Init() выполняется не дождавшись данных

 

Проблема в том, что функция INIT() выполняется, не получив данные. Это происходит в следующих случаях когда индикатор загружен на график, архив котировок которого не известен, хотя график на экране есть. Такая ситуация случается при смене тайм-фрейма. При этом, хочу добавить, уже на функции START() данные получены! Так же данные получены при повторном и последующих загрузках индикатора на тот же график. Это проверено следующим индикатором:


#property indicator_chart_window

int init()
  {
   Print("Свечей ", Bars);  // Здесь выводится "Свечей 0"
  }

int deinit()
  {
  }

int start()
  {
   Print("Свечей ", Bars);  // Здесь выводится "Свечей 53". 53 - это пример.
  }


Проблема обходится сменой тайм-фрейма на любой другой и возвращением обратно. При возвращении происходит повторная инициализация и как результат функция INIT() уже "знает" количество свечей. Функция RefreshRates() не помогает. Ожидание по времени так же не приносит положительного результата (пробовал ждать 60 сек).

Внимание вопрос: Как программно это обойти?

 
Заметил что-то похожее и у меня вопрос к Папам MQL4 когда у нас стоит советник на графике и мы меняем тайм фрейм, на этом же графике, то у нас происходит деинициализация эксперта на старом тайм фрейме и инициализация его же на новом????
 

Да, я тоже отмечал для себя эту заморочку. Но думать в этом направлении не стал - особого практического смысла нет. А что вас в этой ситуации уж так особого напрягает?

Перенесите ту часть расчетов, что требует Bars в start() и все. Сделайте эти расчеты однократными (если уж так нужно) - при первом обращении к функции start(). Например, if(IndicatorCounted()==0) расчет.

 

Ввести переменную. FirstRun.

И вынести код Init в функцию Start.

 
TheXpert >>:

Ввести переменную. FirstRun.

И вынести код Init в функцию Start.

Можно и так.

Кстати! Давно хотел поднять тему про Init() - тут напомнили. Дело вот в чем. На практике, по-любому приходится ее в большей части дублировать. Сбасывать в ноль стат.переменные, переинициализировать буферы и стат.массивы при пропущеных барах (при пересчете) все равно надо. Если разобраться, то кроме присваивания номерам буферов имен массивов там делать особо ничего и не надо. Все остальное так или иначе приходится делать при уже запущенном индикаторе. Может, ну ее... совсем?)))

 
Собственно, инициализацию/переинициализацию нужно делать всегда, когда Bars-(IndicatorCounted()-1>1, за исключение первого запуска разве что ль.
 
Svinozavr >>:

Можно и так.

Кстати! Давно хотел поднять тему про Init() - тут напомнили. Дело вот в чем. На практике, по-любому приходится ее в большей части дублировать. Сбасывать в ноль стат.переменные, переинициализировать буферы и стат.массивы при пропущеных барах (при пересчете) все равно надо. Если разобраться, то кроме присваивания номерам буферов имен массивов там делать особо ничего и не надо. Все остальное так или иначе приходится делать при уже запущенном индикаторе. Может, ну ее... совсем?)))

чисто теоретически любую программу с инит() можно переписать и без инит() без потери функциональности. для сравнения в терминале одного известного банка никаких инитов нету, и все замечательно работает. так что инициативу поддерживаю однозначно.

ps а вот без деинит() обойтись вряд ли получится.

 
Svinozavr >>:

Можно и так.

Кстати! Давно хотел поднять тему про Init() - тут напомнили. Дело вот в чем. На практике, по-любому приходится ее в большей части дублировать. Сбасывать в ноль стат.переменные, переинициализировать буферы и стат.массивы при пропущеных барах (при пересчете) все равно надо. Если разобраться, то кроме присваивания номерам буферов имен массивов там делать особо ничего и не надо. Все остальное так или иначе приходится делать при уже запущенном индикаторе. Может, ну ее... совсем?)))

Вы просто не умеете её готовить :о)

У меня например в init() очень часто делается предварительный одноразовый расчёт,

к примеру расчёт среднего арифметического величины бара, какой смысл его пересчитывать на каждом тике, ведь оно всё равно почти не меняется.

Да и у других встречал присвоение вычислимых значений происходит в init(), так что вы сильно ошибаетесь говоря что init() никому не нужен,

вам может быть, но вы ведь не истина в последней инстанции :о)

 
Urain >>:


к примеру расчёт среднего арифметического величины бара, 

в первом посте как раз и описана ситуация, когда никаких баров еще нет, следовательно, и ср. арифметического у них нет...

 
Urain >>:

Вы просто не умеете её готовить :о)

У меня например в init() очень часто делается предварительный одноразовый расчёт,

к примеру расчёт среднего арифметического величины бара, какой смысл его пересчитывать на каждом тике, ведь оно всё равно почти не меняется.

Да и у других встречал присвоение вычислимых значений происходит в init(), так что вы сильно ошибаетесь говоря что init() никому не нужен,

вам может быть, но вы ведь не истина в последней инстанции :о)

))) Я улыбаюсь. Именно это означает ")))" после фразы "Может, ну ее ...совсем?"

Посмотрите код любого моего индюка - там init() используется по полной. Безуловно, зачем мне каждый раз, например, вычислять х*Point, если это можно сделать один раз и т.п.

Речь о другом.

Есть действия, которые необходимо сделать ТОЛЬКО при подсоединении индикатора к графику.

Но из них есть такие, которые необходимо повторять при работе.

И ф-ей init() они не ограничиваются. Я для этих целей использу ф-ю reinit(), где заново инициализируются общие переменные (частичное дублирование головной части), стат. переменные (эмуляция первого подключения индикатора), буферы (init()).

Так вот. Однократные действия можно сделать и без init() - так что ваш наезд непонятен.))) Тем более не все однократные действия происходят именно там.

 

Svinozavr писал(а) >>

Однократные действия можно сделать и без init() - так что ваш наезд непонятен.))) Тем более не все однократные действия происходят именно там.

init() ничем не отличается от start() кроме того что выполняется однократно "тчк" проблема высосана из пальца.

запуск индикатора

2009.09.03 14:36:43 Init_Time EURUSD,M30: Свечей start()2947

2009.09.03 14:39:58 Init_Time EURUSD,M30: initialized
2009.09.03 14:36:43 Init_Time EURUSD,M30: Свечей init()2947

смена ТФ

2009.09.03 14:40:05 Init_Time EURUSD,H1: Свечей start()17651
2009.09.03 14:40:05 Init_Time EURUSD,H1: initialized

2009.09.03 14:40:05 Init_Time EURUSD,H1: Свечей init()17651

запись идет снизу вверх.

код привожу:

#property indicator_chart_window

int init()
{//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
  Print("Свечей init()", Bars);
return(0);
}//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+

int deinit()
{//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
return(0);
}//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+

int start()
{//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
  Print("Свечей start()", Bars);
return(0);
}//+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+

как у топикстартера лиш обозначено где Print init где Print start.

Причина обращения: