На секунду показалось, что у вас есть желание разобраться и оно поможет усмирить гордыню. Нет, только показалось.
В целом, вопрос раскрыт, и любой желающий сможет посмотреть и ваш, и fxsaber-а и мой коды, и сделать выводы. С вами диалог прекращаю, ничего кроме громких криков от вас не исходит, а на прием информации ваш мозг вообще не работает.
Сергей, мы используем On-функции просто как точку входа.
Вопрос заключался в том, какая точка входа наступит раньше (отдав при этом одинаково правильную информацию о последнем тике).
Запустите мой советник, и посмотрите в лог. Время события (с точностью до мс) и время последнего известного тика (тоже с мс) выводится в лог.
Просто проанализируйте несколько отдельных тиков на предмет "кто раньше".
Это вы неправильно делаете. Возможно событие стакана пришло, но в историю тиков еще не попало. Надо сравнивать цены Bid Ask, а не копаться в истории тиков.
Не думаю, что ОнТик ее проходит. И тесты это подтверждают, ни какой задержки нет.
Прежде чем попасть в историю тики обязательно обрабатываются, а так же раздаются всем необходимым чартам, индикаторам и советникам. И всё это в МТ5 делается последовательно (не распаралеливается).
Возможно, с помощью CopyTicks.
Нет, с помощью CopyTicks тоже невозможно получить лучшую цену, а вдруг это свой ордер стоит лучшим.
Нужно признать, что OnBookEvent() и OnTick() все тики совпадают (у меня была ошибка в коде),
но другие изменения стакана ни как не отражаются в OnTick()
Для ФОРЕКСников это не важно.(Осторожная цитата от сообщения выше: " В 2 раза больше событий ОнБук. Жаль, что далеко не все они несут полезную нагрузку (если нужны бест бид/аск и ласт)".)
Исправленный код:
//+------------------------------------------------------------------+//| Ticks_test.mq5 |//| Copyright 2019 prostotrader |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2019 prostotrader"#property link"https://www.mql5.com"#property version"1.00"//---bool is_book;
MqlTick ticks[];
ulong last_time, mem_cnt, tot_cnt;
bool is_first;
int t_cnt, result;
enum ENUM_BOOK_OR_TICK
{
USE_BOOK, // Use OnBookEvent
USE_TICK // Use OnTick
};
input ENUM_BOOK_OR_TICK Mode = USE_BOOK;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+intOnInit()
{
tot_cnt = 0;
if(Mode == USE_BOOK) is_book = MarketBookAdd(Symbol());
result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
if(result > 0)
{
last_time = ulong(ticks[0].time_msc); //запоминаем время последнего известного тика
is_first = true;
}
else
{
is_first = false;
Alert("No start time!");
return(INIT_FAILED);
}
ArraySetAsSeries(ticks, true);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+ //| возвращает строковое описание тика | //+------------------------------------------------------------------+ string GetTickDescription(MqlTick &tick)
{
string res = string(tick.time) + "." + string(tick.time_msc%1000);
// bool buy_tick = ((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY);
bool sell_tick = ((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL);
bool ask_tick = ((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK);
bool bid_tick = ((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID);
bool last_tick = ((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST);
bool volume_tick = ((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME);
// if((buy_tick== true) || (sell_tick == true))
{
res = res + (buy_tick?StringFormat(" Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
res = res + (sell_tick?StringFormat(" Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):"");
res = res + (bid_tick?StringFormat(" Bid=%G ",tick.bid):"");
}
else
{
res = res + (ask_tick?StringFormat(" Ask=%G ",tick.ask):"");
res = res + (bid_tick?StringFormat(" Bid=%G ",tick.bid):"");
res = res + (last_tick?StringFormat(" Last=%G ",tick.last):"");
res = res + (volume_tick?StringFormat(" Volume=%d ",tick.volume):"");
}
return res;
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
if(Mode == USE_BOOK)
{
Print("USE_BOOK ticks received: ", tot_cnt);
if(is_book == true) MarketBookRelease(Symbol());
}
else
{
Print("USE_TICK ticks received: ", tot_cnt);
}
}
//+------------------------------------------------------------------+//| BookEvent function |//+------------------------------------------------------------------+voidOnBookEvent(conststring &symbol)
{
if ( Mode != USE_BOOK || symbol != Symbol() ) return;
tot_cnt++;
if(is_first == true)
{
result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //копируем все вновь пришедшие тики от последнего известного времениif(result > 0)
{
t_cnt = 0;
for(int i= 0; i<result; i++)
{
if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++; //Считаем кол-во тиков с одинаковым временемPrint(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
}
is_first = false;
last_time = ulong(ticks[0].time_msc); //Запоминаем время последнего тика
}
}
else
{
result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //забираем тики из последнего (посчитанного пакета тикив и считываем тики из нового пакета)if(result > 0)
{
if(result > t_cnt)
{
mem_cnt = t_cnt;
t_cnt = 0;
for(int i= 0; i<(result - int(mem_cnt)); i++)
{
if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++; //Считаем кол-во тиков с одинаковым временемPrint(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
}
if(last_time == ulong(ticks[0].time_msc))
{
t_cnt += int(mem_cnt);
}
else last_time = ulong(ticks[0].time_msc);
}
else
{
Print(__FUNCTION__, ": Pending order!"); //Изменения стакана (добавлен/удален отложенный ордер)
}
}
else
{
Print(__FUNCTION__, ": Pending order!"); //Изменения стакана (добавлен/удален отложенный ордер)
}
}
}
//+------------------------------------------------------------------+//| OnTick function |//+------------------------------------------------------------------+voidOnTick()
{
if ( Mode != USE_TICK ) return;
tot_cnt++;
if(is_first == true)
{
result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //копируем все вновь пришедшие тики от последнего известного времениif(result > 0)
{
t_cnt = 0;
for(int i= 0; i<result; i++)
{
if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++; //Считаем кол-во тиков с одинаковым временемPrint(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
}
is_first = false;
last_time = ulong(ticks[0].time_msc); //Запоминаем время последнего тика
}
}
else
{
result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //забираем тики из последнего (посчитанного пакета тикив и считываем тики из нового пакета)if(result > 0)
{
if(result > t_cnt)
{
mem_cnt = t_cnt;
t_cnt = 0;
for(int i= 0; i<(result - int(mem_cnt)); i++)
{
if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++; //Считаем кол-во тиков с одинаковым временемPrint(__FUNCTION__, ": ",GetTickDescription(ticks[i]));
}
if(last_time == ulong(ticks[0].time_msc))
{
t_cnt += int(mem_cnt);
}
else last_time = ulong(ticks[0].time_msc);
}
else
{
Print(__FUNCTION__, ": Pending order!"); //Изменения стакана (добавлен/удален отложенный ордер)
}
}
else
{
Print(__FUNCTION__, ": Pending order!"); //Изменения стакана (добавлен/удален отложенный ордер)
}
}
}
//+------------------------------------------------------------------+
Нужно признать, что OnBookEvent() и OnTick() все тики совпадают (у меня была ошибка в коде),
но другие изменения стакана ни как не отражаются в OnTick()
Для ФОРЕКСников это не важно.(Осторожная цитата от сообщения выше: " В 2 раза больше событий ОнБук. Жаль, что далеко не все они несут полезную нагрузку (если нужны бест бид/аск и ласт)".)
Исправленный код:
Результат (фрагмент)
Тики в истории конечно будут совпадать, но на картинке выше, получается не все инфо-тики попадают в историю или пропускаются в OnCalculat.
Не знаю может ошибка есть, теперь уже в понедельник буду разбираться.
Зачем копировать, если можно сразу получить текущую цену? В теории, CopyTicks в своих потрохах, имеет дополнительные проверки параметров, чем увеличивает длину кода в теле функции. А SymbolInfoTick не имеет дополнительных параметров, и по идее реализация данной функции должна содержать меньше кода. Меньше кода - быстрее выполнение.
Единственно что плохо, по функции SymbolInfoTick нет подробной документации, как у CopyTicks, и до конца не ясно как она работает. Кэширует, или сразу отдаёт сырец то что пришло.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Хочу напомнить, что в OnTick поступают два независимых потока, информационный и торговый, COPY_TICKS_INFO и COPY_TICKS_ALL и проходит предобработку.
Эти потоки не синхронизированы между собой, поэтому если сравнивать OnBookEvent с OnTick, то надо брать TICKS_INFO.
OnBookEvent по определению должен быть быстрее , т.к. не проходит предобработку.
Тестами достоверно определить невозможно кто быстрее, т.к. мы не знаем биржевое время стакана в отличие от тиков.
Хотя много раз просили разработчиков, ДОБАВЬТЕ ВРЕМЯ СТАКАНА ! ! !
p.s. кроме скорости стакан имеет еще преимущества перед OnTick,
как уже было сказано, в OnTick невозможно получить лучшую цену Bid и Ask,
и в OnTick не приходят данные с других символов, для советников анализирующих несколько инструментов бесполезен.
заменил COPY_TICKS_ALL на COPY_TICKS_INFO
Результат
Отмеченное желтым - один и тот же тик!
Вероятно, в коде все же есть неточность?...На секунду показалось, что у вас есть желание разобраться и оно поможет усмирить гордыню.
Нет, только показалось.
В целом, вопрос раскрыт, и любой желающий сможет посмотреть и ваш, и fxsaber-а и мой коды, и сделать выводы.
С вами диалог прекращаю, ничего кроме громких криков от вас не исходит, а на прием информации ваш мозг вообще не работает.
Удачи на ФОРТСЕ.
Хочу напомнить, что в OnTick поступают два независимых потока, информационный и торговый, COPY_TICKS_INFO и COPY_TICKS_ALL и проходит предобработку.
Эти потоки не синхронизированы между собой, поэтому если сравнивать OnBookEvent с OnTick, то надо брать TICKS_INFO.
Сергей, мы используем On-функции просто как точку входа.
Вопрос заключался в том, какая точка входа наступит раньше (отдав при этом одинаково правильную информацию о последнем тике).
Запустите мой советник, и посмотрите в лог. Время события (с точностью до мс) и время последнего известного тика (тоже с мс) выводится в лог.
Просто проанализируйте несколько отдельных тиков на предмет "кто раньше".
OnBookEvent по определению должен быть быстрее , т.к. не проходит предобработку.
Не думаю, что ОнТик ее проходит. И тесты это подтверждают, ни какой задержки нет.
как уже было сказано, в OnTick невозможно получить лучшую цену Bid и Ask
Возможно, с помощью CopyTicks.
Запустите мой советник, и посмотрите в лог. Время события (с точностью до мс) и время последнего известного тика (тоже с мс) выводится в лог.
Просто проанализируйте несколько отдельных тиков на предмет "кто раньше".
Обычная ситуация, когда ОнБук приходит одновременно с ОнТик или на 1-2 мс позже. Но бывают и лаги:
За 5 часов работы:
В 2 раза больше событий ОнБук. Жаль, что далеко не все они несут полезную нагрузку (если нужны бест бид/аск и ласт).
Сергей, мы используем On-функции просто как точку входа.
Вопрос заключался в том, какая точка входа наступит раньше (отдав при этом одинаково правильную информацию о последнем тике).
Запустите мой советник, и посмотрите в лог. Время события (с точностью до мс) и время последнего известного тика (тоже с мс) выводится в лог.
Просто проанализируйте несколько отдельных тиков на предмет "кто раньше".
Это вы неправильно делаете. Возможно событие стакана пришло, но в историю тиков еще не попало. Надо сравнивать цены Bid Ask, а не копаться в истории тиков.
Не думаю, что ОнТик ее проходит. И тесты это подтверждают, ни какой задержки нет.
Прежде чем попасть в историю тики обязательно обрабатываются, а так же раздаются всем необходимым чартам, индикаторам и советникам. И всё это в МТ5 делается последовательно (не распаралеливается).
Возможно, с помощью CopyTicks.
Просто проанализируйте несколько отдельных тиков на предмет "кто раньше".
У меня по разному получается:
синие линии это OnBook,
красные OnCalculat = OnTick.
Если интересно могу код индикатора показать
У меня по разному получается:
синие линии это OnBook,
красные OnTick.
Если интересно могу код индикатора показать
Да нет Сереж!
Нужно признать, что OnBookEvent() и OnTick() все тики совпадают (у меня была ошибка в коде),
но другие изменения стакана ни как не отражаются в OnTick()
Для ФОРЕКСников это не важно.(Осторожная цитата от сообщения выше: " В 2 раза больше событий ОнБук. Жаль, что далеко не все они несут полезную нагрузку (если нужны бест бид/аск и ласт)".)
Исправленный код:
Результат (фрагмент)Да нет Сереж!
Нужно признать, что OnBookEvent() и OnTick() все тики совпадают (у меня была ошибка в коде),
но другие изменения стакана ни как не отражаются в OnTick()
Для ФОРЕКСников это не важно.(Осторожная цитата от сообщения выше: " В 2 раза больше событий ОнБук. Жаль, что далеко не все они несут полезную нагрузку (если нужны бест бид/аск и ласт)".)
Исправленный код:
Результат (фрагмент)
Тики в истории конечно будут совпадать, но на картинке выше, получается не все инфо-тики попадают в историю или пропускаются в OnCalculat.
Не знаю может ошибка есть, теперь уже в понедельник буду разбираться.
А может для реал тайм, вместо
использовать
Зачем копировать, если можно сразу получить текущую цену?
В теории, CopyTicks в своих потрохах, имеет дополнительные проверки параметров, чем увеличивает длину кода в теле функции.
А SymbolInfoTick не имеет дополнительных параметров, и по идее реализация данной функции должна содержать меньше кода.
Меньше кода - быстрее выполнение.
Единственно что плохо, по функции SymbolInfoTick нет подробной документации, как у CopyTicks, и до конца не ясно как она работает.
Кэширует, или сразу отдаёт сырец то что пришло.