Saltar a contenido

Cómo trabajar con el almacenamiento local

En este artículo y su video correspondiente, explicaremos qué es el almacenamiento local y cómo se puede utilizar en sus algoritmos de cTrader. También proporcionaremos ejemplos útiles y explicaremos cómo funciona el alcance del almacenamiento local.

Por qué usar el almacenamiento local

Hay muchos casos en los que desea que su algoritmo guarde algo o acceda a algo desde el sistema de archivos local. Por ejemplo, es posible que desee guardar un registro de todas las operaciones del cBot. Sin embargo, esto generalmente requiere que el algoritmo tenga derechos de acceso elevados (AccessRights.FullAccess), lo cual es menos que ideal para los usuarios. Si un algoritmo solicita a un usuario que proporcione permisos elevados, es mucho menos probable que el usuario confíe en el algoritmo, especialmente si se distribuye sin su código fuente. El almacenamiento local es una forma conveniente de acceder de manera segura al sistema de archivos local sin introducir ninguna preocupación de seguridad. El uso del almacenamiento local permite a los desarrolladores mantener los derechos de acceso de sus algoritmos establecidos en AccessRights.None.

Guardar cadenas en el almacenamiento local

Cada tipo de algoritmo de cTrader tiene una propiedad LocalStorage que permite ejecutar operaciones de lectura y escritura. Para demostrar cómo funciona el almacenamiento local, crearemos un nuevo cBot. En su manejador OnStart, utilizaremos el método LocalStorage.SetString(string key, string value). Como puede ver, toma dos argumentos, a saber, una clave bajo la cual se debe guardar la información y el valor a guardar.

1
LocalStorage.SetString("Message", Message);

Para recuperar el valor, utilizaremos el método GetString(string key) en el manejador OnTick del cBot.

1
Print(LocalStorage.GetString("Message"));

Mientras Message no sea nulo, podemos construir el cBot y ver el valor recuperado correctamente impreso en el registro.

Guardar objetos en el almacenamiento local

Más allá de las cadenas, puede utilizar el almacenamiento local para guardar cualquier tipo de objeto. Detrás de escena, cTrader serializa y deserializa objetos en el almacenamiento local, lo que permite compartir cualquier tipo de datos. Para demostrarlo, podemos crear una nueva clase para almacenar información, guardarla y luego recuperarla. Llamaremos a esta clase Signal.

1
2
3
4
5
6
class Signal
{
    public TradeType TradeType { get; set; }
    public double SL { get; set; }
    public double TP { get; set; }
}

En el método OnStart(), crearemos una nueva instancia de esta clase e inicializaremos sus propiedades.

1
2
3
4
5
var signal = new Signal{
    TradeType = TradeType.Sell,
    SL = 50,
    TP = 50,
};

Utilizaremos el método SetObject(string key, Object object) para guardar y recuperar el saldo de la cuenta.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
protected override void OnStart()
{
    var signal = new Signal{
    TradeType = TradeType.Sell,
    SL = 50,
    TP = 50,
    };        

    LocalStorage.SetString("Message",Message);
    LocalStorage.SetObject("Signal 1", signal);
}

protected override void OnTick()
{
Print(LocalStorage.GetString("Message")); 

var signal = LocalStorage.GetObject<Signal>("Signal 1"); 
Print(signal.TradeType);
Print(signal.SL);
Print(signal.TP);
}

Si construimos nuestro cBot y lo lanzamos, deberíamos ver los valores correctos impresos en el registro.

Alcances del almacenamiento local

Al utilizar el almacenamiento local, también puede definir el alcance en el que los valores guardados están expuestos para su futura recuperación. Hay tres alcances diferentes disponibles:

  • Alcance de instancia - los valores guardados solo están disponibles para una instancia específica.
  • Alcance de tipo - los valores guardados están disponibles para todas las instancias de un algoritmo específico.
  • Alcance de dispositivo - los valores guardados están disponibles para todos los algoritmos independientemente de sus tipos.

Así es como podría verse el uso del alcance de instancia.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[Parameter()]
public bool IsWriter { get; set; }


protected override void OnStart()
{   
    if(IsWriter)
    { 
        LocalStorage.SetString("Message",Message, LocalStorageScope.Instance);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        if(LocalStorage.GetString("Message") != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Tenga en cuenta que hemos especificado explícitamente el alcance en el método SetString().

Podemos añadir varias instancias de este cBot y configurarlas para que una escriba en el almacenamiento local mientras que otra recupera información. En este caso, la lectura de información debería ser imposible. Sin embargo, si solo una instancia está configurada para ejecutar operaciones de escritura y lectura, el cBot debería funcionar como se espera.

Aquí hay un ejemplo de uso del alcance de tipo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
protected override void OnStart()
{   
    if(IsWriter)
    {             
        LocalStorage.SetString("Message",Message, LocalStorageScope.Type);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        if(LocalStorage.GetString("Message", LocalStorageScope.Type) != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Si creamos dos instancias de este bot y las configuramos para que una instancia escriba en el almacenamiento local y otra lea el valor guardado, todo debería funcionar sin generar errores.

Por último, pero no menos importante, el alcance de dispositivo permite intercambiar información entre diferentes algoritmos. Aquí hay un ejemplo de uso de este tipo de alcance.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
protected override void OnStart()
{   
    if(IsWriter)
    {             
        LocalStorage.SetString("Message",Message, LocalStorageScope.Device);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        if(LocalStorage.GetString("Message", LocalStorageScope.Device) != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Podemos construir varios cBots que utilicen el mismo código. Si los configuramos correctamente, un cBot puede guardar información en el almacenamiento local mientras que otro la recupera. Siempre que el alcance sea igual a LocalStorageScope.Device, nuestro sistema debería funcionar como se espera.

Uso de los métodos Flush() y Reload()

Si desea compartir información entre varias instancias de cTrader, llame a los métodos Flush() y Reload().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
protected override void OnStart()
{   
    if(IsWriter)
    {             
        LocalStorage.SetString("Message",Message, LocalStorageScope.Device);
        LocalStorage.Flush(LocalStorageScope.Device);
    }
}

protected override void OnTick()
{        
    if(!IsWriter)
    {
        LocalStorage.Reload(LocalStorageScope.Device);
        if(LocalStorage.GetString("Message", LocalStorageScope.Device) != string.Empty)
            Print(LocalStorage.GetString("Message"));
    }
}

Si construimos varios cBots con este código y realizamos un experimento para compartir información entre diferentes instancias de cTrader, veremos que nuestros valores guardados persisten como se espera.