Выполнение программ

Каждый скрипт, сервис и эксперт работает в собственном отдельном потоке. Все индикаторы, рассчитываемые на одном символе, даже если они запущены на разных графиках, работают в одном потоке. Таким образом, все индикаторы на одном символе делят между собой ресурсы одного потока.

В одном потоке с индикаторами также последовательно выполняются остальные действия по данному символу - обработка тиков и синхронизация истории. Это означает, что если в индикаторе выполняется бесконечное действие, все остальные события по его символу никогда не выполнятся.

При запуске эксперта ему необходимо обеспечить актуальное торговое окружение, доступность истории по данному символу и периоду, а также произвести синхронизацию между терминалом и сервером. На эти процедуры терминал предоставляет эксперту отсрочку запуска не более чем в 5 секунд, по истечении которых эксперт будет запущен с теми данными, что удалось подготовить. Поэтому при отсутствии связи с сервером это может привести к задержке запуска эксперта.

Краткая сводка по программам на MQL5 приведена в таблице:

Программа

Выполнение

Примечание

Сервис

В собственном потоке, сколько сервисов - столько потоков выполнения для них

Зацикленный сервис не может нарушить работу других программ

Скрипт

В собственном потоке, сколько скриптов - столько потоков выполнения для них

Зацикленный скрипт не может нарушить работу других программ

Эксперт

В собственном потоке, сколько экспертов - столько потоков выполнения для них

Зацикленный эксперт не может нарушить работу других программ

Индикатор

Один поток выполнения для всех индикаторов на одном символе. Сколько символов с индикаторами - столько потоков выполнения для них

Бесконечный цикл в одном индикаторе остановит работу всех остальных индикаторов на этом символе

Сразу после присоединения программы к графику производится ее загрузка в память клиентского терминала и инициализация глобальных переменных. Если какая-либо глобальная переменная типа класса имеет конструктор, то этот конструктор будет вызван в процессе инициализации глобальных переменных.

После этого программа находится в состоянии ожидания события от клиентского терминала. У каждой mql5-программы должна быть хотя бы одна функция-обработчик события, в противном случае загруженная программа выполняться не будет. Функции-обработчики событий имеют предопределенные имена, предопределенные наборы параметров и предопределенные типы возврата.

Тип

Имя функции

Параметры

Применение

Примечание

int

OnInit

нет

эксперты и индикаторы

Обработчик события Init. Допускается тип возвращаемого значения void.

void

OnDeinit

const int reason

эксперты и индикаторы

Обработчик события Deinit.

void

OnStart

нет

скрипты и сервисы

Обработчик события Start.

int

OnCalculate

const int rates_total,

const int prev_calculated,

const datetime &Time[],

const double &Open[],

const double &High[],

const double &Low[],

const double &Close[],

const long &TickVolume[],

const long &Volume[],

const int &Spread[]

индикаторы

Обработчик события Calculate на всех ценовых данных.

int

OnCalculate

const int rates_total,

const int prev_calculated,

const int begin,

const double &price[]

индикаторы

Обработчик события Calculate на одном массиве данных.

В индикаторе не может одновременно присутствовать 2 обработчика Calculate. В этом случае будет работать только обработчик события Calculate на одном массиве данных.

void

OnTick

нет

эксперты

Обработчик события NewTick. Пока идет обработка события прихода нового тика другие события этого типа не приходят.

void

OnTimer

нет

эксперты и индикаторы

Обработчик события Timer.

void

OnTrade

нет

эксперты

Обработчик события Trade.

double

OnTester

нет

эксперты

Обработчики события Tester

void

OnChartEvent

const int id,

const long &lparam,

const double &dparam,

const string &sparam

эксперты и индикаторы

Обработчик события ChartEvent.

void

OnBookEvent

const string &symbol_name

эксперты и индикаторы

Обработчик события BookEvent.

Клиентский терминал отсылает возникающие события в соответствующие открытые графики. Также события могут генерироваться графиками (события графика) либо mql5-программами (пользовательские события).  Генерацию событий создания и удаления графических объектов на графике можно включать и отключать заданием свойств графика CHART_EVENT_OBJECT_CREATE и CHART_EVENT_OBJECT_DELETE. Каждая mql5-программа и каждый график имеют свою собственную очередь событий, куда складываются все вновь поступающие события.

Программа получает события только от графика, на котором она запущена. Все события обрабатываются одно за другим в порядке поступления. Если в очереди уже есть событие NewTick либо это событие находится в состоянии обработки, то новое событие NewTick в очередь mql5-программы не ставится. Аналогично, если в очереди mql5-программы уже находится событие ChartEvent или такое событие обрабатывается, то новое событие такого типа не ставится в очередь. Обработка событий таймера производится по такой же схеме – если в очереди находится или уже обрабатывается событие Timer, то новое событие таймера не ставится в очередь.

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

Крайне не рекомендуется использовать бесконечные циклы для обработки событий. Исключением из этого правила могут быть только скрипты и сервисы, которые обрабатывают одно единственное событие Start.

Библиотеки не обрабатывают никаких событий.

 

Запрет на использование функций в индикаторах и экспертах

Индикаторы, скрипты и эксперты являются исполняемыми программами на MQL5 и предназначены для различных типов задач. Поэтому существует ограничение на использование определенных функций в зависимости от типа программы. В индикаторах запрещены следующие функции:

 

В свою очередь, в экспертах и скриптах запрещены все функции, предназначенные для индикаторов:

Библиотека не является самостоятельной программой и выполняется в контексте вызвавшей её MQL5-программы: скрипт, индикатор или эксперт. Соответственно, на вызванную библиотеку распространяются указанные выше ограничения.

 

Запрет на использование функций в сервисах

Сервисы не принимают никаких событий, так как не имеют привязки к графику.  В сервисах запрещены следующие функции:

ExpertRemove();

EventSetMillisecondTimer();

EventSetTimer();

EventKillTimer();

SetIndexBuffer();

IndicatorSetDouble();

IndicatorSetInteger();

IndicatorSetString();

PlotIndexSetDouble();

PlotIndexSetInteger();

PlotIndexSetString();

PlotIndexGetInteger();

 

Загрузка и выгрузка индикаторов

Индикаторы загружаются в следующих случаях:

  • прикрепление индикатора к графику;
  • запуск терминала (если индикатор был прикреплен к графику перед предыдущим закрытием терминала);
  • загрузка шаблона (если в шаблоне указан прикрепленный к графику индикатор);
  • смена профиля (если индикатор прикреплен к одному из графиков профиля);
  • смена символа и/или периода графика, к которому прикреплен индикатор;
  • смена счета, к которому подключен терминал;
  • после удачной перекомпиляции индикатора, если данный индикатор был прикреплен к графику.
  • изменение входных параметров индикатора.

Индикаторы выгружаются в следующих случаях:

  • при откреплении индикатора от графика;
  • закрытие терминала (если индикатор был прикреплен к графику);
  • загрузка шаблона, если к графику прикреплен индикатор;
  • закрытие графика, к которому был прикреплен индикатор;
  • смена профиля, если индикатор прикреплен к одному из графиков сменяемого профиля;
  • смена символа и/или периода графика, к которому прикреплен индикатор;
  • смена счета, к которому подключен терминал;
  • изменение входных параметров индикатора.

 

Загрузка и выгрузка экспертов

Загрузка эксперта производится в следующих случаях:

  • прикрепление эксперта к графику;
  • запуск терминала (если эксперт был прикреплен к графику перед предыдущим закрытием терминала);
  • загрузка шаблона (если в шаблоне указан прикрепленный к графику эксперт);
  • после удачной перекомпиляции эксперта, если данный эксперт был прикреплен к графику.
  • смена профиля (если эксперт прикреплен к одному из графиков профиля);
  • подключение к счету, даже если номер счета не менялся (если эксперт был прикреплен к графику перед авторизацией терминала на сервере).

Выгрузка эксперта, прикрепленного к графику, производится в следующих случаях:

  • при откреплении эксперта от графика;
  • при прикреплении эксперта к графику – если на данном графике был уже другой эксперт, то этот эксперт выгружается;
  • закрытие терминала (если эксперт был прикреплен к графику);
  • загрузка шаблона, если к графику прикреплен эксперт;
  • закрытие графика, к которому был прикреплен эксперт;
  • смена профиля, если эксперт прикреплен к одному из графиков сменяемого профиля;
  • смена счета, к которому подключен терминал (если эксперт был прикреплен к графику перед авторизацией терминала на сервере);

При смене символа или таймфрейма графика, к которому эксперт прикреплен, выгрузка и загрузка эксперта не производится. При этом последовательно вызываются обработчики OnDeinit() на старом символе/таймфрейме и OnInit() на новом символе/таймфрейме (если они есть), значения глобальных переменных и статических переменных не сбрасываются. Все события, поступившие для эксперта до завершения инициализации (функции OnInit()), пропускаются.

 

Загрузка и выгрузка скриптов

Скрипты загружаются сразу после прикрепления к графику и выгружаются сразу после окончания своей работы. При этом функции OnInit() и OnDeinit() для скриптов не вызываются.

При выгрузке программы (удалении программы с графика) происходит деинициализация глобальных переменных и уничтожение очереди сообщений. В этом случае деинициализация означает освобождение переменных типа string, освобождение объектов динамических массивов и вызов деструкторов при их наличии.

 

Загрузка и выгрузка сервисов

Сервисы загружаются сразу после запуска терминала, если в момент остановки терминала они были запущены. Сервисы выгружаются сразу после окончания своей работы.

Сервисы имеют единственный обработчик OnStart(), в котором вы можете организовать бесконечный цикл получения и обработки данных, например - создание и обновление пользовательских символов при помощи сетевых функций.

В отличие от советников, индикаторов и скриптов, сервисы не привязаны к конкретному графику - поэтому для запуска сервиса предусмотрен отдельный механизм.  Создание нового экземпляра сервиса производится из Навигатора с помощью команды "Добавить сервис". Для запуска, остановки и удаления экземпляра сервиса используйте его меню. Для управления всеми экземплярами, используйте меню самого сервиса.

 

Для лучшего понимания работы эксперта рекомендуется скомпилировать код приведенного в примере эксперта и произвести действия по загрузке/выгрузке экспертов, смене шаблона, символа, таймфрейма и так далее:

Пример:

//+------------------------------------------------------------------+
//|                                                   TestExpert.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
class CTestClass
  {
public:  
   CTestClass() { Print("CTestClass constructor"); }
   ~CTestClass() { Print("CTestClass destructor"); }
  };
CTestClass global;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Print("Initialization");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Print("Deinitialization with reason ",reason);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
 
  }
//+------------------------------------------------------------------+

Скрипты загружаются сразу после прикрепления к графику и выгружаются сразу после окончания своей работы.

Смотри также

События клиентского терминала, Функции обработки событий