Функции обработки событий
В языке MQL5 предусмотрена обработка некоторых предопределенных событий. Функции для обработки этих событий должны быть определены в программе MQL5; имя функции, тип возвращаемого значения, состав параметров (если они есть) и их типы должны строго соответствовать описанию функции-обработчика события.
Именно по типу возвращаемого значения и по типам параметров обработчик событий клиентского терминала идентифицирует функции, обрабатывающие то или иное событие. Если у соответствующей функции указаны иные, не соответствующие нижеследующим описаниям, параметры, или указан иной тип возвращаемого значения, то такая функция не будет использоваться для обработки события.
Функция OnStart() является обработчиком события Start, которое автоматически генерируется только для запущенных на выполнение скриптов. Должна иметь тип void, параметров не имеет:
void OnStart(); |
Для функции OnStart() допустимо указывать тип возвращаемого значения int.
Функция OnInit() является обработчиком события Init. Может иметь тип void или int, параметров не имеет:
void OnInit(); |
Событие Init генерируется сразу после загрузки эксперта или индикатора, для скриптов это событие не генерируется. Функция OnInit() используется для инициализации. Если OnInit() имеет возвращаемого значения типа int, то ненулевой код возврата означает неудачную инициализацию и генерирует событие Deinit с кодом причины деинициализации REASON_INITFAILED.
Функция OnInit() типа void всегда означает удачную инициализацию.
Функция OnDeinit() вызывается при деинициализации и является обработчиком события Deinit . Должна быть объявлена с типом void и иметь один параметр типа const int , который содержит код причины деинициализации. Если объявлен иной тип, компилятор выдаст предупреждение, но функция вызываться не будет. Для скриптов событие Deinit не генерируется и поэтому использовать в скриптах функцию OnDeinit() нельзя.
void OnDeinit(const int reason); |
Событие Deinit генерируется для экспертов и индикаторов в следующих случаях:
Событие NewTick генерируется только для экспертов при поступлении нового тика по символу, к графику которого прикреплен эксперт. Функцию OnTick() бесполезно определять в пользовательском индикаторе или скрипте, поскольку событие Tick для них не генерируется.
Событие Tick генерируется только для экспертов, но это не означает, что эксперты обязаны иметь функцию OnTick(), так как для экспертов генерируются не только события Tick, но и события Timer, BookEvent и ChartEvent. Должна быть объявлена с типом void, параметров не имеет:
void OnTick(); |
Функция OnTimer() вызывается при наступлении события Timer, которое генерируется системным таймером только для экспертов и индикаторов – использовать ее в скриптах нельзя. Периодичность наступления этого события устанавливается при подписке на получение функцией EventSetTimer() уведомлений о событии Timer.
Отписывание от приема посылки событий таймера для конкретного эксперта производится функцией EventKillTimer(). Функция должна быть определена с типом void, параметров не имеет:
void OnTimer(); |
Рекомендуется вызывать функцию EventSetTimer() однократно в функции OnInit(), а функцию EventKillTimer() вызывать однократно в OnDeinit().
Каждый эксперт и каждый индикатор работает со своим таймером, и получает события только от него. При завершении работы mql5-программы таймер уничтожается принудительно, если он был создан, но не был отключен функцией EventKillTimer().
Функция вызывается при наступлении события Trade, которое возникает при изменении списка выставленных ордеров и открытых позиций, истории ордеров и истории сделок. При любом торговом действии (выставлении отложенного ордера, открытие/закрытие позиции, установка стопов, срабатывании отложенных ордеров и т.п.) соответствующим образом изменяется история ордеров и сделок и/или список позиций и текущих ордеров.
void OnTrade(); |
Пользователь должен самостоятельно в коде реализовать проверку состояния торгового счета при получении этого события (если это необходимо по условиям торговой стратегии). Если вызов функции OrderSend() завершился успешно и вернул значение true – это означает, что торговый сервер поставил ордер в очередь на исполнение и присвоил ему номер тикета. Как только сервер обработает данный приказ, будет сгенерировано событие Trade. И если пользователь запомнил значение тикета, то при обработке события OnTrade() он может по этому тикету выяснить что именно случилось с ордером.
Функция OnTester() является обработчиком события Tester, которое автоматически генерируется по окончании исторического тестирования эксперта на заданном интервале дат. Функция должна быть определена с типом double, параметров не имеет:
double OnTester(); |
Функция вызывается непосредственно перед вызовом функции OnDeinit() и имеет тип возвращаемого значения double. Функция OnTester() может быть использована только в экспертах при тестировании и предназначена в первую очередь для расчета некоторого значения, используемого в качестве критерия Custom max при генетической оптимизации входных параметров.
При генетической оптимизации сортировка результатов в пределах одного поколения производится по убыванию. То есть, лучшими с точки зрения критерия оптимизации считаются результаты с наибольшим значением (для критерия оптимизации Custom max в расчет принимаются значения, возвращенные функцией OnTester). Худшие значения при такой сортировке помещаются в конец и впоследствии отбрасываются и не принимают участия в формировании следующего поколения.
Функция OnBookEvent() является обработчиком события BookEvent. Событие BookEvent генерируется только для экспертов при изменении состояния стакана цен (Depth of Market). Должна иметь тип void и один параметр типа string:
void OnBookEvent (const string& symbol); |
Чтобы получать события BookEvent по любому символу, достаточно предварительно подписаться на получение этих событий для этого символа с помощью функции MarketBookAdd(). Для того, чтобы отписаться от получения события BookEvent по конкретному символу, необходимо вызывать функцию MarketBookRelease().
В отличие от других событий, событие BookEvent является широковещательным. Это означает, что достаточно одному эксперту подписаться на получение события BookEvent с помощью функции MarketBookAdd, все остальные эксперты, имеющие обработчик OnBookEvent(), будут получать это событие. Поэтому необходимо анализировать имя символа, которое передается в обработчик в качестве параметра const string& symbol.
OnChartEvent() является обработчиком группы событий ChartEvent:
Функция может вызываться в экспертах и индикаторах, должна иметь тип void и 4 параметра:
void OnChartEvent(const int id, // идентификатор события |
Для каждого типа события входные параметры функции OnChartEvent() имеют определенные значения, которые необходимы для обработки этого события. В таблице перечислены события и значения, которые передаются через параметры.
Событие |
Значение параметра id |
Значение параметра lparam |
Значение параметра dparam |
Значение параметра sparam |
Событие нажатия клавиатуры |
CHARTEVENT_KEYDOWN |
код нажатой клавиши |
— |
— |
Событие создания графического объекта |
CHARTEVENT_OBJECT_CREATE |
— |
— |
Имя созданного графического объекта |
Событие изменения свойств объекта через диалог свойств |
CHARTEVENT_OBJECT_CHANGE |
— |
— |
Имя измененного графического объекта |
Событие удаления графического объекта |
CHARTEVENT_OBJECT_DELETE |
— |
— |
Имя удаленного графического объекта |
Событие щелчка мыши графике |
CHARTEVENT_CLICK |
X координата |
Y координата |
— |
Событие щелчка мыши на графическом объекте |
CHARTEVENT_OBJECT_CLICK |
X координата |
Y координата |
Имя графического объекта, на котором произошло событие |
Событие перемещения графического объекта при помощи мыши |
CHARTEVENT_OBJECT_DRAG |
— |
— |
Имя перемещенного графического объекта |
событие окончания редактирования текста в поле ввода графического объекта "Поле ввода" |
CHARTEVENT_OBJECT_ENDEDIT |
— |
— |
Имя графического объекта "Поле ввода", в котором завершилось редактирование текста |
Пользовательское событие с номером N |
CHARTEVENT_CUSTOM+N |
Значение, заданное функцией EventChartCustom() |
Значение, заданное функцией EventChartCustom() |
Значение, заданное функцией EventChartCustom() |
Функция OnCalculate() вызывается только в пользовательских индикаторах при необходимости произвести расчет значений индикатора по событию Calculate. Обычно это происходит при поступлении нового тика по символу, для которого рассчитывается индикатор. При этом индикатор не обязательно должен быть прикреплен к какому-нибудь ценовому графику данного символа.
Функция OnCalculate() должна иметь тип возвращаемого значения int. Существует два варианта определения. В пределах одного индикатора нельзя использовать оба варианта функции.
Первая форма вызова предназначена для тех индикаторов, которые могут быть рассчитаны на одном буфере данных. Пример такого индикатора - Custom Moving Average.
int OnCalculate (const int rates_total, // размер массива price[] |
В качестве массива price[] может быть передана одна из ценовых таймсерий либо рассчитанный буфер какого-либо индикатора. Чтобы определить направление индексации в массиве price[], необходимо вызывать функцию ArrayGetAsSeries(). Чтобы не зависеть от умолчаний, необходимо безусловно вызывать функцию ArraySetAsSeries() для тех массивов, с которыми предполагается работать.
Выбор необходимой таймсерии или индикатора в качестве массива price[] производится пользователем при запуске индикатора на закладке "Parameters". Для этого необходимо указать нужный элемент в выпадающем списке поля "Apply to".

Для получения значений пользовательского индикатора из других mql5-программ используется функция iCustom(), возвращающая хэндл индикатора для последующих операций. При этом также можно указать необходимый массив price[] или хэндл другого индикатора. Этот параметр должен передаваться последним в списке входных переменных пользовательского индикатора.
Пример:
void OnStart() |
В данном примере последним параметром передано значение PRICE_TYPICAL (из перечисления ENUM_APPLIED_PRICE ), которое указывает, что пользовательский индикатор будет построен по типическим ценам, полученным как (High+Low+Close)/3. Если параметр не указывается, то индикатор строится по значениям PRICE_CLOSE, то есть по ценам закрытия каждого бара.
Другой пример, демонстрирующий передачу хендла индикатора последним параметром для указания массива price[], приведен в описании функции iCustom().
Вторая форма вызова предназначена для всех остальных индикаторов, у которых для расчета используется более чем одна таймсерия.
int OnCalculate (const int rates_total, // размер входных таймсерий |
Параметры open[], high[], low[] и close[] содержит массивы с ценами открытия, максимальной, минимальной ценами и ценами закрытия текущего таймфрейма. Параметр time[] содержит массив со значениями времени открытия, параметр spread[] – массив, содержащий историю спредов (если спред предусмотрен для данного торгового инструмента). Параметры volume[] и tick_volume[] содержат соответственно историю торгового и тикового объема.
Чтобы определить направление индексации в массивах time[], open[], high[], low[], close[], tick_volume[], volume[] и spread[], необходимо вызывать функцию ArrayGetAsSeries(). Чтобы не зависеть от умолчаний, необходимо безусловно вызывать функцию ArraySetAsSeries() для тех массивов, с которыми предполагается работать.
Первый параметр rates_total содержит количество баров, доступных индикатору для расчета, и соответствует количеству баров, доступных на графике.
Необходимо отметить связь между значением, возвращаемым функцией OnCalculate() и вторым входным параметром prev_calculated. Параметр prev_calculated при вызове функции содержит значение, которое вернула функция OnCalculate() на предыдущем вызове. Это позволяет реализовать экономные алгоритмы расчета пользовательского индикатора с тем, чтобы избежать повторных расчетов для тех баров, которые не изменились с предыдущего запуска этой функции.
Для этого обычно достаточно вернуть значение параметра rates_total, которое содержит количество баров при текущем вызове функции. Если с момента последнего вызова функции OnCalculate() ценовые данные были изменены (подкачана более глубокая история или были заполнены пропуски истории), то значение входного параметра prev_calculated будет установлено в нулевое значение самим терминалом.
Примечание: если функция OnCalculate возвращает нулевое значение, то в окне DataWindow клиентского терминала значения индикатора не показываются.
Для лучшего понимания будет полезно запустить индикатор, код которого приложен ниже.
Пример индикатора:
#property indicator_chart_window |
Смотри также
Выполнение программ, События клиентского терминала, Работа с событиями
© 2000-2010, MetaQuotes Software Corp.