prev_calculated

 
В эту тему были перенесены комментарии, не относящиеся к "Ошибки, баги, вопросы".
 

MT5 билд 1455

Индикатор для теста:

#property indicator_chart_window
#property indicator_buffers     0
#property indicator_plots       0

int OnInit(void) {return(INIT_SUCCEEDED);}

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 &TickVolume[],
  const long &Volume[],
  const int &Spread[]
) {
  static int si_Tick = 0;
  Print(++si_Tick, ": prev_calculated = ", prev_calculated);
  
  return(rates_total);
}

1. Вешаю индикатор на график

2. Закрываю терминал

3. Открываю терминал

В логе:

2016.10.17 08:04:38.755 Test (USDJPY,M15)       1: prev_calculated = 0
2016.10.17 08:04:38.757 Test (USDJPY,M15)       2: prev_calculated = 100322
2016.10.17 08:04:39.060 Test (USDJPY,M15)       3: prev_calculated = 0
2016.10.17 08:04:39.837 Test (USDJPY,M15)       4: prev_calculated = 100322
2016.10.17 08:04:39.837 Test (USDJPY,M15)       5: prev_calculated = 100322
...

Я чего-то не понимаю или верить переменной prev_calculated нельзя, нужно стругать костыль?

 
Alexander Puzanov:

MT5 билд 1455

Индикатор для теста:

#property indicator_chart_window
#property indicator_buffers     0
#property indicator_plots       0

int OnInit(void) {return(INIT_SUCCEEDED);}

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 &TickVolume[],
  const long &Volume[],
  const int &Spread[]
) {
  static int si_Tick = 0;
  Print(++si_Tick, ": prev_calculated = ", prev_calculated);
  
  return(rates_total);
}

1. Вешаю индикатор на график

2. Закрываю терминал

3. Открываю терминал

В логе:

2016.10.17 08:04:38.755 Test (USDJPY,M15)       1: prev_calculated = 0
2016.10.17 08:04:38.757 Test (USDJPY,M15)       2: prev_calculated = 100322
2016.10.17 08:04:39.060 Test (USDJPY,M15)       3: prev_calculated = 0
2016.10.17 08:04:39.837 Test (USDJPY,M15)       4: prev_calculated = 100322
2016.10.17 08:04:39.837 Test (USDJPY,M15)       5: prev_calculated = 100322
...

Я чего-то не понимаю или верить переменной prev_calculated нельзя, нужно стругать костыль?

Переменная prev_calculated может сброситься в 0 даже без подкачки истории если контрольная сумма изменилась(это примерный ответ от сервисдеска).
 
Alexey Kozitsyn:
Переменная prev_calculated может сброситься в 0 даже без подкачки истории если контрольная сумма изменилась(это примерный ответ от сервисдеска).
Ясно. Спасибо. Знач к столяру..
 
Alexander Puzanov:
Ясно. Спасибо. Знач к столяру..
Не нужно так утрировать - возврат нуля от prev_calculate - самое что не есть заурядное событие. Задача программиста отлавливать такое событие и правильно заполнять индикаторные буферы в таком случае. Не больше и не меньше.
 
Ilyas:

Добавлены операторы *(Dereference/Inderection) и &(Address-of), никаких дополнительных изменений в языке делать не будем/планируем

Разъясните пожалуйста следующее:

* получение переменной по ссылке - относится только к:

1. Объекты классов

2. Объекты структур

3. Фундаментальные типы

В данном контексте это только rlvalue или lvalue так же?

 
Karputov Vladimir:
Задача программиста отлавливать такое событие

Знач я не программист - задачи другие. Столяр, наверное - буду 'стругать костыль' и считать что 'отлавливаю событие'

И ничё я не утрирую, бо заявленное назначение этой переменной:

prev_calculated  // обработано баров на предыдущем вызове

В нагрузку к этому назначению ей навешано ещё быть флагом изменений в истории, плюс ещё какие-то изменения отслеживать. Это всё полезно, но использовать по прямому назначению - показывать сколько 'обработано баров на предыдущем вызове' - prev_calculated нельзя

 
Alexander Puzanov:

Знач я не программист - задачи другие. Столяр, наверное - буду 'стругать костыль' и считать что 'отлавливаю событие'

И ничё я не утрирую, бо заявленное назначение этой переменной:

prev_calculated  // обработано баров на предыдущем вызове

В нагрузку к этому назначению ей навешано ещё быть флагом изменений в истории, плюс ещё какие-то изменения отслеживать. Это всё полезно, но использовать по прямому назначению - показывать сколько 'обработано баров на предыдущем вызове' - prev_calculated нельзя

А если просто пересчитать весь индикатор когда 0? По-моему, лучшее решение.
 
Alexander Puzanov:

Знач я не программист - задачи другие. Столяр, наверное - буду 'стругать костыль' и считать что 'отлавливаю событие'

И ничё я не утрирую, бо заявленное назначение этой переменной:

prev_calculated  // обработано баров на предыдущем вызове

В нагрузку к этому назначению ей навешано ещё быть флагом изменений в истории, плюс ещё какие-то изменения отслеживать. Это всё полезно, но использовать по прямому назначению - показывать сколько 'обработано баров на предыдущем вызове' - prev_calculated нельзя

Если prev_calculated=0, то это означает, что надо делать полный пересчёт. Все стандартные индикаторы полностью пересчитываются в данном случае.

Что непонятного?

Сказано же, что контрольная сумма в истории изменилась. Дешевле пересчитать индикатор, чем выяснять, а почему же изменилась контрольная сумма.

В документации явно про это сказано

Необходимо отметить связь между значением, возвращаемым функцией OnCalculate() и вторым входным параметром prev_calculated. Параметр prev_calculated при вызове функции содержит значение, которое вернула функция OnCalculate() на предыдущем вызове. Это позволяет реализовать экономные алгоритмы расчета пользовательского индикатора с тем, чтобы избежать повторных расчетов для тех баров, которые не изменились с предыдущего запуска этой функции.

Для этого обычно достаточно вернуть значение параметра rates_total, которое содержит количество баров при текущем вызове функции. Если с момента последнего вызова функции OnCalculate() ценовые данные были изменены (подкачана более глубокая история или были заполнены пропуски истории), то значение входного параметра prev_calculated будет установлено в нулевое значение самим терминалом.

 
Alexey Kozitsyn:
А если просто пересчитать весь индикатор когда 0? По-моему, лучшее решение.
Именно так и нужно поступать: при поступлении prev_calculate==0 нужно пересчитывать ВЕСЬ индикатор. Так как rev_calculate==0 это, как правило, подкачка истории. А если история была подкачена, значит могут быть новые бары, которые были пропущены или не рассчитаны ранее - то есть показания индикатора уже будут неправильными.
 
Karputov Vladimir:
Именно так и нужно поступать: при поступлении prev_calculate==0 нужно пересчитывать ВЕСЬ индикатор. Так как rev_calculate==0 это, как правило, подкачка истории. А если история была подкачена, значит могут быть новые бары, которые были пропущены или не рассчитаны ранее - то есть показания индикатора уже будут неправильными.
:) Я так и делаю...
Причина обращения: