более баров (значит что-то изменилось в истории)
if (prev_calculated==0 || calculated!=bars_calculated || rates_total> prev_calculated+1)
{
// – - если массив больше, чем значений в индикаторе на паре symbol/period, то копируем не все
// – - в противном случае копировать будем меньше, чем размер индикаторных буферов
if (calculated> rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
// – - значит наш индикатор рассчитывается не в первый раз и с момента последнего вызова OnCalculate ())
// – - для расчета добавилось не более одного бара
values_to_copy= (rates_total-prev_calculated) +1;
}
// – - запомним количество значений в индикаторе
bars_calculated=calculated;
// – - вернем значение prev_calculated для следующего вызова
return (rates_total);
}
Здесь переменная values_to_copy – количество рассчитываемых значений в вызове функции OnCalculate ().
Переменная prev_calculated – сколько было обработано баров функцией OnCalculate () при предыдущем вызове.
Таким образом, при загрузке индикатора prev_calculated=0, а при каждом следующем поступлении нового тика prev_calculated= rates_total.
Переменная prev_calculated также обнуляется терминалом, если вдруг изменилось значение переменной rates_total.
Переменная bars_calculated – предыдущее количество рассчитанных данных для запрашиваемого индикатора, на основе которого рассчитывается данный индикатор.
Таким образом, первая проверка здесь:
prev_calculated==0 – индикатор только что загрузился или изменилась ценовая история.
calculated!=bars_calculated – изменилось количество рассчитанных данных для запрашиваемого индикатора.
rates_total> prev_calculated+1 – необходимо рассчитать индикатор для двух или более баров (значит, что-то изменилось в истории).
Последнее условие вступает в противоречие с утверждением справочника:
Если с момента последнего вызова функции OnCalculate () ценовые данные были изменены (подкачана более глубокая история или были заполнены пропуски истории), то значение входного параметра prev_calculated будет установлено в нулевое значение самим терминалом.
Если изменилась история, тогда сработает проверка prev_calculated==0 и проверка последнего условия будет излишней.
Теперь, если срабатывает первое или второе условие, тогда количество рассчитываемых значений – это размер входных таймсерий или количество рассчитанных данных для запрашиваемого индикатора, на основе которого рассчитывается данный индикатор, что из них меньше.
Если же первое или второе условие не срабатывают, тогда количество рассчитываемых значений:
values_to_copy= (rates_total-prev_calculated) +1;
Опять же, тут есть излишний код, так как, судя по справочнику, переменная prev_calculated может принимать значение либо 0, либо rates_total.
Поэтому, values_to_copy=1.
Таким образом, при поступлении нового тика, будет рассчитываться только одно значение индикатора для этого нового тика.
Рассмотрим другую реализацию вычисления размера данных, которые необходимо рассчитать в вызове функции OnCalculate ().
Для индикатора MACD это реализовано следующим образом:
// – - we can copy not all data
int to_copy;
if (prev_calculated> rates_total || prev_calculated <0) to_copy=rates_total;
else
{
to_copy=rates_total-prev_calculated;
if (prev_calculated> 0) to_copy++;
}
Опять же, судя по справочнику, здесь будет работать только код:
to_copy=rates_total-prev_calculated;
if