Comprobar el estado del programa MQL y motivo de finalización

Ya nos hemos encontrado con la función IsStopped en diferentes ejemplos a lo largo del libro. Se trata de una función a la que hay que llamar de vez en cuando en los casos en que el programa MQL realiza cálculos largos. Esto permite comprobar si el usuario inició el cierre del programa (es decir, si intentó eliminarlo del gráfico).

bool IsStopped() ≡ bool _StopFlag

La función devuelve true si el programa ha sido interrumpido por el usuario (por ejemplo, pulsando el botón Borrar en el cuadro de diálogo abierto por el comando Lista de expertos del menú contextual).

El programa dispone de 3 segundos para pausar correctamente los cálculos, guardar los resultados intermedios si es necesario y completar su trabajo. Si esto no ocurre, el programa será retirado del gráfico por la fuerza.

En lugar de la función IsStopped, puede comprobar el valor de la variable _StopFlag integrada.

El script de prueba EnvStop.mq5 emula largos cálculos en bucle: búsqueda de números primos. Las condiciones para salir del bucle while se escriben utilizando la función IsStopped. Por lo tanto, cuando el usuario borra el script, el bucle se interrumpe de la forma habitual y el registro muestra las estadísticas del registro de números primos encontrados (el script también podría guardar los números en un archivo).

bool isPrime(int n)
{
   if(n < 1return false;
   if(n <= 3return true;
   if(n % 2 == 0return false;
   const int p = (int)sqrt(n);
   int i = 3;
   for( ; i <= pi += 2)
   {
      if(n % i == 0return false;
   }
   
   return true;
}
   
void OnStart()
{
   int count = 0;
   int candidate = 1;
   
   while(!IsStopped()) // try to replace it with while(true)
   {
      // emulate long calculations
      if(isPrime(candidate))
      {
         Comment("Count:", ++count", Prime:"candidate);
      }
      ++candidate;
      Sleep(10);
   }
   Comment("");
   Print("Total found:"count);
}

Si sustituimos la condición de bucle por true (bucle infinito), el script dejará de responder a la petición de parada del usuario y se descargará del gráfico forzosamente. Como resultado, veremos el error «Terminación anormal» en el registro, y el comentario en la esquina superior izquierda de la ventana permanece sin limpiar. Así, todas las instrucciones que en este ejemplo simbolizan guardar datos y borrar recursos ocupados (y esto podría ser, por ejemplo, borrar sus propios objetos gráficos de la ventana) son ignoradas.

Una vez enviada una solicitud de parada al programa (y el valor _StopFlag sea igual a true), se puede averiguar el motivo de la finalización mediante la función UninitializeReason.

Lamentablemente, esta función sólo está disponible para los Asesores Expertos y los indicadores.

int UninitializeReason() ≡ int _UninitReason

La función devuelve uno de los códigos predefinidos que describen los motivos de la desinicialización.

Constante

Valor

Descripción

REASON_PROGRAM

0

ExpertRemove : función sólo disponible en Asesores Expertos y scripts a la que se llama

REASON_REMOVE

1

Programa eliminado del gráfico

REASON_RECOMPILE

2

Programa recompilado

REASON_CHARTCHANGE

3

Símbolo del gráfico o período cambiado

REASON_CHARTCLOSE

4

Gráfico cerrado

REASON_PARAMETERS

5

Parámetros de entrada del programa modificados

REASON_ACCOUNT

6

Se conecta otra cuenta o se produce una reconexión al servidor de trading

REASON_TEMPLATE

7

Otra plantilla de gráfico aplicada

REASON_INITFAILED

8

OnInit devuelve una bandera de error

REASON_CLOSE

9

Terminal cerrado

En lugar de una función, puede acceder a la variable global integrada _UninitReason.

El código de motivo de desinicialización también se pasa como parámetro a la función OnDeinit de manejo de eventos.

Más tarde, al estudiar Funciones de inicio y parada del programa, veremos un indicador (Indicators/MQL5Book/p5/LifeCycle.mq5) y un Asesor Experto (Experts/MQL5Book/p5/LifeCycle.mq5) que registran los motivos de desinicialización y permiten explorar el comportamiento de los programas en función de las acciones del usuario.