Funciones de inicio y parada de programas de varios tipos

En programación, el término inicialización se utiliza en muchos contextos diferentes. En MQL5 también existe cierta ambigüedad. En la sección Inicialización hemos utilizado ya esta palabra para referirnos a la fijación de los valores iniciales de las variables. Luego discutimos el evento de inicialización OnInit en indicadores y Asesores Expertos. Aunque el significado de ambas inicializaciones es similar (llevar el programa a un estado de trabajo), en realidad significan diferentes etapas de la preparación de un programa MQL para el lanzamiento: sistema y aplicación.

El ciclo de vida de un programa MQL terminado puede representarse mediante los siguientes pasos principales:

  1. Carga: lectura de un programa desde un archivo en la memoria del terminal: incluye instrucciones, datos predefinidos (literales), recursos y bibliotecas. Aquí es donde entran en juego las directivas #property.
  2. Asignación de memoria para variables globales y establecimiento de sus valores iniciales: es la inicialización del sistema realizada por el tiempo de ejecución. Recordemos que en la sección Inicialización, mientras estudiábamos paso a paso el inicio del programa bajo el depurador, vimos que la entrada @global_initializations estaba en la pila. Este era el bloque de código para este elemento, que fue creado implícitamente por el compilador. Si el programa utiliza objetos globales de clases o estructuras, se llamará a sus constructores en esta fase.
  3. Llamada al manejador de eventos OnInit (si existe): lleva a cabo una inicialización aplicada de nivel superior, por lo que cada programa la realiza de forma independiente, según sea necesario. Por ejemplo, puede ser la asignación dinámica de memoria para arrays de objetos, para los que, por una razón u otra, sea necesario utilizar constructores paramétricos en lugar de constructores predeterminados. Como sabemos, la asignación automática de memoria para arrays utiliza sólo constructores predeterminados, y por lo tanto no se pueden inicializar en el paso anterior (2). También puede ser abrir archivos, llamar a funciones integradas de la API para activar los modos de gráfico necesarios, etc.
  4. Bucle hasta que el usuario cierre el programa o el terminal o realice cualquier otra acción que requiera reinicialización (ver más adelante):
    • llamando a otros manejadores a medida que se produzcan los eventos apropiados.
  5. Llamada al manejador de eventos OnDeinit (si existe) al detectar un intento de cerrar el programa por parte del usuario o programáticamente (la función correspondiente ExpertRemove sólo está disponible en Asesores Expertos y scripts).
  6. Finalización: liberar la memoria asignada y otros recursos que el programador no consideró necesario liberar en OnDeinit. Si el programa utiliza POO, los destructores de objetos globales y estáticos se llaman aquí.
  7. Descarga del programa.

Los scripts y servicios a priori no tienen manejadores OnInit y OnDeinit, y por lo tanto los pasos 3 y 5 no existen para ellos, y el paso 4 degenera en una sola llamada a OnStart.

La inicialización del sistema (paso 2) es inseparable de la carga, es decir, siempre a continuación de ella. La finalización siempre precede a la descarga. No obstante, los indicadores y los Asesores Expertos pasan por las etapas de carga y descarga de manera diferente en distintas situaciones. Por lo tanto, las llamadas a OnInit y OnDeinit (pasos 3 y 5) son los puntos de referencia en los que es posible proporcionar una inicialización y desinicialización aplicada coherente de Asesores Expertos e indicadores.

La carga de indicadores y Asesores Expertos se realiza en los siguientes casos:

Caso

Indicador

Asesor Experto

El usuario inicia el programa en el gráfico

+

+

Lanzamiento del terminal (si el programa se estaba ejecutando en el gráfico antes del cierre anterior del terminal)

+

+

Carga de una plantilla (si la plantilla contiene un programa adjunto al gráfico)

+

+

Modificación del perfil (si el programa está vinculado a uno de los gráficos del perfil)

+

+

Tras la recompilación correcta, si el programa se adjuntó al gráfico

+

+

Cambio de la cuenta activa

+

+

-

-

-

Modificación del símbolo o el período del gráfico al que está vinculado el indicador

+

-

Modificación de los parámetros de entrada del indicador

+

-

-

-

-

Conexión a la cuenta (autorización), aunque el número de cuenta no haya cambiado

-

+

De forma más compacta, se puede formular la siguiente regla: los Asesores Expertos no pasan por el ciclo de vida completo, es decir, no se recargan cuando cambia el símbolo o marco temporal del gráfico, así como cuando cambian los parámetros de entrada.

Por lo tanto, puede observarse una asimetría similar al descargar los programas. Las razones para descargar indicadores y Asesores Expertos son:

Caso

Indicador

Asesor Experto

Eliminación del programa del gráfico

+

+

Cierre del terminal (cuando el programa está conectado al gráfico)

+

+

Carga de una plantilla en el gráfico en el que se ejecuta el programa

+

+

Cierre del gráfico en el que se está ejecutando el programa

+

+

Modificación del perfil si el programa está vinculado a uno de los gráficos del perfil

+

+

Modificación de la cuenta a la que está conectado el terminal

+

+

-

-

-

Modificación del símbolo y/o el periodo del gráfico al que está vinculado el indicador

+

-

Modificación de los parámetros de entrada del indicador

+

-

-

-

-

Vinculación del mismo u otro EA al gráfico en el que ya se está ejecutando el EA actual

-

+

Llamada a la función ExpertRemove

-

+

El motivo de la desinicialización se puede encontrar en el programa utilizando la función UninitializeReason o la bandera _UninitReason (véase la sección Comprobar el estado y el motivo de parada de un programa MQL).

Tenga en cuenta que cuando cambia el símbolo o el marco temporal del gráfico, así como cuando cambia los parámetros de entrada, el Asesor Experto permanece en memoria, es decir, los pasos 6-7 (finalización y descarga) y los pasos 1-2 (carga y asignación de memoria primaria) no se ejecutan, por lo tanto, los valores de las variables globales y estáticas no se restablecen. En este caso, los manejadores OnDeinit y OnInit son llamados de forma secuencial en el antiguo y en el nuevo símbolo o marco temporal, respectivamente (o en la antigua y en la nueva configuración).

Una consecuencia de que las variables globales no se borren en los Asesores Expertos es que el código de desinicialización _UninitReason permanece inalterado para su análisis en el manejador OnInit. El nuevo código se escribirá en la variable sólo en caso del siguiente evento, justo antes de la llamada a OnDeinit.

Todos los eventos recibidos para el Asesor Experto antes del final de la función OnInit se omiten.

Cuando se inicia el programa MQL por primera vez, aparece el cuadro de diálogo de configuración entre los pasos 1 y 2. Al cambiar los parámetros de entrada, el cuadro de diálogo de configuración se encaja en el bucle general de diferentes maneras en función del tipo de programa: para los indicadores aparece todavía antes del paso 2, y para los Asesores Expertos, antes del paso 3.
 
El libro va acompañado de un indicador y una plantilla de Asesor Experto que lleva por título LifeCycle.mq5 y registra los pasos globales de inicialización o finalización en manejadores OnInit/OnDeinit. Coloque programas en el gráfico y vea qué eventos se producen en respuesta a diversas acciones del usuario: carga o descarga, cambio de parámetros, cambio de símbolos o marcos temporales.

El script se carga sólo cuando se añade al gráfico. Si un script se está ejecutando en bucle, recompilarlo no provoca un reinicio.

El servicio se carga y descarga mediante los comandos del menú contextual de la interfaz del terminal. Cuando se recompila un servicio que ya está en funcionamiento, éste se reinicia. Recuerde que las instancias activas de los servicios se cargan automáticamente cuando se inicia el terminal, y se descargan cuando se cierra.

En las dos secciones siguientes examinaremos las características del lanzamiento de diferentes programas MQL a nivel de manejadores de eventos.