У вас индикатор не отслеживает обновление данных. От брокера приходят новые бары, а вы их не проверяете. Я добавил пару строк чтобы показать, что при проверке всё отображается верно.
Это рабочая ситуация - проверять новый бар.
Да Вы что! А с чего Вы взяли, что я обязательно должен отслеживать новые бары? Это в документации написано? В смысле, я ДОЛЖЕН получить значение функции, а потом обязательно сравнивать его с предыдущим? Есть функция, функция рассчитана на работу со старшими таймфреймами. Функция может возвращать ошибку, когда у нее нет данных или возвращать некорректное значение (равное 0 в данном случае). Все. Не должны программисты что-то городить для того, чтобы 100% получить корректное значение.
Зато смотрите, что я нашел в документации к SeriesInfoInteger():
Чтобы получить дополнительную информацию об ошибке, необходимо вызвать функцию GetLastError().
В моем коде GetLastError() видите? Вот проверка. Эта проверка должна быть необходимой и ДОСТАТОЧНОЙ! Все остальное - костыльные решения.
А Вы посмотрите мой самый первый пост. Видите там ошибку 4066? Потом ошибку 0 и возврат некорректных данных. Почему же функция (в данном случае SeriesInfoInteger()) предварительно перед отправкой данных не делает проверку на актуальность? Почему она не взводит флаг ошибки? Понимаете, лучше подождать чуть дольше, пока проходят внутренние проверки, чем потом искать ошибки.
Зато после этого, мне было дано много советов, используя которые результат так и не был получен. А дело оказалось даже не в таймере.
ок, читаем справку)
SeriesInfoInteger
Возвращает информацию о состоянии исторических данных.
Слово исторических что означает? Если История загружена - ошибки нет.
Alexey Kozitsyn:
Да Вы что! А с чего Вы взяли, что я обязательно должен отслеживать новые бары? Это в документации написано? В смысле, я ДОЛЖЕН получить значение функции, а потом обязательно сравнивать его с предыдущим? Есть функция, функция рассчитана на работу со старшими таймфреймами. Функция может возвращать ошибку, когда у нее нет данных или возвращать некорректное значение (равное 0 в данном случае). Все. Не должны программисты что-то городить для того, чтобы 100% получить корректное значение.
Зато смотрите, что я нашел в документации к SeriesInfoInteger():
В моем коде GetLastError() видите? Вот проверка. Эта проверка должна быть необходимой и ДОСТАТОЧНОЙ! Все остальное - костыльные решения.
Вы ничего не должны) ...брокер вам присылает обновленные данные - если хотите, используйте их для расчета, если нет - какие проблемы, считайте по уже имеющейся Истории)
пс. сейчас выходные, рынок закрыт, у вас в терминале некорректные данные! и нет ошибки!!!)
Слово исторических что означает? Если История загружена - ошибки нет.
Вы ничего не должны) ...брокер вам присылает обновленные данные - если хотите используйте их для расчета, если нет - какие проблемы, считайте по Истории)
Каждый тик, пришедший в терминал - уже история. И я хочу получать актуальные ее значения или ошибку. Если Вас все устраивает - ок.
Каждый тик, пришедший в терминал - уже история. И я хочу получать актуальные ее значения или ошибку. Если Вас все устраивает - ок.
Да, история это то что уже загрузилось, или то что грузится в прошлое. А то, что только сейчас обновляется (после последней котировки) - это еще не история, это новые необработанные данные.
Проверяйте не расчет баров, а время свечи. Вот так будет правильно обновляться (проверил).
Тарас, вот результат Вашего кода:
2018.10.0811:11:39.080 test_isNewDayInOnCalculate GBPUSD,M1: initialized
2018.10.0811:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Время открытия недельного бара = 2018.09.3000:00. Ошибка #02018.10.0811:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущей недели = 2018.10.0100:00. Ошибка #02018.10.0811:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Время открытия текущего дня = 2018.10.0500:00. Ошибка #02018.10.0811:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущего дня = 2018.10.0500:00. Ошибка #02018.10.0811:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Время открытия текущего часа = 2018.10.0523:00. Ошибка #02018.10.0811:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущего часа = 2018.10.0523:00. Ошибка #02018.10.0811:11:39.788 test_isNewDayInOnCalculate GBPUSD,M1: OnCalculate: Данные старших ТФ загружены!
Да, это первый тик, тот который выдает готовую историю, та которая есть в наличии. После этого тика (если есть новые бары), сразу приходит второй тик, в котором мой код обновляет ваши переменные и они показывают правильные данные.
пс. можете вставить свою функцию проверки нового бара, будет тоже самое.
ппс. я, у себя, постоянно проверяю количество баров, если число изменилось больше чем на 1, значит нужно пересчитать всё заново, если число изменилось на 1 - значит просто новый бар. А ошибки проверяю только самые критические, и не вижу этой задержки-ошибки.
Да, это первый тик, тот который выдает готовую историю, та которая есть в наличии. После этого тика (если есть новые бары), сразу приходит второй тик, в котором мой код обновляет ваши переменные и они показывают правильные данные.
пс. можете вставить свою функцию проверки нового бара, будет тоже самое.
ппс. я, у себя, постоянно проверяю количество баров, если число изменилось больше чем на 1, значит нужно пересчитать всё заново, если число изменилось на 1 - значит просто новый бар. А ошибки проверяю только самые критические, и не вижу этой задержки-ошибки.
А вот, кстати, еще аргумент, в пользу того, что происходит ошибка. Именно ОШИБКА при расчете в индикаторе! Написал советник:
#property version"1.00"#property strict//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+//--- Время открытия текущего часа, дня и неделиdatetime _weekOpenTime = 0;
datetime _hourOpenTime = 0;
datetime _dayOpenTime=0;
//--- Вести лог журналаconstbool inpFileLog=true;
//--- Количество секунд в одном днеconstint SEC_PER_DAY=86400;
//--- Флаг работоспособности индикатораbool _isWorking=true;
//--- Флаг соединения с торговым сервером (для таймера, получаем в OnCalculate())bool _isConnected=false;
//---bool _firstLaunch = true;
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- Устанавливаем флаг первого запуска
_firstLaunch = true;
//--- Сбрасываем время открытия текущего часа, дня и недели
_weekOpenTime= 0;
_dayOpenTime = 0;
_hourOpenTime= 0;
//--- Устанавливаем флаг работоспособности
_isWorking=true;
//--- Сбрасываем флаг установки соединения
_isConnected=false;
////--- Запускаем таймер// if(!EventSetMillisecondTimer(20))// {// Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 не установлен!");// //--- Устанавливаем флаг неработоспособности индикатора// _isWorking=false;// }//--- Запрос данныхSeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
//---return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
////--- Выключаем таймер// EventKillTimer();
}
////+------------------------------------------------------------------+////| |////+------------------------------------------------------------------+//void OnTimer()// {////---// if(!_isWorking)// return;////---// if(!_isConnected)// return;////---// Print(__FUNCTION__,": Данные старших ТФ загружены!");////--- Отключаем таймер// EventKillTimer();// }//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnTick()
{
//--- Проверяем связь с серверомif(!IsConnected()) // Если не удалось установить связь с сервером
{
//--- Сбрасываем флаг соединения с сервером
_isConnected=false;
//--- Выходимreturn;
}
//--- Проверяем первый запуск экспертаif( _firstLaunch )
{
//--- Проверяем, записано ли время открытия текущей неделиif(!CheckCurrentWeekOpenTime()) // Если время не записаноreturn; // Выходим//--- Проверяем, записано ли время открытия текущего дняif(!CheckCurrentDayOpenTime()) // Если время не записаноreturn; // Выходим//--- Проверяем, записано ли время открытия текущего часаif(!CheckCurrentHourOpenTime()) // Если время не записаноreturn; // Выходим////--- Устанавливаем флаг соединения с сервером для запуска таймера//_isConnected=true;//---Print(__FUNCTION__,": Данные старших ТФ загружены!");
//--- Сбрасываем флаг первого запуска
_firstLaunch = false;
}
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущей недели |//+------------------------------------------------------------------+bool CheckCurrentWeekOpenTime()
{
//--- Проверяем, записано ли времяif(_weekOpenTime==0) // Если время не записано
{
//--- Получаем время открытия недельного бараResetLastError();
constdatetime weekBarOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия недельного бара = "+TimeToString(weekBarOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия недельного бараif(weekBarOpenTime==0 || err!=0) // Если время бара не получено или история обновляетсяreturn(false); // Возвращаем ложь//--- Запоминаем время открытия текущей недели (время открытия недельного бара - воскресенье)
_weekOpenTime=weekBarOpenTime+SEC_PER_DAY;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущей недели = "+TimeToString(_weekOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия недели ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего дня |//+------------------------------------------------------------------+bool CheckCurrentDayOpenTime()
{
//--- Проверяем, записано ли времяif(_dayOpenTime==0) // Если время не записано
{
//--- Получаем время открытия дневного бараResetLastError();
constdatetime tempDayOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия текущего дня = "+TimeToString(tempDayOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия дневного бараif(tempDayOpenTime==0 || err!=0) // Если время бара не полученоreturn(false); // Возвращаем ложь//--- Сохраняем в глобальную переменную значение открытия текущего дня
_dayOpenTime=tempDayOpenTime;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущего дня = "+TimeToString(_dayOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия дня ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего часа |//+------------------------------------------------------------------+bool CheckCurrentHourOpenTime()
{
//--- Проверяем, записано ли времяif(_hourOpenTime==0) // Если время не записано
{
//--- Получаем время открытия часового бараResetLastError();
constdatetime tempHourOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия текущего часа = "+TimeToString(tempHourOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия часового бараif(tempHourOpenTime==0 || err!=0) // Если время бара не полученоreturn(false); // Возвращаем ложь//---
_hourOpenTime=tempHourOpenTime;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущего часа = "+TimeToString(_hourOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия часа ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+
Запускается с того же графика, что и индикатор. Посмотрим результаты:
2018.10.0908:45:42.627 test_isNewDayInOnTick GBPUSD,M1: OnTick: Данные старших ТФ загружены!
2018.10.0908:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Актуальное время открытия текущего часа = 2018.10.0906:00. Ошибка #02018.10.0908:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Время открытия текущего часа = 2018.10.0906:00. Ошибка #02018.10.0908:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Актуальное время открытия текущего дня = 2018.10.0900:00. Ошибка #02018.10.0908:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Время открытия текущего дня = 2018.10.0900:00. Ошибка #02018.10.0908:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Актуальное время открытия текущей недели = 2018.10.0800:00. Ошибка #02018.10.0908:45:42.627 test_isNewDayInOnTick GBPUSD,M1: test_isNewDayInOnTick.mq4: Время открытия недельного бара = 2018.10.0700:00. Ошибка #02018.10.0908:45:41.479 test_isNewDayInOnTick GBPUSD,M1: initialized
2018.10.09 08:45:40.822 GBPUSD,M1: CheckCurrentHourOpenTime: Время открытия текущего часа = 2018.10.08 11:00
2018.10.09 08:45:40.822 GBPUSD,M1: CheckCurrentDayOpenTime: Время открытия текущего дня = 2018.10.08 00:00
2018.10.09 08:45:40.822 GBPUSD,M1: CheckCurrentWeekOpenTime: Время открытия текущей недели = 2018.10.08 00:00
2018.10.09 08:45:40.064 GBPUSD,M1: initialized
2018.10.0908:45:40.022 Expert Other\test_isNewDayInOnTick GBPUSD,M1: loaded successfully
Что же мы видим. Видим, что все хорошо. Все прогрузилось, и заметьте, никаких ошибок, сразу актуальные данные! Главный ВОПРОС: дак почему в эксперте данные старших ТФ можно получить нормально, а в индикаторе нужно "плясать с бубном"? Разве не должны программы работать одинаково? Почему один и тот же код в индикаторе и эксперте работает по разному?! Не должно такого быть.
А вот, кстати, еще аргумент, в пользу того, что происходит ошибка. Именно ОШИБКА при расчете в индикаторе! Написал советник:
Запускается с того же графика, что и индикатор. Посмотрим результаты:
Что же мы видим. Видим, что все хорошо. Все прогрузилось, и заметьте, никаких ошибок, сразу актуальные данные! Главный ВОПРОС: дак почему в эксперте данные старших ТФ можно получить нормально, а в индикаторе нужно "плясать с бубном"? Разве не должны программы работать одинаково? Почему один и тот же код в индикаторе и эксперте работает по разному?! Не должно такого быть.
Потому что это дело терминала соединяться и что то там делать с подгрузкой проверкой и т.д., все индикаторы находятся в одном потоке, и покуда все в потоке не закончится (фактически до следующего вызова OnСalculate) ничего нового не произойдет, т.е. находясь в этом потоке, быстрее окончания потока, вы все равно ничего не получите. Эксперт находится в своем отдельном потоке, поэтому когда он запускается, ему позволено отложить свой запуск на время обновлений данных, обновлять данные - на все остальное в терминале это не влияет. Это с рождения так и никак уже не исправить, т.к. среду metatrader4 похоронили.
Потому что это дело терминала соединяться и что то там делать с подгрузкой проверкой и т.д., все индикаторы находятся в одном потоке, и покуда все в потоке не закончится (фактически до следующего вызова OnСalculate) ничего нового не произойдет, т.е. находясь в этом потоке, быстрее окончания потока, вы все равно ничего не получите. Эксперт находится в своем отдельном потоке, поэтому когда он запускается, ему позволено отложить свой запуск на время обновлений данных, обновлять данные - на все остальное в терминале это не влияет. Это с рождения так и никак уже не исправить, т.к. среду metatrader4 похоронили.
Да я в курсе, что все индикаторы одного символа находятся в одном потоке, а на каждый эксперт выделяется свой поток. Но это не дело. Разработчики - они на то и разработчики, чтобы исправлять ошибки в своих творениях. Программы не должны по разному работать! Если индикаторы что-то не успели - ошибка и нет проблем. Ведь эксперт как-то сразу получил корректные данные без ошибок! Значит можно реализовать. @Slava, можете высказаться по поводу, будет ли исправлено явно ошибочное поведение? Или, хотя бы, дополнение документации (что при prev_calculated = 0 корректных данных старших ТФ не получить)?
Да я в курсе, что все индикаторы одного символа находятся в одном потоке, а на каждый эксперт выделяется свой поток. Но это не дело. Разработчики - они на то и разработчики, чтобы исправлять ошибки в своих творениях. Программы не должны по разному работать! Если индикаторы что-то не успели - ошибка и нет проблем. Ведь эксперт как-то сразу получил корректные данные без ошибок! Значит можно реализовать. @Slava, можете высказаться по поводу, будет ли исправлено явно ошибочное поведение? Или, хотя бы, дополнение документации (что при prev_calculated = 0 корректных данных старших ТФ не получить)?
В документации где то было что эксперту дается целых 5 секунд перед запуском чтобы получить данные, а в это время терминал пытается выкачать данные для эксперта. Индикатору это не дано, так же индикатору не положено запрашивать обновление истории, для него это не критично, если критично - значит считайте в эксперте. Главная мысль, что в текущей реализации не возможно желаемое положение вещей. По существу, ТФ-ы это таймеры и есть периоды где эти кратные таймеры совпадают в один момент - это 100% совпадающий по времени синхронный процесс(кроме времени открытия/закрытия), т.к. первый тик минуты текущего тф совпадающей с первой минутой пятиминутки, часа и т.д. - это просто запись в несколько переменных одного и того же значения , и логично что в этих моментах можно задать набор нужных ТФ и получать все необходимые данные сразу. Почему разработчики сделали так, а не иначе, хз, возможно из-за разделения клиент-сервер это невозможно было(будет) сделать в существующей модели работы терминала, т.к. если сейчас дать возможность индикаторам возможности экспертов, то они завесят терминал.
Можно посмотреть в конце дня, кому интересно, как работает вызов индикатора, индикатор вызывает другой индикатор, эксперт(_asktfexp) вызывает индикатор(_asktf_sample) вызывающий индикатор(_asktf). При вызове индикатора из эксперта, таймер в индикаторе не запустится, поэтому решения с таймером в индикаторе это только для случаев, когда этот индикатор только будет висеть на графике и не будет вызываться (что в общем логично).
У вас индикатор не отслеживает обновление данных.
От брокера приходят новые бары, а вы их не проверяете.
Я добавил пару строк чтобы показать, что при проверке всё отображается верно.
Это рабочая ситуация - проверять новый бар.
Да Вы что! А с чего Вы взяли, что я обязательно должен отслеживать новые бары? Это в документации написано? В смысле, я ДОЛЖЕН получить значение функции, а потом обязательно сравнивать его с предыдущим? Есть функция, функция рассчитана на работу со старшими таймфреймами. Функция может возвращать ошибку, когда у нее нет данных или возвращать некорректное значение (равное 0 в данном случае). Все. Не должны программисты что-то городить для того, чтобы 100% получить корректное значение.
Зато смотрите, что я нашел в документации к SeriesInfoInteger():
Чтобы получить дополнительную информацию об ошибке, необходимо вызвать функцию GetLastError().
А Вы посмотрите мой самый первый пост. Видите там ошибку 4066? Потом ошибку 0 и возврат некорректных данных. Почему же функция (в данном случае SeriesInfoInteger()) предварительно перед отправкой данных не делает проверку на актуальность? Почему она не взводит флаг ошибки? Понимаете, лучше подождать чуть дольше, пока проходят внутренние проверки, чем потом искать ошибки.
Зато после этого, мне было дано много советов, используя которые результат так и не был получен. А дело оказалось даже не в таймере.
ок, читаем справку)
SeriesInfoInteger
Возвращает информацию о состоянии исторических данных.
Слово исторических что означает?
Если История загружена - ошибки нет.
Да Вы что! А с чего Вы взяли, что я обязательно должен отслеживать новые бары? Это в документации написано? В смысле, я ДОЛЖЕН получить значение функции, а потом обязательно сравнивать его с предыдущим? Есть функция, функция рассчитана на работу со старшими таймфреймами. Функция может возвращать ошибку, когда у нее нет данных или возвращать некорректное значение (равное 0 в данном случае). Все. Не должны программисты что-то городить для того, чтобы 100% получить корректное значение.
Зато смотрите, что я нашел в документации к SeriesInfoInteger():
В моем коде GetLastError() видите? Вот проверка. Эта проверка должна быть необходимой и ДОСТАТОЧНОЙ! Все остальное - костыльные решения.Вы ничего не должны)
...брокер вам присылает обновленные данные - если хотите, используйте их для расчета, если нет - какие проблемы, считайте по уже имеющейся Истории)
пс. сейчас выходные, рынок закрыт, у вас в терминале некорректные данные!
и нет ошибки!!!)
ок, читаем справку)
Слово исторических что означает?
Если История загружена - ошибки нет.
Вы ничего не должны)
...брокер вам присылает обновленные данные - если хотите используйте их для расчета, если нет - какие проблемы, считайте по Истории)
Каждый тик, пришедший в терминал - уже история. И я хочу получать актуальные ее значения или ошибку. Если Вас все устраивает - ок.
Каждый тик, пришедший в терминал - уже история. И я хочу получать актуальные ее значения или ошибку. Если Вас все устраивает - ок.
Да, история это то что уже загрузилось, или то что грузится в прошлое.
А то, что только сейчас обновляется (после последней котировки) - это еще не история, это новые необработанные данные.
Проверяйте не расчет баров, а время свечи.
Вот так будет правильно обновляться (проверил).
Тарас, вот результат Вашего кода:
Тарас, вот результат Вашего кода:
Да, это первый тик, тот который выдает готовую историю, та которая есть в наличии.
После этого тика (если есть новые бары), сразу приходит второй тик, в котором мой код обновляет ваши переменные и они показывают правильные данные.
пс. можете вставить свою функцию проверки нового бара, будет тоже самое.
ппс. я, у себя, постоянно проверяю количество баров, если число изменилось больше чем на 1, значит нужно пересчитать всё заново, если число изменилось на 1 - значит просто новый бар. А ошибки проверяю только самые критические, и не вижу этой задержки-ошибки.
Да, это первый тик, тот который выдает готовую историю, та которая есть в наличии.
После этого тика (если есть новые бары), сразу приходит второй тик, в котором мой код обновляет ваши переменные и они показывают правильные данные.
пс. можете вставить свою функцию проверки нового бара, будет тоже самое.
ппс. я, у себя, постоянно проверяю количество баров, если число изменилось больше чем на 1, значит нужно пересчитать всё заново, если число изменилось на 1 - значит просто новый бар. А ошибки проверяю только самые критические, и не вижу этой задержки-ошибки.
А вот, кстати, еще аргумент, в пользу того, что происходит ошибка. Именно ОШИБКА при расчете в индикаторе! Написал советник:
Запускается с того же графика, что и индикатор. Посмотрим результаты:
Что же мы видим. Видим, что все хорошо. Все прогрузилось, и заметьте, никаких ошибок, сразу актуальные данные! Главный ВОПРОС: дак почему в эксперте данные старших ТФ можно получить нормально, а в индикаторе нужно "плясать с бубном"? Разве не должны программы работать одинаково? Почему один и тот же код в индикаторе и эксперте работает по разному?! Не должно такого быть.
А вот, кстати, еще аргумент, в пользу того, что происходит ошибка. Именно ОШИБКА при расчете в индикаторе! Написал советник:
Запускается с того же графика, что и индикатор. Посмотрим результаты:
Что же мы видим. Видим, что все хорошо. Все прогрузилось, и заметьте, никаких ошибок, сразу актуальные данные! Главный ВОПРОС: дак почему в эксперте данные старших ТФ можно получить нормально, а в индикаторе нужно "плясать с бубном"? Разве не должны программы работать одинаково? Почему один и тот же код в индикаторе и эксперте работает по разному?! Не должно такого быть.
Потому что это дело терминала соединяться и что то там делать с подгрузкой проверкой и т.д., все индикаторы находятся в одном потоке, и покуда все в потоке не закончится (фактически до следующего вызова OnСalculate) ничего нового не произойдет, т.е. находясь в этом потоке, быстрее окончания потока, вы все равно ничего не получите. Эксперт находится в своем отдельном потоке, поэтому когда он запускается, ему позволено отложить свой запуск на время обновлений данных, обновлять данные - на все остальное в терминале это не влияет. Это с рождения так и никак уже не исправить, т.к. среду metatrader4 похоронили.
Потому что это дело терминала соединяться и что то там делать с подгрузкой проверкой и т.д., все индикаторы находятся в одном потоке, и покуда все в потоке не закончится (фактически до следующего вызова OnСalculate) ничего нового не произойдет, т.е. находясь в этом потоке, быстрее окончания потока, вы все равно ничего не получите. Эксперт находится в своем отдельном потоке, поэтому когда он запускается, ему позволено отложить свой запуск на время обновлений данных, обновлять данные - на все остальное в терминале это не влияет. Это с рождения так и никак уже не исправить, т.к. среду metatrader4 похоронили.
Да я в курсе, что все индикаторы одного символа находятся в одном потоке, а на каждый эксперт выделяется свой поток. Но это не дело. Разработчики - они на то и разработчики, чтобы исправлять ошибки в своих творениях. Программы не должны по разному работать! Если индикаторы что-то не успели - ошибка и нет проблем. Ведь эксперт как-то сразу получил корректные данные без ошибок! Значит можно реализовать. @Slava, можете высказаться по поводу, будет ли исправлено явно ошибочное поведение? Или, хотя бы, дополнение документации (что при prev_calculated = 0 корректных данных старших ТФ не получить)?
Да я в курсе, что все индикаторы одного символа находятся в одном потоке, а на каждый эксперт выделяется свой поток. Но это не дело. Разработчики - они на то и разработчики, чтобы исправлять ошибки в своих творениях. Программы не должны по разному работать! Если индикаторы что-то не успели - ошибка и нет проблем. Ведь эксперт как-то сразу получил корректные данные без ошибок! Значит можно реализовать. @Slava, можете высказаться по поводу, будет ли исправлено явно ошибочное поведение? Или, хотя бы, дополнение документации (что при prev_calculated = 0 корректных данных старших ТФ не получить)?
В документации где то было что эксперту дается целых 5 секунд перед запуском чтобы получить данные, а в это время терминал пытается выкачать данные для эксперта. Индикатору это не дано, так же индикатору не положено запрашивать обновление истории, для него это не критично, если критично - значит считайте в эксперте. Главная мысль, что в текущей реализации не возможно желаемое положение вещей. По существу, ТФ-ы это таймеры и есть периоды где эти кратные таймеры совпадают в один момент - это 100% совпадающий по времени синхронный процесс(кроме времени открытия/закрытия), т.к. первый тик минуты текущего тф совпадающей с первой минутой пятиминутки, часа и т.д. - это просто запись в несколько переменных одного и того же значения , и логично что в этих моментах можно задать набор нужных ТФ и получать все необходимые данные сразу. Почему разработчики сделали так, а не иначе, хз, возможно из-за разделения клиент-сервер это невозможно было(будет) сделать в существующей модели работы терминала, т.к. если сейчас дать возможность индикаторам возможности экспертов, то они завесят терминал.
Можно посмотреть в конце дня, кому интересно, как работает вызов индикатора, индикатор вызывает другой индикатор, эксперт(_asktfexp) вызывает индикатор(_asktf_sample) вызывающий индикатор(_asktf). При вызове индикатора из эксперта, таймер в индикаторе не запустится, поэтому решения с таймером в индикаторе это только для случаев, когда этот индикатор только будет висеть на графике и не будет вызываться (что в общем логично).