prev_calculated - страница 2

 
Alexey Kozitsyn:
А если просто пересчитать весь индикатор когда 0? По-моему, лучшее решение.
Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого
 
Alexey Kozitsyn:
:) Я так и делаю...
Я так и понял, просто я цитировал Ваш вопрос, но реально я отвечал Alexander Puzanov. :)
 
Alexander Puzanov:
Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого

Человек употребляющий слово "костыль":  

  • или лениться почитать документацию
  • или пока ещё не знает, как должно быть правильно.
Единственно правильное решение: при prev_calculate==0 пересчитывать индикатор.

 
Alexander Puzanov:
Для тяжёлого индикатора с тоннами графики - далеко не лучшее. Да не, решение-то простое - использовать вместо prev_calculated собственную переменную, статическую или глобальную. Но это таки костыль, а хотелось жеж другого
Ни разу не костыль. Так и делаю.
 
Karputov Vladimir:
А если история была подкачена, значит могут быть новые бары, которые были пропущены или не рассчитаны ранее - то есть показания индикатора уже будут неправильными.

Slawa:

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

Всё понятно, но увы, это всё не отменяет вот этого:

Alexander Puzanov:

Это всё полезно, но использовать по прямому назначению - показывать сколько 'обработано баров на предыдущем вызове' - prev_calculated нельзя

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

В общем, ув программисты, не отвлекайте, пожалуйста, столяра от 'отлова события'

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

Я-бы не сказал что это лучшее решение. Во всяком случае пока не лучшее.

Решил я написать индикатор регистрирующий текущую просадку на счёте, соответственно мне ничего в истории пересчитывать не надо. Первая строка выглядела сначала так.

if(prev_calculated == 0)  return(rates_total);
Но после запуска обнаружил что буферы не пустые и не обнулённые. В буферах какая-то цена неизвестно откуда взявшаяся. Пришлось принудительно обнулять буферы... Дальше обнаружилась другая проблема. Именно та о которой идёт речь, prev_calculate обнуляется и индикатор пересчитывается, соответственно обнуляя все буферы до последнего бара. В общем пока бросил эту затею.
 
Alexey Viktorov:

Я-бы не сказал что это лучшее решение. Во всяком случае пока не лучшее.

Решил я написать индикатор регистрирующий текущую просадку на счёте, соответственно мне ничего в истории пересчитывать не надо. Первая строка выглядела сначала так.

if(prev_calculated == 0)  return(rates_total);
Но после запуска обнаружил что буферы не пустые и не обнулённые. В буферах какая-то цена неизвестно откуда взявшаяся. Пришлось принудительно обнулять буферы... Дальше обнаружилась другая проблема. Именно та о которой идёт речь, prev_calculate обнуляется и индикатор пересчитывается, соответственно обнуляя все буферы до последнего бара. В общем пока бросил эту затею.

 "... какая-то цена неизвестно откуда взявшаяся ... " - это мусор НЕИНИЦИАЛИЗИРОВАННЫХ элементов массива индикаторного буфера. Как нужно поступать:

  • при prev_calculate==0 пройтись в цикле по всем элементам индикаторного буфера и назначить им значения. При этом нужно отслеживать ситуацию появления нового бара ( rates_total минус prev_calculate будет больше нуля) - при этом индикаторный буфер соответственно увеличивается и этот новый элемент тоже нужно проинициализировать.

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Alexey Viktorov, 2016.10.17 09:58

Сам-то понял что написал?

Лучше объясни как избавиться от мусора ПРИ ПЕРВОМ запуске индикатора. Откуда этот мусор? Разве при связывании буфера с массивом не должно происходить инициализации? или именно при инициализации в массив попадает космический мусор??? Почему в mql4 такого мусора нет?

Приведи лучше пример как отсеять мусор от нормальных значений без использования посторонних дополнительных статических или глобальных переменных.

Цитировать документацию все горазды.


 

Никто никому ничего не должен. То есть в индикаторном буфере, после связывания, будет мусор, пока Вы самостоятельно не проинициализируете все элементы массива.

 

Добавлено:

Сейчас создам пример... 

//+------------------------------------------------------------------+
//|                                              prev_calculated.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGray
#property indicator_label1  "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   if(prev_calculated==0)
     {
      //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
      for(int i=0;i<rates_total;i++)
         ExtBuffer[i]=1.01;
      return(rates_total);
     }
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
   int limit=rates_total-prev_calculated+1;
   for(int i=rates_total-limit;i<rates_total;i++)
     {
      //--- визуализация пересчёта самого правого бара
      static bool drive=false;
      if(!drive)
         ExtBuffer[i]=1.03;
      else
         ExtBuffer[i]=1.02;
      drive=!drive;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Запустите его на M1. Будет видно, что пересчитывается только самый правый бар.
Файлы:
 
Karputov Vladimir:

Никто никому ничего не должен. То есть в индикаторном буфере, после связывания, будет мусор, пока Вы самостоятельно не проинициализируете все элементы массива.

 

Добавлено:

Сейчас создам пример... 

//+------------------------------------------------------------------+
//|                                              prev_calculated.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGray
#property indicator_label1  "prev_calculated"
//---- buffers
double ExtBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   if(prev_calculated==0)
     {
      //--- инициализация элементов индикаторного буфера при первом запуске или при подкачке истории
      for(int i=0;i<rates_total;i++)
         ExtBuffer[i]=1.01;
      return(rates_total);
     }
//--- пересчитываем самый правый бар или самый правый бар и один предыдущий при появлении нового бара
   int limit=rates_total-prev_calculated+1;
   for(int i=rates_total-limit;i<rates_total;i++)
     {
      //--- визуализация пересчёта самого правого бара
      static bool drive=false;
      if(!drive)
         ExtBuffer[i]=1.03;
      else
         ExtBuffer[i]=1.02;
      drive=!drive;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Запустите его на M1. Будет видно, что пересчитывается только самый правый бар.

Потрясающая способность отвечать не на тот вопрос который задан...

Теперь объясни мне что произойдёт если:

1. Пересчиталось 100 баров, внесено в буферы от 0 по 99 включительно (давайте считать направление как таймсерию) значение 1.03

2. Вдруг подгрузилась история и prev_calculated стало равно 0

С какого бара в индикаторе будет значение 1.03???

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