Skip to content

Local Storage

In this guide, we explain how you can work with local storage when developing cTrader algos. Below, we provide a one-minute summary of how local storage access 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 optimisation, local storage only stores data in memory only.

How to Use Local Storage

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/indicato data and then accessing this information in several ways depending on your needs. Local storage works regardless of the access rights given to an algo.

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.

Warning

The SetObject(string key, object obj) and GetObject<T>(string key) methods only work with data types that can be serialised (i.e., converted into bytes).

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
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.

Defining 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 (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}/{AlgoName}/ 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 behavioгr 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 automatically saves data every minute. Data is also saved on instance stop.

However, you can customise this behavioгr 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 P&L 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);

Local Storage in Backtesting and Optimisation

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 large amounts data that beard 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 optimising 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.