Registrar arrays

La impresión de variables, arrays y mensajes sobre el estado de un programa MQL en el registro es el medio más sencillo para informar al usuario, depurar y diagnosticar problemas. En cuanto al array, podemos implementar la impresión por elementos utilizando la función Print que ya conocemos de los scripts de demostración. Lo describiremos formalmente un poco más adelante, en la sección sobre interacción con el usuario.

Sin embargo, es más conveniente confiar toda la rutina relacionada con la iteración sobre los elementos y su formateo preciso al entorno MQL5. Para ello, la API ofrece una función ArrayPrint especial.

Ya hemos visto ejemplos de cómo trabajar con esta función en la sección Utilización de arrays. Hablemos ahora de sus capacidades con más detalle.

void ArrayPrint(const void &array[], uint digits = _Digits, const string separator = NULL,
ulong start = 0, ulong count = WHOLE_ARRAY,
ulong flags = ARRAYPRINT_HEADER | ARRAYPRINT_INDEX | ARRAYPRINT_LIMIT | ARRAYPRINT_DATE | ARRAYPRINT_SECONDS)

La función registra un array utilizando la configuración especificada. El array debe ser uno de los tipos integrados o un tipo de estructura simple. Una estructura simple es una estructura con campos de tipos integrados, a excepción de las cadenas y los arrays dinámicos. La presencia de objetos de clase y punteros en la composición de la estructura la saca de la categoría simple.

El array debe tener una dimensión de 1 o 2. El formato se ajusta automáticamente a la configuración del array y, si es posible, lo muestra de forma visual (véase más abajo). A pesar de que MQL5 admite arrays con dimensiones de hasta 4, la función no muestra arrays con 3 o más dimensiones, ya que es difícil representarlos de forma «plana». Esto ocurre sin generar errores en el paso de compilación o ejecución del programa.

Todos los parámetros, excepto el primero, pueden omitirse, y para ellos se definen valores por defecto.

El parámetro digits se utiliza para arrays de números reales y para campos numéricos de estructuras. Establece el número de caracteres mostrados en la parte fraccionaria de los números. El valor por defecto es una de las variables de gráfico predefinidas, _Digits, que es el número de decimales del precio del símbolo del gráfico actual.

El carácter de separación separator se utiliza para designar columnas cuando se muestran campos en un array de estructuras. Con el valor por defecto (NULL), la función utiliza un espacio como separador.

Los parámetros start y count establecen el número del elemento inicial y el número de elementos que se van a imprimir, respectivamente. Por defecto, la función imprime todo el array, pero el resultado puede verse afectado de forma adicional por la presencia de la bandera ARRAYPRINT_LIMIT (véase más abajo).

El parámetro flags acepta una combinación de banderas que controlan varias características de visualización. He aquí algunas de ellas:

  • ARRAYPRINT_HEADER imprime el encabezado con los nombres de los campos de la estructura delante del array de estructuras; no afecta a los arrays de no estructuras.
  • ARRAYPRINT_INDEX muestra los índices de los elementos por dimensiones (para arrays unidimensionales, los índices se muestran a la izquierda; para arrays bidimensionales se muestran a la izquierda y arriba).
  • ARRAYPRINT_LIMIT se utiliza para arrays grandes, y la salida se limita a los cien primeros y los cien últimos registros (este límite está activado por defecto).
  • ARRAYPRINT_DATE se utiliza para valores del tipo datetime para mostrar la fecha.
  • ARRAYPRINT_MINUTES se utiliza para valores del tipo datetime para mostrar la hora al minuto más cercano.
  • ARRAYPRINT_SECONDS se utiliza para valores del tipo datetime para mostrar la hora al segundo más cercano.

Los valores del tipo datetime semuestran por defecto en el formato ARRAYPRINT_DATE | ARRAYPRINT_SECONDS.

Los valores del tipo color se muestran en formato hexadecimal.

Los valores de enumeración se muestran como números enteros.

La función no produce arrays anidados, estructuras ni punteros a objetos. En lugar de ellos aparecen tres puntos.

El script ArrayPrint.mq5 demuestra cómo funciona.

La función OnStart proporciona definiciones de varios arrays (unidimensionales, bidimensionales y tridimensionales), cuya salida se realiza mediante ArrayPrint (con la configuración predeterminada).

void OnStart()
{
   int array1D[] = {12345678910};
   double array2D[][5] = {{12345}, {678910}};
   double array3D[][3][5] =
   {
      {{ 1,  2,  3,  4,  5}, { 6,  7,  8,  910}, {1112131415}},
      {{1617181920}, {2122232425}, {2627282930}},
   };
   
   Print("array1D");
   ArrayPrint(array1D);
   Print("array2D");
   ArrayPrint(array2D);
   Print("array3D");
   ArrayPrint(array3D);
   ...
}

Obtendremos las siguientes líneas en el registro:

array1D
 1  2  3  4  5  6  7  8  9 10
array2D
         [,0]     [,1]     [,2]     [,3]     [,4]
[0,]  1.00000  2.00000  3.00000  4.00000  5.00000
[1,]  6.00000  7.00000  8.00000  9.00000 10.00000
array3D

El array array1D no es lo suficientemente grande (cabe en una fila), por lo que no se muestran los índices correspondientes.

El array array2D tiene varias filas (índices), y por lo tanto se muestran sus índices (ARRAYPRINT_INDEX está activado por defecto).

Tenga en cuenta que el script se ejecutó en el gráfico EURUSD con precios de cinco dígitos, _Digits=5, lo que afecta al formato de los valores de tipo double.

El array array3D se ignora: no se ha generado ninguna fila para él.

Además, las estructuras Pair y SimpleStruct están definidas en el script:

struct Pair
{
   int xy;
};
   
struct SimpleStruct
{
   double value;
   datetime time;
   int count;
   ENUM_APPLIED_PRICE price;
   color clr;
   string details;
   void *ptr;
   Pair pair;
};

SimpleStruct contiene campos de tipos integrados, un puntero a void, así como un campo de tipo Pair.

En la función OnStart se crea un array del tipo SimpleStruct y se emite utilizando ArrayPrint en dos modos: con la configuración predeterminada y con la personalizada (el número de dígitos después de la «coma» es 3, el separador es «;», el formato para datetime es sólo fecha).

void OnStart()
{
   ...
   SimpleStruct simple[] =
   {
      { 12.57839D'2021.07.23 11:15', 22345PRICE_MEDIANclrBlue"text message"},
      {135.82949D'2021.06.20 23:45', 8569PRICE_TYPICALclrAzure},
      { 1087.576D'2021.05.15 10:01:30', -3298PRICE_WEIGHTEDclrYellow"note"},
   };
   Print("SimpleStruct (default)");
   ArrayPrint(simple);
   
   Print("SimpleStruct (custom)");
   ArrayPrint(simple3";"0WHOLE_ARRAYARRAYPRINT_DATE);
}

El resultado es el siguiente:

SimpleStruct (default)
       [value]              [time] [count] [type]    [clr]      [details] [ptr] [pair]
[0]   12.57839 2021.07.23 11:15:00   22345      5 00FF0000 "text message"   ...    ...
[1]  135.82949 2021.06.20 23:45:00    8569      6 00FFFFF0 null             ...    ...
[2] 1087.57600 2021.05.15 10:01:30   -3298      7 0000FFFF "note"           ...    ...
SimpleStruct (custom)
  12.578;2021.07.23;  22345;     5;00FF0000;"text message";  ...;   ...
 135.829;2021.06.20;   8569;     6;00FFFFF0;null          ;  ...;   ...
1087.576;2021.05.15;  -3298;     7;0000FFFF;"note"        ;  ...;   ...

Tenga en cuenta que el registro que utilizamos en este caso y en las secciones anteriores se genera en el terminal y está a disposición del usuario en la pestaña Experts de la ventana Toolbox. No obstante, en el futuro nos familiarizaremos con el probador, que proporciona el mismo entorno de ejecución para ciertos tipos de programas MQL (indicadores y Asesores Expertos) que el propio terminal. Si se lanzan en el probador, la función ArrayPrint y otras funciones relacionadas, que se describen en la sección Interacción con el usuario enviarán mensajes al registro de agentes de prueba.
 
Hasta ahora hemos trabajado, y seguiremos haciéndolo durante algún tiempo, sólo con scripts, y éstos sólo pueden ejecutarse en el terminal.