Тики в реальном времени - страница 15

 
Yuriy Zaytsev:

Но я смотрю в лог , а по логу один и то же тик  с разницей в 4 секунды приехал.

p.s.

Очень не люблю фразу - мысль  "не может быть"  , давно привык к тому что может быть все что угодно.

К слову, возможно это далеко от темы,  но когда то на утверждение, что земля круглая тоже говорили примерно так же - "этого не может быть".

Вообще всегда сомневаюсь , пока не проверю потом перепроверю, и желательно  кто то еще перепроверит несколько раз.


У Вас  точно код не лажает - который формирует лог, обрабатывает данные ? а то выходит  4 секунды разница

Тики уже в терминале, т.е они уже переданы по сети.

Код в открытом доступе подставьте в него

if(SymbolInfoTick(Symbol(), s_tick) == true)
  {
    Print("SymbolInfoTick: ",GetTickDescription(s_tick));
  }

И сами посмотрите

 
prostotrader:

Тики уже в терминале, т.е они уже переданы по сети.

Код в открытом доступе подставьте в него

И сами посмотрите

Спасибо, попробую, давно слежу за темой,  мне интересно скорее как исследователю.

это этот код лаганул на 4 секунды ?

//+------------------------------------------------------------------+
//|                                                   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[], s_tick;
ulong last_time, mem_cnt, tot_cnt;
bool is_first;
int t_cnt, result;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  tot_cnt = 0;
  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                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol());
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  if(symbol != Symbol()) return;
  tot_cnt++;
  if(SymbolInfoTick(Symbol(), s_tick) == true)
  {
    Print("SymbolInfoTick: ",GetTickDescription(s_tick));
  }
  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]));
      }
    //  l_tick = ticks[0];
      is_first = false;
      last_time = ulong(ticks[0].time_msc);                             //Запоминаем время последнего тика
    } 
  }
  else
  {
    if(SymbolInfoTick(Symbol(), s_tick) == true)
    {
      Print("SymbolInfoTick: ",GetTickDescription(s_tick));
    }
    result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //забираем тики из последнего (посчитанного пакета тикив и считываем тики из нового пакета)
    if(result > 0)
    {
     // l_tick = ticks[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

 

Видимо речь шла об этом коде

//+------------------------------------------------------------------+
//|                                                   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                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  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                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int 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                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &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                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
  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!");                          //Изменения стакана (добавлен/удален отложенный ордер)
    }
  }
}
//+------------------------------------------------------------------+
 

Добавил в код свое время.

Запоминаю время, когда сработал  OnTick() (t_time = GetMicrosecondCount();)

Затем беру время, при выполнении каждой функции

   t_time = GetMicrosecondCount();
//  if(symbol != Symbol()) return;
  //tot_cnt++;
  if(SymbolInfoTick(Symbol(), s_tick) == true)
  {
    func_time = GetMicrosecondCount();
    Print("SymbolInfoTick: time = ", string(func_time - t_time), " mcs ", GetTickDescription(s_tick));
  }
  double a_ask, a_bid, a_last;
  if (SymbolInfoDouble(Symbol(), SYMBOL_ASK, a_ask) == true)
  {
    func_time = GetMicrosecondCount();
    Print("SymbolInfoDouble: time = ", string(func_time - t_time), " mcs ", "ask = ", a_ask);
  }
  if (SymbolInfoDouble(Symbol(), SYMBOL_BID, a_bid) == true)
  {
    func_time = GetMicrosecondCount();
    Print("SymbolInfoDouble: time = ", string(func_time - t_time), " mcs ", "bid = ", a_bid);
  }
  if (SymbolInfoDouble(Symbol(), SYMBOL_LAST, a_last) == true)
  {
    func_time = GetMicrosecondCount();
    Print("SymbolInfoDouble: time = ", string(func_time - t_time), " mcs ", "last = ", a_last);
  }
  if(is_first == true)
  {
    result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0); //копируем все вновь пришедшие тики от последнего известного времени
    if(result > 0)
    {
      func_time = GetMicrosecondCount();
      t_cnt = 0;
      for(int i= 0; i<result; i++)
      {
        if(ticks[i].time_msc == ticks[0].time_msc) t_cnt++;             //Считаем кол-во тиков с одинаковым временем
        Print(__FUNCTION__, ": time = ", string(func_time - t_time), " mcs ", GetTickDescription(ticks[i]));

Результат

2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: time = 2 mcs 2020.02.04 13:09:10.720 Bid=1573.1 
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 28 mcs ask = 1573.3
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 33 mcs bid = 1573.1
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 36 mcs last = 1573.4
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       OnTick: time = 41 mcs 2020.02.04 13:09:10.720 Bid=1573.1 
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       OnTick: time = 41 mcs 2020.02.04 13:09:00.328 Ask=1573.3 

Т.е время выполнения каждой функции менее 50 микросекунд!

Откуда может взяться 4 секунды?

Думается, что работали два советника в одном терминале, а терминал просто не успевает

"сливать" в один лог всю инфу, вот и ставит локальное время как считает нужным.

 
prostotrader:

В торговых операциях, лично я, использую асинхронные ордера.

Дело в том (если серьезно торговать на Бирже), то нужны все изменения стакана,

и чем быстрее это событие придет - тем лучше.

Я, для себя, не вижу альтернативы ОнБук

Можно в принципе разгрузить непосредственный вызов торговых операций из  ОнБук. В ОнБук всего лишь формировать флаг на необходимость исполнить операцию, сам флаг обрабатывать уже в другом месте. Т.е. саму операцию начинать в другой процедуре по сформированному флагу, который создаст событие,  но после выхода из процедуры ОнБук, и тогда сам код ОнБук останется свободным от тяжелых операций. Впрочем если ордера открываются асинхронно , и нет безумно большой обработки условий ,  то вряд ли это вызовет существенные задержки.

 
prostotrader:

Добавил в код свое время.

Запоминаю время, когда сработал  OnTick() (t_time = GetMicrosecondCount();)

Затем беру время, при выполнении каждой функции

Результат

Т.е время выполнения каждой функции менее 50 микросекунд!

Откуда может взяться 4 секунды?

Думается, что работали два советника в одном терминале, а терминал просто не успевает

"сливать" в один лог всю инфу, вот и ставит локальное время как считает нужным.

Пожалуй верно , мало реальна такая дикая задержка.


1 - FLUSH отработал когда MQ это решил сам!

2 - Техническаа задержка записи на диск связанная с интенсивной работой с жестким диском


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

могу лишь предположить следующее:

например если в этот момент  параллельно ставить макйрософт офис - обновлять виндовс и записывать какой нибудь фильм из интернета , интенсивно работать с MS SQL который стоит на локале,

делать пару бекапов , иметь десятка 4 торентов  ну и еще два три десятка программ интенсивно пишуших на диск.

т е я хочу сказать что если была интенсивная работа с диском - вполне возможно и возникла задержка записи лога на диск.

 
Yuriy Zaytsev:

Пожалуй верно , мало реальна такая дикая задержка.


1 - FLUSH отработал когда MQ это решил сам!

2 - Техническаа задержка записи на диск связанная с интенсивной работой с жестким диском


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

могу лишь предположить следующее:

например если в этот момент  параллельно ставить макйрософт офис - обновлять виндовс и записывать какой нибудь фильм из интернета , интенсивно работать с MS SQL который стоит на локале,

делать пару бекапов , иметь десятка 4 торентов  ну и еще два три десятка программ интенсивно пишуших на диск.

т е я хочу сказать что если была интенсивная работа с диском - вполне возможно была задержка записи лога на диск.

Вряд ли с диском связано, время МТ ставит уже при записи лога в кэш свой. Вот что задумался терминал вообще на 4 сек может связано быть с общей загрузкой системы, скорее оперативки и проца. 
 
prostotrader:

Добавил в код свое время.

Запоминаю время, когда сработал  OnTick() (t_time = GetMicrosecondCount();)

Затем беру время, при выполнении каждой функции

Результат

Т.е время выполнения каждой функции менее 50 микросекунд!

Откуда может взяться 4 секунды?

Думается, что работали два советника в одном терминале, а терминал просто не успевает

"сливать" в один лог всю инфу, вот и ставит локальное время как считает нужным.

кстати - что бы не грешить на время записи в лог - можно добавить локальное время в массив - который вы формируете в коде - ниже

Тогда в логе будет четкая разница между временем когда терминал соизволил сбросить лог на диск  и временем локальным когда приехал тик или событие ОнБук.

И это будет более правильно с точки зрения исследования.

//+------------------------------------------------------------------+ 
//| возвращает строковое описание тика                               | 
//+------------------------------------------------------------------+ 
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; 
  } 
 
Aleksey Mavrin:
Вряд ли с диском связано, время МТ ставит уже при записи лога в кэш свой. Вот что задумался терминал вообще на 4 сек может связано быть с общей загрузкой системы, скорее оперативки и проца. 

ВЫ В ЭТОМ УВЕРЕНЫ ?


4 секунды ????  , да нееет!  Реально полагаете процессор завис на 4 секунды  или  память выделялась освобождалась 4 секунды ?   Вы шутите.

Более вероятно  это очередь записи на диск.

Диск устройство более медленное чем память и процессор.

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

Именно  ее вызывают когда нужно сбросить буфера на диск.

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