Об IndicatorCounted()

 

 Столкнулся с задачей. Если отказаться в некоторых индикаторах от использования IndicatorCounted(), то при запуске терминала после определённого простоя не прорисовывается весь буфер на графике торгового инструмента. Например, имеется индикатор Zig-Zag. От IndicatorCounted() отказался. Если вчера или в какой-то другой день этот индикатор работал, то при запуске терминала будет прорисован Zig-Zag по всей истории, до момента предыдущего закрытия терминала. Остальное не прорисовано. Вот на графике чёрная линия:

 

 Вместо IndicatorCounted() я использую следующий конструкцию:

В глобальных переменных:

int       countedBars;                             // Количество просчитанных баров таймсерии, на предыдущем вызове

 В OnInit() так:

countedBars = 0;                                // На данный момент, не просчитано ни одного бара

 В OnCalculate() так:

 if (lastBarTime != Time[i_TF])                     // Появился новый бар..
   {
      ratesCount++;                                 // Появился новый бар в рассчитываемой таймсерии
      lastBarTime = Time[i_TF];
   }
      
      int limit = GetRecalcIndex();                 // Определим первый расчетный бар

 И вот функция GetRecalcIndex():

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                               Определение индекса бара, с которого необходимо производить перерасчет                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------+
int GetRecalcIndex()
{
//   int countedBars = IndicatorCounted();
   if (countedBars == 0)                           // Кол-во посчитанных баров - 0. Будут
   {                                               // ..пересчитаны все буфера с самого начала
      ArrayInitialize (ZZBuf, EMPTY_VALUE);        // Очистка буфера экстремумов Zig-Zag'а
      ArrayInitialize (ZZModifyedBuf, EMPTY_VALUE);// Очистка буфера экстремума модифицированного Zig-Zag'а
      ArrayInitialize (ZZTime, 0);                 // Очистка буфера времени нахождения экстремумов Zig-Zag'а
      ArrayInitialize (tendency, 0);               // Обнуление буфера направления движения цены
      return (ratesCount - 2);                     // Начинаем со второго бара истории
   }
   return (ratesCount - countedBars - 1);          // Начинаем с нового бара
}

 По логике всё верно. Но мой вариант работает только, если запустить терминал и переключить ТФ. Тогда всё пересчитывается. В чём косяк?

 
https://www.mql5.com/ru/code/14173/84221#!tab=code
 
eevviill:
https://www.mql5.com/ru/code/14173/84221#!tab=code

По этой ссылке:

 

 
shanty:

 Столкнулся с задачей. Если отказаться в некоторых индикаторах от использования IndicatorCounted(), то при запуске терминала после определённого простоя не прорисовывается весь буфер на графике торгового инструмента. Например, имеется индикатор Zig-Zag. От IndicatorCounted() отказался. Если вчера или в какой-то другой день этот индикатор работал, то при запуске терминала будет прорисован Zig-Zag по всей истории, до момента предыдущего закрытия терминала. Остальное не прорисовано. Вот на графике чёрная линия:

 

 Вместо IndicatorCounted() я использую следующий конструкцию:

В глобальных переменных:

 В OnInit() так:

 В OnCalculate() так:

 И вот функция GetRecalcIndex():

 По логике всё верно. Но мой вариант работает только, если запустить терминал и переключить ТФ. Тогда всё пересчитывается. В чём косяк?

 

 

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

 
shanty:

По этой ссылке:

 

 

https://www.mql5.com/ru/code/14173
 
tara:

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

Что Вы имеете ввиду? Если мне не нужно просчитывать все бары, то какой прок мне от встроенного счётчика? Или Вы не представляете надобность этой альтернативы?

 

eevviill:
https://www.mql5.com/ru/code/14173

 Василий, там нет ответа не мой вопрос.

 
shanty:

Что Вы имеете ввиду? Если мне не нужно просчитывать все бары, то какой прок мне от встроенного счётчика? Или Вы не представляете надобность этой альтернативы?

 

 Василий, там нет ответа не мой вопрос.

Точно???? С таким анализом кода ещё долго будешь искать ответы.

//history update
   int all=rates_total;
   int counted=prev_calculated;
   if(all-counted>1)
     {
      ArrayInitialize(up_arr,EMPTY_VALUE);
      ArrayInitialize(down_arr,EMPTY_VALUE);
      counted=0;
     }

//main
   for(int i=all-counted;i>=0;i--)
 
eevviill:

Точно???? С таким анализом кода ещё долго будешь искать ответы. 

Так я ж его не анализировал. Думал там обычный индюк. Щяс прошерстю..

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

Если б я знал реализацию, я б не заморачивался. А так этот prev_calculated  - чёрный ящик, с непонятной надёжностью. Ведь если б, например, счётчик, который добавляет к prev_calculated каждый раз с каждым просчитанным баров 1-ку, то я б понял. А так хз как оно туда добавляет 1-ку, т.к. явной итерации нет.

 
shanty:

Так я ж его не анализировал. Думал там обычный индюк. Щяс прошерстю..

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

Если б я знал реализацию, я б не заморачивался. А так этот prev_calculated  - чёрный ящик, с непонятной надёжностью. Ведь если б, например, счётчик, который добавляет к prev_calculated каждый раз с каждым просчитанным баров 1-ку, то я б понял. А так хз как оно туда добавляет 1-ку, т.к. явной итерации нет.

Идеология OnCalculate() полностью прозрачна и понятно. Что здесь сложного? 

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 &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

Зашли в OnCalculate(), просчитали всю историю (при первом запуске или при подкачке истории) или просчитали только новые бары, перед выходом из OnCalculate() отдали rates_total. Никаких счётчиков не нужно. Всё что Вам нужно - это две переменные rates_total и prev_calculated.

 
barabashkakvn:

Идеология OnCalculate() полностью прозрачна и понятно. Что здесь сложного? 

Зашли в OnCalculate(), просчитали всю историю (при первом запуске или при подкачке истории) или просчитали только новые бары, перед выходом из OnCalculate() отдали rates_total. Никаких счётчиков не нужно. Всё что Вам нужно - это две переменные rates_total и prev_calculated.

Оно то всё понятно. Но есть один момент. Что если по какой-то причине определённый бар не просчитается ? В тот момент уже будет просчитано баров на 1 больше. Соответственно, будет сдвиг в итарации просчитанных баров. Я понимаю, что обычно подобных вариантов не возникнет, но всё же ситуация может быть подобная. Тогда как быть?
 
shanty:
Оно то всё понятно. Но есть один момент. Что если по какой-то причине определённый бар не просчитается ? В тот момент уже будет просчитано баров на 1 больше. Соответственно, будет сдвиг в итарации просчитанных баров. Я понимаю, что обычно подобных вариантов не возникнет, но всё же ситуация может быть подобная. Тогда как быть?

Что значит бар не посчитается? Вы в цикле обходите или по всем барам (при первом запуске или при обновлении истории) или проходите в цикле только по изменённым барам. Абсолютно все бары просчитываюся.


Добавлено.

Никакой итерации не существует - это в Вашей голове застряло неправильное слово. Единственное, что Вы можете натворить - это сделать неправильный алгоритм просчёта новых баров (например появился новый бар и в этом случае Вам нужно просчитать предыдущий и новый - а Вы просчитаете только новый бар. В таком случае в индикаторном буфере на месте предыдущего бара будет неопределенное число).

То есть Вы определяете сколько новых баров (это элементарно) и соответственно просчитываете только новые бары.