Проверка статуса и причины остановки MQL-программы

Во многих примерах книги мы уже встречали функцию IsStopped. Её необходимо периодически вызывать в тех случаях, когда MQL-программа производит длительные вычисления. Это позволяет проверить, не инициировал ли пользователь закрытие программы (т.е. не попытался ли он удалить её с графика).

bool IsStopped() ≡ bool _StopFlag

Функция возвращает true, если программа была прервана пользователем (например, нажатием кнопки Удалить в диалоге, открываемом по команде Список экспертов контекстного меню).

Программе дается 3 секунды на то, чтобы корректно приостановить расчеты, при необходимости сохранить промежуточные результаты, и завершить свою работу. Если этого не произойдет, программа будет снята с графика принудительно.

Вместо функции IsStopped можно проверять значение встроенной переменной _StopFlag.

Тестовый скрипт EnvStop.mq5 эмулирует длительные расчеты в цикле: поиск простых чисел. Условие выхода из цикла while записано с использованием функции IsStopped. Поэтому, когда пользователь удаляет скрипт, цикл прерывается штатным образом и в журнал выводится статистика найденных простых чисел (скрипт мог бы также сохранить сами числа в файл).

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()) // попробуйте заменить на while(true)
   {
      // эмулируем длительные расчеты
      if(isPrime(candidate))
      {
         Comment("Count:", ++count", Prime:"candidate);
      }
      ++candidate;
      Sleep(10);
   }
   Comment("");
   Print("Total found:"count);
}

Если же заменить условие цикла на true (бесконечный цикл), скрипт перестанет реагировать на запрос пользователя остановиться и будет выгружен с графика принудительно. В результаты мы увидим в журнале ошибку "Abnormal termination", а комментарий в левом верхнем углу окна остается неочищенным. Таким образом, все инструкции, которые в данном примере символизируют сохранение данных и очистку занятых ресурсов (а это могло бы быть, например, удаление собственных графических объектов из окна), игнорируются.

После того как программе был послан запрос на остановку (и значение _StopFlag равно true), из неё можно узнать причину остановки с помощью функции UninitializeReason.

К сожалению, данная возможность доступна только для экспертов и индикаторов.

int UninitializeReason() ≡ int _UninitReason

Функция возвращает один из предопределенных кодов, описывающих причины деинициализации.

Константа

Значение

Описание

REASON_PROGRAM

0

была вызвана функция ExpertRemove, доступная только в советниках и скриптах

REASON_REMOVE

1

программа удалена с графика

REASON_RECOMPILE

2

программа перекомпилирована

REASON_CHARTCHANGE

3

символ или период графика был изменен

REASON_CHARTCLOSE

4

график закрыт

REASON_PARAMETERS

5

входные параметры программы были изменены

REASON_ACCOUNT

6

активирован другой счет либо произошло переподключение к торговому серверу

REASON_TEMPLATE

7

применен другой шаблон графика

REASON_INITFAILED

8

обработчик события OnInit вернул признак ошибки

REASON_CLOSE

9

терминал был закрыт

Вместо функции можно обращаться к встроенной глобальной переменной _UninitReason.

Код причины деинициализации передается также в качестве параметра функции-обработчика события OnDeinit.

В дальнейшем при изучении Особенности запуска и остановки программ разных типов будут представлены индикатор (Indicators/MQL5Book/p5/LifeCycle.mq5) и эксперт (Experts/MQL5Book/p5/LifeCycle.mq5), которые выводят в журнал причины деинициализации и позволяют исследовать поведение программ в зависимости от действий пользователя.