Еще раз. Об этом нигде не сказано. Это во-первых. Во-вторых, зачем она вводит тогда в заблуждение сначала показывая код ошибки 4066, а потом - нет?
Данные подкачиваются порциями, а потом ещё и обрабатываются терминалом, а так как вы работаете по таймеру вы и попадаете в паузу. Да об этом явно ни где не говориться но многие программисты пишущие МТФ приложения обычно об этом знают я об этом сразу и сказал.
Прежде чем ценовые данные будут доступны в терминале MetaTrader 4, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 4. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
Данные подкачиваются порциями, а потом ещё и обрабатываются терминалом, а так как вы работаете по таймеру вы и попадаете в паузу. Да об этом явно ни где не говориться но многие программисты пишущие МТФ приложения обычно об этом знают я об этом сразу и сказал.
Ну и выше дали уже вариант проверки доступности истории. Он не идеален но прост и нагляден.
Про попадание "в паузу" где пруфы?
Внимательно прочитал (и раньше читал). Я в курсе, что данные (тем более старших ТФ) не всегда доступны сразу. Не вопрос. Но почему тогда функция SeriesInfoInteger() возвращает отсутствие ошибки!? Вот в чем вопрос!
Если предположить, что запрос приходится на какую-то паузу/подкачку/обновление/перерыв и т.д. дак пусть вернет код ошибки != 0. И проблем не будет!
Сначала ответ @Ihor Herasko. Код для воспроизведения:
#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 );
}
Результат:
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
По записям лога. Терминал был выключен в 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 |//+------------------------------------------------------------------+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 );
}
//+------------------------------------------------------------------+
Результат:
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
Выключил терминал в 14:48, включил в 15:01. Должен был получить время 13:00. Получил - 12.45. Еще вопросы?
Меняю ТФ с М1 на М5, получаю корректный результат:
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
А вроде я понял! Индюк запускается сразу вместе с терминалом? Если да то перед проверкой дождитесь что есть связь с сервером IsConnected() у вас очень быстрый таймер он не успевает синхронизироваться!
Или сделай вот так
if(iBarShift(Symbol(),PERIOD_M15,TimeLocal(),true)==-1)
{
Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
return( false );
}
Но придётся учитывать разницу между Серверным временем и локальным. Отпишись по результатам!
Еще раз. Об этом нигде не сказано. Это во-первых. Во-вторых, зачем она вводит тогда в заблуждение сначала показывая код ошибки 4066, а потом - нет?
Данные подкачиваются порциями, а потом ещё и обрабатываются терминалом, а так как вы работаете по таймеру вы и попадаете в паузу. Да об этом явно ни где не говориться но многие программисты пишущие МТФ приложения обычно об этом знают я об этом сразу и сказал.
https://docs.mql4.com/ru/series/timeseries_access внимательно прочитайте.
Ну и выше дали уже вариант проверки доступности истории. Он не идеален но прост и нагляден.
Если этот вариант не работает то проверьте следующим образом.
Данные подкачиваются порциями, а потом ещё и обрабатываются терминалом, а так как вы работаете по таймеру вы и попадаете в паузу. Да об этом явно ни где не говориться но многие программисты пишущие МТФ приложения обычно об этом знают я об этом сразу и сказал.
https://docs.mql4.com/ru/series/timeseries_access внимательно прочитайте.
Ну и выше дали уже вариант проверки доступности истории. Он не идеален но прост и нагляден.
Про попадание "в паузу" где пруфы?
Внимательно прочитал (и раньше читал). Я в курсе, что данные (тем более старших ТФ) не всегда доступны сразу. Не вопрос. Но почему тогда функция SeriesInfoInteger() возвращает отсутствие ошибки!? Вот в чем вопрос!
Если предположить, что запрос приходится на какую-то паузу/подкачку/обновление/перерыв и т.д. дак пусть вернет код ошибки != 0. И проблем не будет!
Ну и выше дали уже вариант проверки доступности истории. Он не идеален но прост и нагляден.
Ответил уже выше @Ihor Herasko по этому моменту.
Ответил уже выше @Ihor Herasko по этому моменту.
Выше дал свой вариант проверки. Почему так вопрос к разработчикам но этот момент известен очень давно!
Я обызательно попробую Ваш вариант проверки и отпишусь о результатах.
Я обызательно попробую Ваш вариант проверки и отпишусь о результатах.
Сначала ответ @Ihor Herasko. Код для воспроизведения:
Результат:
По записям лога. Терминал был выключен в 14:25. Далее, включен в 14:30. Проверяем время бара М15. Запуск с ТФ М1. Индикатор (код выше) показал актуальное время открытия 12:15 (терминальное время, отстает от моего локального на 2 часа). Должен был получен результат 12:30! Вывод - ошибка присутствует. И данный метод, предложенный @Ihor Herasko не работает.
Обязательно отпишитесь! У меня это работает! Но могут быть и всякие подводные камни если не получиться подумем что можно ещё сделать.
Отписываюсь. Код:
Результат:
Выключил терминал в 14:48, включил в 15:01. Должен был получить время 13:00. Получил - 12.45. Еще вопросы?
Меняю ТФ с М1 на М5, получаю корректный результат:
А вроде я понял! Индюк запускается сразу вместе с терминалом? Если да то перед проверкой дождитесь что есть связь с сервером IsConnected() у вас очень быстрый таймер он не успевает синхронизироваться!
Или сделай вот так
Но придётся учитывать разницу между Серверным временем и локальным. Отпишись по результатам!