MQL5 при отрисовке индикатора. - страница 4

 
Fedor Arkhipov:
А вы всегда инициализируете буферы в функции OnCalculate() ?

Только при первом старте или подкачке истории:

//+------------------------------------------------------------------+
//| 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(rates_total<4) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)                               // Если вписать limit>0 - то появление нового бара и полный просчёт индикатора на каждом новом баре
     {                                       // при limit>1 - изменение исторических данных и полный просчёт индикатора, иначе просчёт нулевого и первого бара
      limit=rates_total-1;
      ArrayInitialize(Buffer,EMPTY_VALUE);   // здесь в качестве нерисуемого значения выступает EMPTY_VALUE
     }                                       // Если в OnInit() задать PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,128), то именно 128.0 будет нерисуемым значением

//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {

     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

При вычислениях не обязательно заполнять буфер значением EMPTY_VALUE  в MT4 и в МТ5. Нужно лишь заполнить нужные значения индикатора. А это значит, что буфер был инициализирован изначально.

 
Вы еще в своем коде забыли докачать историю котировок. При переключении на новый символ, по которому нет истории, ваш индикатор будет работать не корректно.
 
Fedor Arkhipov:
Вы еще в своем коде забыли докачать историю котировок. При переключении на новый символ, по которому нет истории, ваш индикатор будет работать не корректно.

Поверьте, если это мне, мои индикаторы сделаны корректно. А выше был лишь минимально-достаточный пример в ответ на ваш вопрос.

 
Fedor Arkhipov:

При вычислениях не обязательно заполнять буфер значением EMPTY_VALUE  в MT4 и в МТ5. Нужно лишь заполнить нужные значения индикатора. А это значит, что буфер был инициализирован изначально.

Особенно на стрелочных индикаторах :)))

А потом народ не понимает откуда куча мусора берётся на графике.

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

 
Fedor Arkhipov:
Вы еще в своем коде забыли докачать историю котировок. При переключении на новый символ, по которому нет истории, ваш индикатор будет работать не корректно.

А вот это?

if(rates_total<4) return 0;

Только на четырёх сможет отрисоваться - иначе возврат на ожидание подкачки. Причём 4 - это не постоянная величина, а зависящая от конкретного индикатора. И часто - расчётная величина.

На мультитаймфреймовых там иначе, но тоже всё есть, и работает.

 
Artyom Trishkin:

Особенно на стрелочных индикаторах :)))

А потом народ не понимает откуда куча мусора берётся на графике.

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

100 %

и желательно не пользовать лишние неиспользуемые буферы

опять же мусорка получится

 

Я изначально ни у кого не просил помощи, я открыл тему чтобы указать на проблему, которой просто не было в МТ4. Я считаю что это баг МТ5.

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

Попробуйте не задать значение переменной, вы сразу получите предупреждение.

Инициализация производится в тестере стратегий и при повторном прикреплении того же индикатора на график. Это два факта, которые имеют место.

Третий факт - инициализация производится в МТ4 аналогичной функцией.

 
Fedor Arkhipov:

Я изначально ни у кого не просил помощи, я открыл тему чтобы указать на проблему, которой просто не было в МТ4. Я считаю что это баг МТ5.

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

Попробуйте не задать значение переменной, вы сразу получите предупреждение.

Инициализация производится в тестере стратегий и при повторном прикреплении того же индикатора на график. Это два факта, которые имеют место.

Третий факт - инициализация производится в МТ4 аналогичной функцией.

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

ArrayInitialize(Buffer, Value) - инициализация массива Buffer значением Value. Должна выполняться в индикаторах при прикреплении его к графику и при изменении исторических данных:
когда rates_total-prev_calculated > 1, в редких случаях >0

PlotIndexSetDouble(BufferNum, PLOT_EMPTY_VALUE, Value) - указание индикатору что значение Value буфера BufferNum НЕ должно выводиться, т.е - назначение пустого значения буферу. И это НЕ инициализация массива, а лишь задание пустого нерисуемого значения конкретному буферу. Если задать Value равным 0, то нулевое значение, находящееся в буфере не будет рисоваться на графике. Если задать Value равным EMPTY_VALUE, то значение DBL_MAX не будет рисоваться на графике индикатора. При этом, если задать в качестве пустого значения любое число, например -256, то DBL_MAX будет рисоваться на графике индикатора, так как EMPTY_VALUE==DBL_MAX.

 
Я этих индикаторов переделал больше сотни. Не забывайте, что это не обычный массив, а буфер индикатора.