Skip to content

Local Storage

In this guide, we explain what local storage is in the Automate API and how you can use it. Below, we provide a one-minute summary of how this feature works.

Local Storage in One Minute!

  • Local storage allows for saving information in your local file system. Use it to persist data between two or more deployments of your cBots and indicators!
  • To save data, use the SetString(string key, string value) and SetObject(string key, object obj) methods. To retrieve it, invoke the GetString(string key) and T GetObject<T>(string key) methods.
  • Specify your preferred local storage scope by using the LocalStorageScope enum! For example, the SetString(string key, string value, LocalStorageScope.Device) overload will save data in your "Documents/cAlgo/LocalStorage/" directory.
  • While information is saved automatically every minute, you can use the Flush(LocalStorageScope localStorageScope) method to store data without delays.
  • During backtesting and optimization, local storage only stores data in memory only.

How to Use Local Storage in cTrader Automate

Think of local storage as a way to store information between one or several stops/starts of your cBots and indicators. This feature allows for saving cBot/indicator data and then accessing this information in several ways depending on your needs. Local storage works regardless of the access rights given to a cBot.

The LocalStorage interface contains all methods that you can use to store and/or access data to/from local storage. Some examples of these methods include the following.

  • SetString(string key, string value). Saves a string value by matching it with the specified key.
  • SetObject(string key, object obj). Saves an object by matching it with the specified key.
  • GetString(string key). Retrieves a saved string value by finding it under the specified key.
  • T GetObject<T>(string key). Retrieves a saved object of type T from local storage by finding it under the specified key.

Consider the following example in which we ask a cBot instance to save an example message on start. On subsequent starts, the same instance will display a message box containing our message.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class SampleLocalStorageTest : Robot

    {

        protected override void OnStart()
        {

            string messageLocalStorage = LocalStorage.GetString("Example Message");

            if (messageLocalStorage is not null)

            {

                MessageBox.Show(messageLocalStorage);

            }

            LocalStorage.SetString("Example Message", "This is just an example message");

        }

    }
}

After an instance of the cBot above is launched for the first time, it saves our example message in local storage. After stopping the instance and starting it again, the following message box is shown.

Note that local storage works even when AccessRights.None is specified.

How You Can Customize the Local Storage Scope

The local storage scope (defined via the LocalStorageScope type) determines where exactly information is stored and how it can be accessed. This enum contains the following constants.

  • LocalStorageScope.Instance. Saved data is stored and can only be accessed by a specific running instance of a cBot/indicator. Information is saved to the "Documents/cAlgo/LocalStorage/{AlgoType}/{AlgoName}/{InstanceUniqueIdentifier}/" directory. In this path, "AlgoType" denotes the type of the cTrader extension working with local storage (either "cBots" or "Indicators") while "AlgoName" is the name of a specific cBot/indicator. "InstanceUniqueIdentifier" is the unique ID of a specific instance of a particular cBot/indicator.
  • LocalStorageScope.Type. Saved data is stored and can be accessed by all running instances of a particular cBot/indicator. Information is saved to the "Documents/cAlgo/LocalStorage/AlgoType/AlgoNam}/" directory.
  • LocalStorageScope.Device. Saved data is stored and can be accessed by all running instances of cBots/indicators on the current device. Information is saved to the "Documents/cAlgo/LocalStorage/" directory.

In turn, methods such as SetString() and SetObject() have additional overloads allowing for specifying a custom local storage scope. For example, the following code will save a string to LocalStorageScope.Type; this string, subsequently, will be accessible to all extensions of a particular type.

1
SetString(Example String, Just an example string, LocalStorageScope.Type);

If LocalStorageScope is not specified as a parameter, LocalStorageScope.Instance is used by default.

Note that this behavior is different for the GetString(string key) and T GetObject<T>(string key) methods. When these methods are invoked without specifying the local storage scope, they will search for the specified key in all scopes following the below hierarchy.

  • Instance.
  • Type.
  • Device.

Additionally, each different local storage scope has its own disk space quota.

  • LocalStorageScope.Instance is limited to 10 MB.
  • LocalStorageScope.Type is limited to 100 MB.
  • LocalStorageScope.Device is limited to 500 MB.

The limits defined above are not cumulative. For example, if you have already used all 500 MB of device-level storage, you will still be able to store information using instance-level storage until reaching its limit of 10 MB.

How Saving and Loading Information Works

When storing information to local storage (e.g., by invoking the SetString() method), cTrader Automate automatically saves data every minute. Data is also saved on instance stop.

However, you can customize this behavior by using the following methods.

  • Flush(LocalStorageScope localStorageScope). Saves all data to the specified scope.
  • Reload(LocalStorageScope localStorageScope). Reloads all values from the specified scope.

Keep in mind that, when calling the Reload(LocalStorageScope localStorageScope method, any pending changes may be lost. To avoid this, make sure to invoke Flush(LocalStorageScope localStorageScope) beforehand.

In the below example, we ask a cBot to execute a market order. After this action is completed, we immediately save the gross PnL of the position we have just opened in LocalStorageScope.Type.

1
2
3
4
5
ExecuteMarketOrder(TradeType.Buy, SymbolName, 10000, Custom label);
var positionOne = Positions.Find("Custom label");        
string positionOneGrossProfit = positionOne.GrossProfit.ToString();
LocalStorage.SetString("Position 1", positionOneGrossProfit, LocalStorageScope.Device); 
LocalStorage.Flush(LocalStorageScope.Device);

How Local Storage Works in Backtesting and Optimization

To avoid confusion and interference, local storage works differently in backtesting compared to real-time trading.

As shown previously, local storage uses the file system of your local machine when this feature is used in real-time trading. However, using the file system in backtesting would lead to several issues, most notably saving data for objects and strings that bear no relation to current market movements and trading operations.

To avoid these problems, all operations with local storage are conducted in memory only when performing backtests or optimizing your cBots. As a result, you can be sure that all data saved to your file system only concerns real-time trading.

In summary, local storage is a highly beneficial feature of the Automate API that allows for persisting data between multiple stops/starts of various cBots and indicators. By using local storage effectively, you can create complex automated trading strategies based on custom data saved in your file system.


Last update: January 24, 2023