Escritura y lectura de variables globales

La API de MQL5 proporciona dos funciones para escribir y leer variables globales: GlobalVariableSet y GlobalVariableGet (en dos versiones).

datetime GlobalVariableSet(const string name, double value)

La función establece un nuevo value a la variable global «name». Si la variable no existía antes de llamar a la función, se creará. Si la variable ya existe, el valor anterior será sustituido por value.

Si tiene éxito, la función devuelve la hora de modificación de la variable (la hora local actual del ordenador). En caso de error, obtenemos 0.

double GlobalVariableGet(const string name)

bool GlobalVariableGet(const string name, double &value)

La función devuelve el valor de la variable global 'nombre'. El resultado de llamar a la primera versión de la función contiene sólo el valor de la variable (en caso de éxito) o 0 (en caso de error). Dado que la variable puede contener el valor 0 (que equivale a una indicación de error), esta opción requiere analizar el código de error interno _LastError si se recibe cero, para distinguir la versión estándar de la no estándar. En concreto, si se intenta leer una variable que no existe, se genera un error interno 4501 (GLOBALVARIABLE_NOT_FOUND).

Esta versión de la función es conveniente utilizarla en algoritmos en los que obtener cero es un análogo adecuado de la inicialización por defecto para una variable previamente inexistente (véase el ejemplo siguiente). Si la ausencia de una variable debe ser tratada de una manera especial (en concreto, para calcular algún otro valor inicial), primero debe comprobar la existencia de la variable utilizando la función GlobalVariableCheck y, en función de su resultado, ejecutar diferentes ramas de código. Opcionalmente, puede utilizar la segunda versión.

La segunda versión de la función devuelve true o false dependiendo del éxito de la ejecución. Si tiene éxito, el valor de la variable global del terminal se coloca en la variable value receptora, pasada por referencia como segundo parámetro. Si no hay variable, obtenemos false.

En el script de prueba GlobalsRunCount.mq5 utilizamos una variable global para contar el número de veces que se ha ejecutado. El nombre de la variable es el nombre del archivo fuente.

const string gv = __FILE__;

Recordemos que la macro integrada __FILE__ (véase Constantes predefinidas) es expandida por el compilador en el nombre del archivo compilado, es decir, en este caso, «GlobalsRunCount.mq5».

En la función OnStart intentaremos leer la variable global dada y guardar el resultado en la variable local count. Si todavía no había ninguna variable global, obtenemos 0, lo cual está bien para nosotros (empezamos a contar desde cero).

Antes de guardar el valor en count, es necesario realizar una conversión de tipo a (int), ya que la función GlobalVariableGet devuelve double, y sin la conversión, el compilador genera un aviso de posible pérdida de datos (no sabe que pensamos almacenar sólo enteros).

void OnStart()
{
   int count = (int)PRTF(GlobalVariableGet(gv));
   count++;
   PRTF(GlobalVariableSet(gvcount));
   Print("This script run count: "count);
}

A continuación, incrementamos el contador en 1 y lo escribimos de nuevo en la variable global con GlobalVariableSet. Si ejecutamos el script varias veces, obtendremos algo parecido a las siguientes entradas de registro (sus marcas de tiempo serán diferentes):

GlobalVariableGet(gv)=0.0 / GLOBALVARIABLE_NOT_FOUND(4501)
GlobalVariableSet(gv,count)=2021.08.29 16:04:40 / ok
This script run count: 1
GlobalVariableGet(gv)=1.0 / ok
GlobalVariableSet(gv,count)=2021.08.29 16:05:00 / ok
This script run count: 2
GlobalVariableGet(gv)=2.0 / ok
GlobalVariableSet(gv,count)=2021.08.29 16:05:21 / ok
This script run count: 3

Es importante señalar que en la primera ejecución recibimos un valor de 0, y se generó la bandera de error interno 4501. Todas las llamadas posteriores se ejecutan sin problemas, ya que la variable existe (puede verse en la ventana «Variables globales» del terminal). Quien lo desee puede cerrar el terminal, reiniciarlo y volver a ejecutar el script: el contador seguirá aumentando desde el valor anterior.