Полторы минуты разницы между локальным временем и временем свежего тика. Что делать. - страница 2

 
prostotrader:

Есть исходный код с комментариями.

Лень посмотреть? Или что-то не понятно?

Посмотрел. Идею я и без кода понял. Не понятно почему вы мне советуете :

prostotrader:

Нужно добавить в Обзор рынка самые ликвидные инструменты.

Затем, добавить стаканы этих инструментов.

И, при срабатывании OnBookEvent(), копировать 1 тик (последний) там будет время и тут же брать локальное время и сравнивать.

Чем ваш метод лучше ? 

 
pivomoe:

Посмотрел. Идею я и без кода понял. Не понятно почему вы мне советуете :

Чем ваш метод лучше ? 

Потому что он правильный!

Я ошибся, не локальное время, а время сервера.

1. Тики приходят в терминал пакетами.

2. Каждый последующий пакет может содержать тики, которые не были "уложены" в предыдущий пакет, но имеют время совпадающее с предыдущим.

3. OnBookEvent() срабатывает по приходу любого тика (Изменение цены, объёма ) т.е каждого тика. (вы запускаете таймер - уже плохо).

4. Вы используете локальное время компа, что вообще не нужно!

 

Вот, собственно, все что нужно для торговли (проверка торгового времени сессий)

//+------------------------------------------------------------------+
//|                                                         Time.mq5 |
//|                                                   Copyright 2019 |
//|                                                                  |
//+------------------------------------------------------------------+
int is_book;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  is_book = MarketBookAdd(Symbol());
  if(is_book == false) return(INIT_FAILED);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol()); 
}
//+------------------------------------------------------------------+
// Expert Book event function                                        |
//+------------------------------------------------------------------+  
void OnBookEvent(const string &symbol)
{
  if(symbol == Symbol())
  {
    if(CheckMarketTime() == true)
    {
     //Торговое время
     //Наш код
    }
  }
}
//+------------------------------------------------------------------+
//| Expert Check Market Time function                                |
//+------------------------------------------------------------------+
bool CheckMarketTime()
{
  MqlDateTime cur_time, sv_time;
  MqlTick ticks[];
  cur_time.year = 0;
  TimeTradeServer(cur_time); //Возвращает расчетное текущее время торгового сервера.
  if(cur_time.year > 0)
  {
    int result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      if(TimeToStruct(ticks[0].time, sv_time) == true)
      {
        if(sv_time.day_of_year == cur_time.day_of_year)      //Проверка, что это сегодняшний тик
        {
          ulong tr_time = sv_time.hour * 3600 + sv_time.min * 60 + sv_time.sec;
          if(((tr_time >= 3600) && (tr_time < 50370)) ||   //10:00:00 - 13:59:30
             ((tr_time >= 50700) && (tr_time < 67470)) ||  //14:05:00 - 19:44:30 
             ((tr_time >= 68700) && (tr_time < 85770)))    //19:05:00 - 23:49:30
          {
            return(true);
          }
        }
      }
    }
  }   
  return(false);
} 

Добавлено

Если нужна миллисекундная точность, то так

double t_msc = double(ticks[0].time_msc - ulong(ticks[0].time) * 1000)/1000; //Получаем в секундах
double tr_time = sv_time.hour * 3600 + sv_time.min * 60 + sv_time.sec + t_msc;

Добавлено

Но все это не даст желаемого результата (границы торгового времени), потому что

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

Допустим, кто-то убрал свой отложенный ордер, стакан изменился,

есть сигнал, а там "старая"  корировка (время не текущее).

Терминал не транслирует точное время сервера.

 

Вы меня не понимаете. Давайте с самого начала.

1) В программе вы вызываете функцию TimeCurrent() и получаете время прихода последней котировки по одному из выбранных в "Обзоре рынка" символов.

  Пусть это будет 18:00:00

2) Следующей командой вы получаете время последнего тика по SBER.

    Пусть это будет 17:58:00

3) Проходит немного времени и вы опять запрашиваете время последнего тика по SBER.

    Пусть это будут 17:59:00


Внимание вопрос: Считаете ли вы нормальным в 18:00:00 по TimeCurrent() не знать о тике со временем 17:59:00 ?

 
pivomoe:

Вы меня не понимаете. Давайте с самого начала.

1) В программе вы вызываете функцию TimeCurrent() и получаете время прихода последней котировки по одному из выбранных в "Обзоре рынка" символов.

  Пусть это будет 18:00:00

2) Следующей командой вы получаете время последнего тика по SBER.

    Пусть это будет 17:58:00

3) Проходит немного времени и вы опять запрашиваете время последнего тика по SBER.

    Пусть это будут 17:59:00


Внимание вопрос: Считаете ли вы нормальным в 18:00:00 по TimeCurrent() не знать о тике со временем 17:59:00 ?

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

В последнем коде используется не TineCurrent(), а TimeTradeServer() - это мремя нужно лишь для того,

чтобы проверить тик с точностью до ДНЯ и ВСЁ!

Давайте начнем сначала.

Вообще что Вы хотите сделать, узнать?

Для чего Вы стали сравнивать время тика с локальным временем.

Какова изначальная цель?

 

Теперь покажу, как это проблема выглянет на практике. Я полностью переделал советника. Сделал возможность как ловить новые тики в OnTimer так и в OnBookEvent. 

В обзоре рынка 45 символов. Большинство не ликвидные.

Вот результат с ловлей новых тиков в  OnBookEvent:

РЕКОРДная  Разница между временем последенго тика по ВСЕМ символам Минус только, что полученный новый тик по символу 494013 милесекундa.

CR      0       18:51:47.334    ProverkaAktyalnostiTikov (ALRS,H1)       Получен НОВЫЙ тик по символу                     SNGR-3.19 time_msc= 2019.03.18 18:41:47.988

HN      0       18:51:47.335    ProverkaAktyalnostiTikov (ALRS,H1)       ХОТЯ до этого был получeн тик                        ARMD time_msc 2019.03.18 18:50:02.001

Т.е в 18:50 по TimeCurrent был пойман новый тик по символу SNGR-3.19 с временем 18:41.


Дальше идут замеры локального времени компьютера в момент: 


1) получения нового тика т.е в момент последнего вызова  CopyTick (или SymbolInfo в зависимости от настроек )

2) В момент ПРЕДпоследнего вызова.

18:51:47.335    ProverkaAktyalnostiTikov (ALRS,H1)       Локальное время получения нового тика по символу.                      2019.03.18 18:51:47.334

18:51:47.335    ProverkaAktyalnostiTikov (ALRS,H1)       Предпоследние Локальное время попытки получить новый тик по символу    2019.03.18 18:41:47.204


Т.е в данном случае проблема произошла из-за того, функция получения нового просто не вызывалась 10 минут.... А это произошло из-за того, что событие OnBookEvent для символа SNGR-3.19 не генерировалось 10 минут.

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


 
pivomoe:


Какова Ваша изначальная цель?

Для чего Вам нужно сравнивать время тивов с локальным временем?

 
prostotrader:

Какова Ваша изначальная цель?

Для чего Вам нужно сравнивать время тивов с локальным временем?

Хочу знать максимальную задержку между моментом возникновения тика на сервере и временем когда он придет в терминал. И как это время можно минимизировать.

Это знание можно использовать при написании своего тестера. А может даже получиться озадачить разработчиков большими задержками. 

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

 
pivomoe:

Хочу знать максимальную задержку между моментом возникновения тика на сервере и временем когда он придет в терминал. И как это время можно минимизировать.

Это знание можно использовать при написании своего тестера. А может даже получиться озадачить разработчиков большими задержками. 

Понятно. Продолжайте... Без меня.

А для других участников форума

//+------------------------------------------------------------------+
//|                                                         Time.mq5 |
//|                                                   Copyright 2019 |
//|                                                                  |
//+------------------------------------------------------------------+
enum FRESH_TICK
{
  UNKNOWN_TICK,
  NEW_TICK,
  CUR_TICK
};
//
int is_book;
ulong last_tick_time; //Время последнего тика
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  last_tick_time = 0;
  is_book = MarketBookAdd(Symbol());
  if(is_book == false) return(INIT_FAILED);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol()); 
}
//+------------------------------------------------------------------+
// Expert Book event function                                        |
//+------------------------------------------------------------------+  
void OnBookEvent(const string &symbol)
{
  if(symbol == Symbol())
  {
    MqlTick a_ticks[];
    int result = CopyTicks(symbol, a_ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      FRESH_TICK tick_state = CheckTickTime(a_ticks[0]);
      switch(tick_state)
      {
       case UNKNOWN_TICK:; //Тик не определен
       break;
       case NEW_TICK:;     //Торговое время, можно отсылать ордера;
       break;
       case CUR_TICK:;     //По усмотрению разработчика;
       break;
      }
    }  
  }
}
//+------------------------------------------------------------------+
//| Expert Check Market Time function                                |
//+------------------------------------------------------------------+
FRESH_TICK CheckTickTime(MqlTick &a_tick)
{
  MqlDateTime cur_time, tick_time;
  cur_time.year = 0;
  TimeTradeServer(cur_time); //Возвращает расчетное текущее время торгового сервера.
  if(cur_time.year > 0)
  {
    if(TimeToStruct(a_tick.time, tick_time) == true)
    {
      if(tick_time.day_of_year == cur_time.day_of_year)      //Проверка, что это сегодняшний тик
      {
        double t_msc = double(a_tick.time_msc - ulong(a_tick.time) * 1000)/1000;
        double tr_time = double(tick_time.hour * 3600 + tick_time.min * 60 + tick_time.sec) + t_msc;
        if(((tr_time >= 36000) && (tr_time < 50370)) ||   //10:00:00 - 13:59:30
           ((tr_time >= 50700) && (tr_time < 67470)) ||   //14:05:00 - 19:44:30 
           ((tr_time >= 68700) && (tr_time < 85770)))     //19:05:00 - 23:49:30
        {
          if(ulong(a_tick.time_msc) > last_tick_time)
          {
            last_tick_time = ulong(a_tick.time_msc);
            return(NEW_TICK);
          } else return(CUR_TICK);  
        }
      }
    }
  }   
  return(UNKNOWN_TICK);
} 
      
 
pivomoe:

Внимание вопрос: Считаете ли вы нормальным в 18:00:00 по TimeCurrent() не знать о тике со временем 17:59:00 ?

Считаю, что вопрос спорный. Хочется, чтобы тиковая последовательность удовлетворяла как минимум следующим критериям:

1. Была последовательной, т.е. время каждого последующего тика >= времени предыдущего тика;

2. Актуальность. Т.е. время последнего пришедшего тика как можно ближе к текущему моменту;

Похоже, что проблема у Вас именно со вторым пунктом.

Спорность п.2 заключается в следующем: хочется, чтобы время от формирования тика на сервере до получения его мною (лаг) было минимальным, дабы я смог быстрее других его обработать и принять торговое решение. Но! Если лаг одинаков для всех участников торгов - тогда проблем нет (насколько я это понимаю). Т.е. проблема у сервера брокера, но все в равных условиях. Если же кто-то информацию о тике в 17:59:00 получил в 17:59:01, а я не получил даже в 18:00 - вот это уже большая проблема.

И вот тут вопрос. В чем проблема (и есть ли она)? В сервере брокера, который долго не отдает тик (всем), или в МТ5, который долго его не получает.