[СЕРВИСДЕСК] Ошибка получения времени старшего ТФ в таймере! - страница 2

 
Alexey Kozitsyn:

Еще раз. Об этом нигде не сказано. Это во-первых. Во-вторых, зачем она вводит тогда в заблуждение сначала показывая код ошибки 4066, а потом - нет?

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

https://docs.mql4.com/ru/series/timeseries_access внимательно прочитайте.

Ну и выше дали уже вариант проверки доступности истории. Он не идеален но прост и нагляден.

Если этот вариант не работает то проверьте следующим образом.

if(iBarShift(Symbol(),PERIOD_H1,TimeCurrent(),true)==-1){Print("Данные истории по последнему часу отсутствуют!");}
Организация доступа к данным - Доступ к таймсериям и индикаторам - Справочник MQL4
Организация доступа к данным - Доступ к таймсериям и индикаторам - Справочник MQL4
  • docs.mql4.com
Прежде чем ценовые данные будут доступны в терминале MetaTrader 4, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 4. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
 
Vitaly Gorbunov:

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

https://docs.mql4.com/ru/series/timeseries_access внимательно прочитайте.

Ну и выше дали уже вариант проверки доступности истории. Он не идеален но прост и нагляден.

Про попадание "в паузу" где пруфы? 

Внимательно прочитал (и раньше читал). Я в курсе, что данные (тем более старших ТФ) не всегда доступны сразу. Не вопрос. Но почему тогда функция SeriesInfoInteger() возвращает отсутствие ошибки!? Вот в чем вопрос!

Если предположить, что запрос приходится на какую-то паузу/подкачку/обновление/перерыв и т.д. дак пусть вернет код ошибки != 0. И проблем не будет!

 
Vitaly Gorbunov:

Ну и выше дали уже вариант проверки доступности истории. Он не идеален но прост и нагляден.

Ответил уже выше @Ihor Herasko по этому моменту.

 
Alexey Kozitsyn:

Ответил уже выше @Ihor Herasko по этому моменту.

Выше дал свой вариант проверки. Почему так вопрос к разработчикам но этот момент известен очень давно!
 
Vitaly Gorbunov:
Выше дал свой вариант проверки. Почему так вопрос к разработчикам но этот момент известен очень давно!

Я обызательно попробую Ваш вариант проверки и отпишусь о результатах.

 
Alexey Kozitsyn:

Я обызательно попробую Ваш вариант проверки и отпишусь о результатах.

Обязательно отпишитесь! У меня это работает! Но могут быть и всякие подводные камни если не получиться подумем что можно ещё сделать.
 

Сначала ответ @Ihor Herasko. Код для воспроизведения:

#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- Время открытия текущего часа, дня и недели
datetime _m15OpenTime=0;
//--- Вести лог журнала
const bool inpFileLog=true;
//--- Количество секунд в одном дне
const int SEC_PER_DAY=86400;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Запускаем таймер
   if(!EventSetMillisecondTimer(20))
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
      return( INIT_FAILED );
     }
//--- Сбрасываем время открытия текущего бара м15, часа, дня
   _m15OpenTime = 0;
//---
   return( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

   return( rates_total );
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- Проверяем, записано ли время открытия текущего бара М15
   if(!CheckCurrentM15OpenTime())                        // Если время не записано
      return;                                                // Выходим                                                                                                                         // Выходим
  }
//+------------------------------------------------------------------+
//| Проверяем, записано ли время открытия текущего бара М15             |
//+------------------------------------------------------------------+
bool CheckCurrentM15OpenTime()
  {
//--- Проверяем, записано ли время
   if(_m15OpenTime==0) // Если время не записано
     {
      //---
      ResetLastError();
      iTime(NULL,PERIOD_M15,1);
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
      else
         return( false );
     }
//--- Время открытия М15 ранее записано. Возвращаем истину
   return( true );
  }

Результат:

2018.09.21 14:25:02.793 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: removed
2018.09.21 14:30:44.120 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: loaded successfully
2018.09.21 14:30:44.149 test_isNewDayInTimer_iTime() EURGBP.e,M1: initialized
2018.09.21 14:30:44.262 test_isNewDayInTimer_iTime() EURGBP.e,M1: test_isNewDayInTimer_iTime().mq4: Актуальное время открытия бара М15 = 2018.09.21 12:15. Ошибка #0

По записям лога. Терминал был выключен в 14:25. Далее, включен в 14:30. Проверяем время бара М15. Запуск с ТФ М1. Индикатор (код выше) показал актуальное время открытия 12:15 (терминальное время, отстает от моего локального на 2 часа). Должен был получен результат 12:30! Вывод - ошибка присутствует. И данный метод, предложенный @Ihor Herasko не работает.

 
Vitaly Gorbunov:
Обязательно отпишитесь! У меня это работает! Но могут быть и всякие подводные камни если не получиться подумем что можно ещё сделать.

Отписываюсь. Код:

#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- Время открытия текущего часа, дня и недели
datetime _m15OpenTime=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Запускаем таймер
   if(!EventSetMillisecondTimer(20))
     {
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
      return( INIT_FAILED );
     }
//--- Сбрасываем время открытия текущего бара м15
   _m15OpenTime=0;
//---
   return( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

   return( rates_total );
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- Проверяем, записано ли время открытия текущего бара М15
   if(!CheckCurrentM15OpenTime())                        // Если время не записано
      return;                                                // Выходим
  }
//+------------------------------------------------------------------+
//| Проверяем, записано ли время открытия текущего бара М15             |
//+------------------------------------------------------------------+
bool CheckCurrentM15OpenTime()
  {
//--- Проверяем, записано ли время
   if(_m15OpenTime==0) // Если время не записано
     {
      //---
      ResetLastError();
      if(iBarShift(Symbol(),PERIOD_M15,TimeCurrent(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
      else
         return( false );
     }
//--- Время открытия недели ранее записано. Возвращаем истину
   return( true );
  }
//+------------------------------------------------------------------+

Результат:

2018.09.21 14:48:46.485 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: removed
2018.09.21 15:01:23.158 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: loaded successfully
2018.09.21 15:01:23.175 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: initialized
2018.09.21 15:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.21 12:45. Ошибка #0

Выключил терминал в 14:48, включил в 15:01. Должен был получить время 13:00. Получил - 12.45. Еще вопросы?

Меняю ТФ с М1 на М5, получаю корректный результат:

2018.09.21 15:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.21 12:45. Ошибка #0
2018.09.21 15:05:50.057 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: uninit reason 3
2018.09.21 15:05:50.058 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: initialized
2018.09.21 15:05:50.094 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.21 13:00. Ошибка #0
 
Еще раз прошу разработчиков (@Slava, @Alexander, @Renat Fatkhullin) обратить внимание на данную проблему.
 

А вроде я понял! Индюк запускается сразу вместе с терминалом? Если да то перед проверкой дождитесь что есть связь с сервером IsConnected() у вас очень быстрый таймер он не успевает синхронизироваться!

Или сделай вот так

if(iBarShift(Symbol(),PERIOD_M15,TimeLocal(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
Но придётся учитывать разницу между Серверным временем и локальным. Отпишись по результатам!