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.
Прежде чем ценовые данные будут доступны в терминале MetaTrader 4, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 4. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
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.
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: 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.
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;
//--- Вести лог журналаconstbool inpFileLog=true;
//--- Количество секунд в одном днеconstint SEC_PER_DAY=86400;
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- Запускаем таймерif(!EventSetMillisecondTimer(20))
{
Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
return( INIT_FAILED );
}
//--- Сбрасываем время открытия текущего бара м15, часа, дня
_m15OpenTime = 0;
//---return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
return( rates_total );
}
//+------------------------------------------------------------------+//| Timer function |//+------------------------------------------------------------------+voidOnTimer()
{
//--- Проверяем, записано ли время открытия текущего бара М15if(!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 );
}
elsereturn( false );
}
//--- Время открытия М15 ранее записано. Возвращаем истинуreturn( true );
}
Resultado:
2018.09.2114:25:02.793 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: removed
2018.09.2114:30:44.120 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: loaded successfully
2018.09.2114:30:44.149 test_isNewDayInTimer_iTime() EURGBP.e,M1: initialized
2018.09.2114:30:44.262 test_isNewDayInTimer_iTime() EURGBP.e,M1: test_isNewDayInTimer_iTime().mq4: Актуальное время открытия бара М15 = 2018.09.2112: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 |//+------------------------------------------------------------------+intOnInit()
{
//--- Запускаем таймерif(!EventSetMillisecondTimer(20))
{
Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
return( INIT_FAILED );
}
//--- Сбрасываем время открытия текущего бара м15
_m15OpenTime=0;
//---return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
return( rates_total );
}
//+------------------------------------------------------------------+//| Timer function |//+------------------------------------------------------------------+voidOnTimer()
{
//--- Проверяем, записано ли время открытия текущего бара М15if(!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 );
}
elsereturn( false );
}
//--- Время открытия недели ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+
Resultado:
2018.09.2114:48:46.485 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: removed
2018.09.2115:01:23.158 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: loaded successfully
2018.09.2115:01:23.175 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: initialized
2018.09.2115:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.2112: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.2115:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.2112:45. Ошибка #02018.09.2115:05:50.057 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: uninit reason 32018.09.2115:05:50.058 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: initialized
2018.09.2115:05:50.094 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.2113:00. Ошибка #0
¡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.
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.
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.
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.
Ya he respondido a @Ihor Herasko sobre este punto.
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.
Sin duda, probaré su versión de la prueba e informaré de los resultados.
Primero una respuesta de @Ihor Herasko. Código para la reproducción:
Resultado:
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.
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:
Resultado:
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:
¡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
Pero hay que tener en cuenta la diferencia entre la hora del servidor y la hora local. Escriba de nuevo con los resultados.