[SERVICE DESK] ¡Error al obtener la hora de la TF superior en el temporizador! - página 2

 
Alexey Kozitsyn:

Una vez más. No lo dice en ningún sitio. Eso es lo primero. En segundo lugar, ¿por qué entonces es engañoso al mostrar primero un código de error 4066 y luego no?

Los datos se bombean por lotes y luego son procesados por el terminal, y como estás trabajando en un temporizador, estás en pausa. No lo veo explícitamente en ningún sitio, pero muchos programadores que escriben aplicaciones MTF suelen conocerlo y te lo he contado enseguida.

https://docs.mql4.com/ru/series/timeseries_access lo leyó detenidamente.

Bueno, arriba ya nos dio una variante de comprobar la accesibilidad del historial. No es perfecto, pero es sencillo y evidente.

Si esta variante no funciona, compruebe lo siguiente.

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

Los datos se bombean en porciones y luego son procesados por el terminal, y como estás en un temporizador, te pones en pausa. Sí, no se menciona explícitamente en ningún sitio, pero muchos programadores que escriben aplicaciones MTF suelen conocerlo y se lo dije enseguida.

https://docs.mql4.com/ru/series/timeseries_access lo leyó detenidamente.

Bueno, arriba ya nos has dado una variante de comprobar la accesibilidad del historial. No es perfecto, pero es sencillo y evidente.

Sobre lo de "entrar en pausa", ¿dónde están las pruebas?

Lo he leído con atención (y lo he leído antes). Soy consciente de que los datos (especialmente los TF más antiguos) no siempre están disponibles de forma inmediata. No hay problema. ¿Pero por qué entonces la función SeriesInfoInteger() no devuelve ningún error? ¡Aquí está la pregunta!

Suponiendo que la solicitud cae en alguna pausa/intercambio/actualización/interrupción, etc., entonces que devuelva el código de error != 0. Y no habrá ningún problema.

 
Vitaly Gorbunov:

Y arriba ya has dado la opción de comprobar la accesibilidad de la historia. No es perfecto, pero es simple y sencillo.

Respondido arriba @Ihor Herasko sobre este punto.

 
Alexey Kozitsyn:

Ya he respondido a @Ihor Herasko sobre este punto.

Arriba dio su versión de la prueba. Por qué tanta pregunta a los desarrolladores, pero este punto se conoce desde hace mucho tiempo.
 
Vitaly Gorbunov:
He dado mi versión de la prueba anterior. Por qué tanta pregunta a los desarrolladores, pero este punto se conoce desde hace mucho tiempo.

Sin duda, probaré su versión de la prueba e informaré de los resultados.

 
Alexey Kozitsyn:

Sin duda, probaré su versión de la prueba e informaré de los resultados.

Sin duda alguna, le informaré de ello. A mí me funciona. Pero puede haber todo tipo de trampas si no funciona y pensaremos qué más podemos hacer.
 

Primero una respuesta de @Ihor Herasko. Código para la reproducción:

#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 );
  }

Resultado:

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

Según las entradas del registro. La terminal se apagó a las 14:25. A continuación, se encendió a las 14:30. Comprobamos la hora del bar M15. Empezamos con la TF M1. El indicador (código anterior) mostraba la hora real de apertura 12:15 (hora de la terminal, retrasada respecto a mi hora local en 2 horas). ¡El resultado debería haber sido 12:30! Conclusión: el error está presente. Y este método sugerido por @Ihor Herasko no funciona.

 
Vitaly Gorbunov:
Asegúrese de informar al respecto. A mí me funciona. Pero puede haber todo tipo de trampas si no funciona, pensemos qué más podemos hacer.

Me despido. Código:

#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 );
  }
//+------------------------------------------------------------------+

Resultado:

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

Apagó el terminal a las 14:48 y lo volvió a encender a las 15:01. Debería haber recibido la hora a la 1:00 p.m. Tengo las 12:45. ¿Alguna otra pregunta?

Cambié el TF de M1 a M5 y obtuve un resultado correcto:

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
 
Una vez más pido a los desarrolladores(@Slava, @Alexander, @Renat Fatkhullin) que presten atención a este problema.
 

¡Creo que lo tengo! ¿Se pone en marcha el indicador inmediatamente con el terminal? ¡Si es así, antes de comprobar esperar una conexión con el servidor IsConnected() tiene un temporizador muy rápido no tiene tiempo para sincronizar!

O haz esto

if(iBarShift(Symbol(),PERIOD_M15,TimeLocal(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
Pero hay que tener en cuenta la diferencia entre la hora del servidor y la hora local. Escriba de nuevo con los resultados.