В программировании термин инициализация используется во множестве разных контекстов. В MQL5, к сожалению, также возникает некоторая неоднозначность. В разделе Инициализация мы уже применяли это слово для обозначения установки начальных значений переменных. Сейчас мы познакомились с событием инициализации OnInit в индикаторах и экспертах. И хотя смысл обоих инициализаций похож (привести программу в рабочее состояние), они на самом деле обозначают разные этапы подготовки MQL-программы к запуску: системный и прикладной.
Жизненный цикл готовой MQL-программы можно представить следующими крупными шагами:
Скрипты и сервисы априори не имеют обработчиков OnInit и OnDeinit, и потому для них шаги 3 и 5 отсутствуют, а шаг 4 вырождается в единственный вызов OnStart.
Системная инициализация (под пунктом 2) неотделима от загрузки, то есть всегда следует после неё. А финализация всегда предшествует выгрузке. Однако индикаторы и эксперты по-разному проходят этапы загрузки и выгрузки в различных ситуациях. Поэтому вызовы OnInit и OnDeinit (пункты 3 и 5) являются теми опорными точками, в которых можно обеспечить согласованную прикладную инициализацию и деинициализацию экспертов и индикаторов.
Загрузка индикаторов и экспертов происходит по следующим причинам:
Причина |
|
|
|---|---|---|
Прикрепление к графику пользователем |
+ |
+ |
Запуск терминала (если программа была прикреплена к графику перед предыдущим закрытием терминала) |
+ |
+ |
Загрузка шаблона (если в шаблоне указана прикрепленная к графику программа) |
+ |
+ |
Смена профиля (если программа прикреплена к одному из графиков профиля) |
+ |
+ |
После удачной перекомпиляции, если программа была прикреплена к графику |
+ |
+ |
Смена активного счета |
+ |
+ |
- |
- |
- |
Смена символа или периода графика, к которому прикреплен индикатор |
+ |
- |
Изменение входных параметров индикатора |
+ |
- |
- |
- |
- |
Подключение к счету (авторизация), даже если номер счета не менялся |
- |
+ |
В более сжатом виде можно сформулировать следующее правило: эксперты не проходят полный жизненный цикл, то есть не перезагружаются при смене символа/таймфрейма графика, а также при изменении входных параметров.
Поэтому аналогичную несимметричность можно наблюдать и при выгрузке программ. Причинами выгрузки для индикаторов и экспертов являются:
Причина |
|
|
|---|---|---|
Удаление с графика |
+ |
+ |
Закрытие терминала (когда программа прикреплена к графику) |
+ |
+ |
Загрузка шаблона на график, к которому прикреплена программа |
+ |
+ |
Закрытие графика, к которому прикреплена программа |
+ |
+ |
Смена профиля, если программа прикреплена к одному из графиков сменяемого профиля |
+ |
+ |
Смена счета, к которому подключен терминал |
+ |
+ |
- |
- |
- |
Смена символа и/или периода графика, к которому прикреплен индикатор |
+ |
- |
Изменение входных параметров индикатора |
+ |
- |
- |
- |
- |
Прикрепление другого или того же эксперта к графику, на котором уже работает текущий эксперт |
- |
+ |
Вызов функции ExpertRemove |
- |
+ |
Причину деинициализации можно узнать из программы с помощью функции UninitializeReason или флага _UninitReason (см. раздел Проверка статуса и причины остановки MQL-программы).
Обратим еще раз внимание: при смене символа или таймфрейма графика, а также при смене входных параметров эксперт остается в памяти, то есть пункты 6-7 (финализация и выгрузка) и пункты 1-2 (загрузка и первичное распределение памяти) не выполняются, поэтому значения глобальных и статических переменных не сбрасываются. При этом последовательно вызываются обработчики OnDeinit и OnInit на старом и на новом символе/таймфрейме соответственно (или при старых и новых настройках).
Следствием того, что глобальные переменные не очищаются в экспертах, является то, что код деинициализации _UninitReason остается в неизменном виде для анализа в обработчике OnInit. Новый код будет записан в переменную только в случае следующего события, непосредственно перед вызовом OnDeinit.
Все события, поступившие для эксперта до завершения функции OnInit, пропускаются.
При первом запуске MQL-программы диалог настроек выводится между шагами 1 и 2. При смене входных параметров диалог настройки по-разному вклинивается в общий цикл в зависимости от типа программы: для индикаторов он по-прежнему появляется перед шагом 2, а для экспертов — перед шагом 3.
К книге прилагается шаблон индикатора и эксперта с одним и тем же названием LifeCycle.mq5. В нем реализован вывод в журнал этапов глобальной инициализации/финализации и в обработчиках OnInit/OnDeinit. Разместите программы на графике и посмотрите, какие события происходят в ответ на различные действия пользователя: загрузку/выгрузку, смену параметров, переключение символа/таймфрейма.
Загрузка скрипта происходит только при набрасывании его на график. Если скрипт выполняется в цикле, его перекомпиляция не приводит к перезапуску.
Загрузка и выгрузка сервиса происходит по командам контекстного меню в интерфейсе терминала. При перекомпиляции уже выполняющегося сервиса он перезапускается. Напомним, что активные экземпляры сервисов автоматически загружаются при старте терминала и выгружаются при закрытии.
В следующих двух разделах мы рассмотрим особенности запуска разных MQL-программ на уровне обработчиков соответствующих событий.