OnBookEvent

Вызывается в индикаторах и экспертах при наступлении события BookEvent. Функция предназначена для обработки изменений стакана цен (Depth of Market).

void  OnBookEvent(
   const string&  symbol         // символ
   );

Параметры

symbol

[in]  Имя финансового инструмента, по которому пришло событие BookEvent

Возвращаемое значение

Нет возвращаемого значения

Примечание

Чтобы получать события BookEvent по любому символу, достаточно предварительно подписаться на получение этих событий для этого символа с помощью функции MarketBookAdd(). Для того чтобы отписаться от получения события BookEvent по конкретному символу, необходимо вызывать функцию MarketBookRelease().

Событие BookEvent является широковещательным в пределах графика. Это означает, что достаточно одному приложению на графике подписаться на получение события BookEvent с помощью функции MarketBookAdd, как все остальные индикаторы и эксперты, запущенные на этом графике и имеющие обработчик OnBookEvent(), будут получать это событие. Поэтому необходимо анализировать имя символа, которое передается в обработчик OnBookEvent() в качестве параметра symbol.

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

Начальное значение счетчика подписок равно нулю. При каждом вызове MarketBookAdd() счетчик подписок для указанного символа на данном графике увеличивается на единицу (символ графика и символ в MarketBookAdd() не обязаны совпадать). При вызове MarketBookRelease() счетчик подписок на указанный символ в пределах графика уменьшается на единицу. Трансляция событий BookEvent по любому символу в пределах графика продолжается до тех пор, пока счетчик подписок по данному символу не станет равным нулю. Поэтому важно, чтобы каждая MQL5-программа, которая содержит вызовы MarketBookAdd(), при завершении своей работы правильно отписывалась от получения событий по каждому использованному символу с помощью MarketBookRelease(). Для этого достаточно, чтобы количество вызовов MarketBookAdd() и MarketBookRelease() по каждому вызову было четным за всё время жизни MQL5-программы. Использование флагов или собственных счетчиков подписок внутри программы позволяет безопасно работать с событиями BookEvent и предотвращает отключение подписок на получение этого события в чужих программах в пределах одного графика.

События BookEvent никогда не пропускаются и всегда ставятся в очередь, даже если в данный момент еще не закончена обработка предыдущего события BookEvent. При этом необходимо иметь в виду, что события BookEvent доставляются сами по себе и не несут с собой состояния стакана заявок. Это означает, что вызов MarketBookGet() из обработчика OnBookEvent() позволяет получить текущее актуальное состояние стакана на момент вызова, а не то состояние стакана, которое вызвало отправку события BookEvent. Для гарантированного получения всех уникальных состояний стакана функция OnBookEvent() должна быть максимально быстрой.

 

Пример

//+------------------------------------------------------------------+
//|                                           OnBookEvent_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com/ru/articles/2635"
#property version   "1.00"
#property description "Пример замера скорости обновления стакана с помощью OnBookEvent()"
#property description "Код взят из статьи https://www.mql5.com/ru/articles/2635"
//--- входные параметры
input ulong ExtCollectTime   =30;  // время теста в секундах
input ulong ExtSkipFirstTicks=10;  // количество пропускаемых тиков на старте
//--- флаг наличия подписки на получение событий BookEvent
bool book_subscribed=false;
//--- массив для приема заявок из стакана
MqlBookInfo  book[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- покажем старт
   Comment(StringFormat("Ждем поступления первых %I64u тиков",ExtSkipFirstTicks));
   PrintFormat("Ждем поступления первых %I64u тиков",ExtSkipFirstTicks);
//--- включим трансляцию стакана
   if(MarketBookAdd(_Symbol))
     {
      book_subscribed=true;
      PrintFormat("%s: Функция MarketBookAdd(%s) вернула true",__FUNCTION__,_Symbol);
     }
   else
      PrintFormat("%s: Функция MarketBookAdd(%s) вернула false! GetLastError()=%d",__FUNCTION__,_Symbol,GetLastError());
//--- успешная инициализация
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Deinitialize expert                                              |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- выведем код причины деинициализации
   Print(__FUNCTION__,": Код причины деинициализации = ",reason);  
//--- отменим свою подписку на получение событий стакана
   if(book_subscribed)
     {
      if(!MarketBookRelease(_Symbol))
         PrintFormat("%s: MarketBookRelease(%s) вернула false! GetLastError()=%d",_Symbol,GetLastError());
      else
         book_subscribed=false;
     }
//--- 
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
   static ulong starttime=0;             // время начала теста
   static ulong tickcounter=0;           // счетчик обновлений стакана цен
//--- работаем с событиями стакана только в том случае, если мы сами на него подписались 
   if(!book_subscribed)
      return;
//--- считаем обновления только по своему символу
   if(symbol!=_Symbol)
      return;
//--- пропускаем первые тики для первичной очистки очереди и разогрева
   tickcounter++;
   if(tickcounter<ExtSkipFirstTicks)
      return;
//--- запомним время старта
   if(tickcounter==ExtSkipFirstTicks
      starttime=GetMicrosecondCount();
//--- запросим данные стакана
   MarketBookGet(symbol,book);
//--- когда надо остановиться?   
   ulong endtime=GetMicrosecondCount()-starttime;
   ulong ticks  =1+tickcounter-ExtSkipFirstTicks;
// сколько прошло времени в микросекундах с начала теста?
   if(endtime>ExtCollectTime*1000*1000) 
     {
      PrintFormat("%I64u ticks for %.1f seconds: %.1f ticks/sec ",ticks,endtime/1000.0/1000.0,ticks*1000.0*1000.0/endtime);
      ExpertRemove();
      return;
     }
//--- вывод счетчиков в поле комментария
   if(endtime>0)
      Comment(StringFormat("%I64u ticks for %.1f seconds: %.1f ticks/sec ",ticks,endtime/1000.0/1000.0,ticks*1000.0*1000.0/endtime));
  }

 

 

Смотри также

MarketBookAdd, MarketBookRelease, MarketBookGet, OnTrade, OnTradeTransaction, OnTick, Функции обработки событий, Выполнение программ, События клиентского терминала