Потеря тиковых данных на срочном рынке Московской биржи. - страница 2

 
Ilya Baranov:

Откуда информация, что OnBookEvent не пропускает?

Как проверяли?

Шестилетней непрерывной торговлей на реале ФОРТС в МТ5,

Ну и подумать немного следует почему не пропускает....

Проверьте сами и с удивлением увидите, что в OnBookEvent(), иногда, result = 0 :)


//+------------------------------------------------------------------+
//|                                                       onBook.mq5 |
//|                                     Copyright 2019, prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//
bool my_book;
ulong mem_time;
MqlTick cur_ticks[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
    my_book = MarketBookAdd(Symbol());
    if(my_book == false)
    {
      Alert("Не добавлен стакан фьючерса ", Symbol());
      return(INIT_FAILED);
    }
    int result = CopyTicks(Symbol(), cur_ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
       mem_time = ulong(cur_ticks[0].time_msc);
    }
    else
    {
      Alert("Не получено начальное время тиков!");
      return(INIT_FAILED);
    }    
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
    if(my_book == true) MarketBookRelease(Symbol()); 
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
    if(symbol == Symbol())
    {
      int result = CopyTicks(Symbol(), cur_ticks, COPY_TICKS_ALL, mem_time, 0);
      if(result > 0)
      {
       //Place you code here
        mem_time = ulong(cur_ticks[result - 1].time_msc + 1);
      }  
    }
  }
//+------------------------------------------------------------------+
 
Igor Zakharov:

Для HFT используется асинхронные приказы (отправили и не ждём ответ). Судя по вышеописанному, вы используете синхронные (отправили и ждём ответ сервера).

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

 
Ihor Herasko:

Какой комментарий Вы хотите услышать от разработчиков, если сами же правильно процитировали справку? Не может советник по определению обработать все тики, потому и пропускает их. Больше добавить нечего. 

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

Если же задача лишь в том, чтобы собрать все тики, то используйте индикатор. Он тики не пропускает. 

Для разработчиков MetaQuotes Software я хотел акцентировать внимание, что отсутствие буферизации приводит к тому, что один и тот же код на бэктесте и на реальных торгах ведет из-за этого совершенно по разному. Можно конечно считать это фичей, но с моей точки зрения скорее баг. Кроме того для события OnBookEvent(), буферизация реализована. По моему мнению, было бы здорово, если события  OnTick() тоже ставились в очередь.

 
prostotrader:

Советник на реале может обрабатывать все тики, а в тестере нет (по крайней мере раньше так было).

Смотрите здесь https://www.mql5.com/ru/code/16210

madpower2000, выложите часть кода, где Вы получаете и обрабатываете тики

void OnTick()
{
  MqlTick tick = {0};
  if(!SymbolInfoTick(_Symbol, tick)) {  Alert("SymbolInfoTick() failed, error = "+(string)GetLastError()); return; }
  TickID++;
  log_file.WriteString(
        (string)TickID + "," +
        TimeToString(tick.time, TIME_DATE) + "," +
        TimeToString(tick.time, TIME_SECONDS) + "," +
        (string)tick.time_msc + "," +
        (string)tick.bid + "," +
        (string)tick.ask + "," +
        (string)tick.last + "," +
        (string)tick.volume + "," +
        (string)tick.volume_real + "," +
        (string)(int)((tick.flags & TICK_FLAG_BID)>0) + "," +
        (string)(int)((tick.flags & TICK_FLAG_ASK)>0) + "," +
        (string)(int)((tick.flags & TICK_FLAG_LAST)>0) + "," +
        (string)(int)((tick.flags & TICK_FLAG_VOLUME)>0) + "," +
        (string)(int)((tick.flags & TICK_FLAG_BUY)>0) + "," +
        (string)(int)((tick.flags & TICK_FLAG_SELL)>0) + "\r\n"
       );
}
 
Ilya Baranov:

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

См. вот эту ветку, там описание как это делается, в конце решения для обхода некоторых нюансов.

https://www.mql5.com/ru/forum/317990

Спасибо огромное за наводку, честно говоря у меня промелькнула идея протестировать CopyTicksRange(), но мне подумалось что каждый раз копировать массив при вызове OnTick() будет не продуктивно, если я его могу и так собрать все данные в обработчике OnTick()...

 
madpower2000:

Не правильно делаете.

См. мои посты выше.

 
prostotrader:

Шестилетней непрерывной торговлей на реале ФОРТС в МТ5,

Ну и подумать немного следует почему не пропускает....

Проверьте сами и с удивлением увидите, что в OnBookEvent(), иногда, result = 0 :)


Спасибо за совет, но OnBookEvent() не работает в бэктестере, как тогда тестировать стратегию?

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

 
madpower2000:

Спасибо за совет, но OnBookEvent() не работает в бэктестере, как тогда тестировать стратегию?

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

Тестировать стратегию можно на реале, эмулируя сделки.

Или на истории тиков, правда поизголятся придется.

Очень важно откуда вызывать CopyTicks(), но дело ваше...

 
prostotrader:

Тестировать стратегию можно на реале, эмулируя сделки.

Или на истории тиков, правда поизголятся придется.

Очень важно откуда вызывать CopyTicks(), но дело ваше...

Это вопрос на знание микроструктуры рынка и механизма работы OrderBook? :)

Result =0  потому что нет новых тиков, а их нет потому что, не произошло операций покупки/продажи, и/или  best bid/ask не менялся, но были приказы на добавление или удаление ордеров из книги заявок которые и  вызвали OnBookEvent().

Вообще вопрос работы с книгой заявок (OrderBook) в MT5 я бы сказал щепетильный и вот почему:

  • Невозможность его использовать при бэктестинге, т.е.  например OrderBook imbalance не посчитать на истории..
  • Получить срез стакана с биржи, если предположить, что сервер MT5 у брокера подключен через PLAZA (а это может быть и FIX протокол -   ту опять вопрос к разработчикам MetaQuotes Ltd.) можно через FORTS_FUTORDERBOOK_REPL, но надо понимать, что это одномоментный срез и например в случае если ликвидность рынка не большая и было несколько ордеров которую эту ликвидность собрали, и на рынке большая активность, то срез стакана, пока он дойдет до вашего терминала и реальная ситуация будут различаться весьма драматическим образом.
  • Другая возможность, это получать FORTS_ORDLOG_REP и собирать стакан самостоятельно на стороне клиента, тогда рассинхронизации стакана будут исключены. Но в  MT5 такой алгоритм скорее не будет реализован никогда, так как MT5 все же нацелен на ритейл FX-рынок, публику использующие индикаторы и прочую магию, и кроме того это большая нагрузка на канал передачи данных. Также возможно, что  сервер MT5 у брокера получает FORTS_ORDLOG_REP (косвенно об этом говорит, что они все-таки транслируют признак покупки/продажи в тиковой истории), строит стакан на севере у брокера и далее транслирует его в терминал, но опять вопрос каким образом это происходит и какие задержки могут возникать на стороне клиента - непонятно. Хотя любопытно было бы эту информацию от разработчиков MetaQuotes Ltd. получить!
 
madpower2000:

1.Речь идет не о ДЕМО акаунте, а о реальном торговом акаунте

2.Есть доступ

Причина обращения: