Главное событие экспертов: OnTick

Событие OnTick генерируется терминалом для экспертов при появлении нового тика с ценой рабочего символа текущего графика, на котором запущен эксперт. Для обработки этого события в коде эксперта должна быть определена функция OnTick со следующим прототипом.

void OnTick(void)

Как видно, функция не имеет параметров. При необходимости само значение новой цены и прочих характеристик тика следует запрашивать с помощью вызова SymbolInfoTick.

С точки зрения реакции на событие нового тика данный обработчик является аналогом OnCalculate в индикаторах. Однако OnCalculate можно определять только в индикаторах, а OnTick — только в экспертах (если более точно, функция OnTick в коде индикатора, скрипта или сервиса будет просто проигнорирована).

Вместе с тем, эксперт не обязан обязательно содержать обработчик OnTick. Помимо этого события эксперты могут обрабатывать события OnTimer, OnBookEvent, OnChartEvent и выполнять все необходимые торговые операции из них.

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

Событие OnTick генерируется независимо от того, запрещена или разрешена автоматическая торговля (кнопка Алготрейдинг в интерфейсе терминала). Запрет автоматической торговли означает только запрет на отправку торговых запросов из эксперта, но работа эксперта при этом не прекращается.

Следует напомнить, что события о тике генерируются только для одного символа — символа текущего графика. Если эксперт является мультивалютным, получение тиков с других символов следует организовать каким-либо альтернативным способом, например, с помощью индикатора-шпиона EventTickSpy.mq5 или подписки на события стакана, как в MarketBookQuasiTicks.mq5.

В качестве простого примера рассмотрим эксперт ExpertEvents.mq5. В нем определены обработчики всех событий, которые обычно используются для запуска торговых алгоритмов. Некоторые прочие события (OnTrade, OnTradeTransaction, а также события тестера) мы изучим позднее.

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

#define N_LINES 25
#include <MQL5Book/Comments.mqh>
   
void Display(const string message)
{
   ChronoComment((string)GetTickCount() + ": " + message);
}

Событие OnTick будет вызываться автоматически по приходу новых тиков. Для событий таймера и стакана необходимо активировать соответствующие обработчики с помощью вызовов EventSetTimer и MarketBookAdd в OnInit.

void OnInit()
{
   Print(__FUNCTION__);
   EventSetTimer(2);
   if(!MarketBookAdd(_Symbol))
   {
      Print("MarketBookAdd failed:"_LastError);
   }
}
   
void OnTick()
{
   Display(__FUNCTION__);
}
   
void OnTimer()
{
   Display(__FUNCTION__);
}
   
void OnBookEvent(const string &symbol)
{
   if(symbol == _Symbol// реагируем только на стаканы "своего" символа
   {
      Display(__FUNCTION__);
   }
}

Событие изменений графика также доступно: его можно использовать для торговли по разметке на основе графических объектов, по нажатию кнопок или горячих клавиш, а также по приходу пользовательских событий от других программ, например, индикаторов вроде EventTickSpy.mq5.

void OnChartEvent(const int idconst long &lparamconst double &dparamconst string &sparam)
{
   Display(__FUNCTION__);
}
   
void OnDeinit(const int)
{
   Print(__FUNCTION__);
   MarketBookRelease(_Symbol);
   Comment("");
}

На следующем скриншоте показан результат работы эксперта на графике.

Комментарии с событиями различных типов в эксперте
Комментарии с событиями различных типов в эксперте

Обратите внимание, что событие OnBookEvent (если оно транслируется для символа) поступает чаще, чем OnTick.