Индикатор ругается на "Array out of a range", что нужно исправить?

 

Добрый день!

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

//+------------------------------------------------------------------+

//|                                                     Pattern1.mq5 |

//|                        Copyright 2013, MetaQuotes Software Corp. |

//|                                              http://www.mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2013, MetaQuotes Software Corp."

#property link      "http://www.mql5.com"

#property version   "1.00"

#property indicator_chart_window

#property indicator_buffers 2

#property indicator_plots   2

//--- plot BuyBar

#property indicator_label1  "BuyBarBuffer"

#property indicator_type1   DRAW_BARS

#property indicator_color1  clrBlue

#property indicator_style1  STYLE_SOLID

#property indicator_width1  1

//--- plot SellBarBuffer

#property indicator_label2  "SellBarBuffer"

#property indicator_type2   DRAW_BARS

#property indicator_color2  clrYellow

#property indicator_style2  STYLE_SOLID

#property indicator_width2  1

//--- input parameters

input int      Procent=20;

//--- indicator buffers

double         BuyBarBuffer[];

double         SellBarBuffer[];

double         ExtVolBuffer[];

double         HCPBuffer[];

double         LCPBuffer[];

//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int OnInit()

  {

//--- indicator buffers mapping

   SetIndexBuffer(0,BuyBarBuffer,INDICATOR_DATA);

   SetIndexBuffer(1,SellBarBuffer,INDICATOR_DATA);

   SetIndexBuffer(2,ExtVolBuffer,INDICATOR_CALCULATIONS);

   SetIndexBuffer(3,HCPBuffer,INDICATOR_CALCULATIONS);

   SetIndexBuffer(4,LCPBuffer,INDICATOR_CALCULATIONS);

//---

   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 &TickVolume[],

                const long &Volume[],

                const int &Spread[])

  {

//---

   if (rates_total<1)

      return 0;

      

   int i, first;

   const short sto = 100;   

   

   if (prev_calculated == 0)

      first = 1;

   else first = prev_calculated - 1;

   

//--- the main loop of calculations

   for(i=first;i<rates_total && !IsStopped();i++)

     {

      ExtVolBuffer[i] = High[i] - Low[i];

      HCPBuffer[i] = (sto * (High[i] - Close[i])) / ExtVolBuffer[i];

      LCPBuffer[i] = (sto * (Close[i] - High[i])) / ExtVolBuffer[i];

      

      if (HCPBuffer[i] <= Procent && LCPBuffer[i] > Procent)

         BuyBarBuffer[i] = HCPBuffer[i];

      else

         if (LCPBuffer[i] <= Procent && HCPBuffer[i] > Procent)

            SellBarBuffer[i] = LCPBuffer[i];

     }

//--- return value of prev_calculated for next call

   return(rates_total);

  }


Что же я хотел сделать на самом деле? Мне нужно было от индикатора, чтобы он брал бар и считал какой процент от всего бара составляет расстояние от максимума и до закрытия, а затем от минимума до закрытия. И в случае если то или иное входило в установленный пользователем "процент", то индикатор подсвечивал такой бар желтым или синим цветами в зависимости от сигнала (продажа или покупка). Это из книги Ларри Вильямса, когда он объяснял фигуры. Готовые решения не нашел, пришлось импровизировать, да только пока не выходит :)

 Буду безмерно благодарен, если укажете на ошибки или же хотя бы отошлете, над чем подумать. Предполагаю, что не получается передать значения массивам. Не могу выявить, где "не так". Перелопатил все похожие индикаторы, там примерно также делают, но работает.

 
Sonotokiwaatte:


... 

#property indicator_buffers 2 - объявлено 2 индикаторных буфера

#property indicator_plots   2

...

//--- indicator buffers mapping

   SetIndexBuffer(0,BuyBarBuffer,INDICATOR_DATA);

   SetIndexBuffer(1,SellBarBuffer,INDICATOR_DATA);

   SetIndexBuffer(2,ExtVolBuffer,INDICATOR_CALCULATIONS); - инициализировано 5 буферов

   SetIndexBuffer(3,HCPBuffer,INDICATOR_CALCULATIONS);

   SetIndexBuffer(4,LCPBuffer,INDICATOR_CALCULATIONS);

...


Что же я хотел сделать на самом деле? Мне нужно было от индикатора, чтобы он брал бар и считал какой процент от всего бара составляет расстояние от максимума и до закрытия, а затем от минимума до закрытия. И в случае если то или иное входило в установленный пользователем "процент", то индикатор подсвечивал такой бар желтым или синим цветами в зависимости от сигнала (продажа или покупка). Это из книги Ларри Вильямса, когда он объяснял фигуры. Готовые решения не нашел, пришлось импровизировать, да только пока не выходит :)

 Буду безмерно благодарен, если укажете на ошибки или же хотя бы отошлете, над чем подумать. Предполагаю, что не получается передать значения массивам. Не могу выявить, где "не так". Перелопатил все похожие индикаторы, там примерно также делают, но работает.

в #property indicator_buffers 2 объявлено всего 2 буфера, а инициализировано 5. Нужно в #property indicator_buffers объявить 5 буферов, у тебя их просто не существует, они не объявлены, поэтому пишет "out of range".
Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
Документация по MQL5: Основы языка / Препроцессор / Свойства программ (#property)
  • www.mql5.com
Основы языка / Препроцессор / Свойства программ (#property) - Документация по MQL5
 
Ern.CheGevarra:
в #property indicator_buffers 2 объявлено всего 2 буфера, а инициализировано 5. Нужно в #property indicator_buffers объявить 5 буферов, у тебя их просто не существует, они не объявлены, поэтому пишет "out of range".

Благодарю. Это изменил, но теперь ругается на "Zero divide" в этой строке:

      HCPBuffer[i] = (sto * (High[i] - Close[i])) / ExtVolBuffer[i];

 

Думаю, что это из-за того, что в предыдущей строке никакие данные не заносятся, но почему?

      ExtVolBuffer[i] = High[i] - Low[i];

 Условие for можете наблюдать в предыдущем письме. Для моего ведь индикатора нужен только один бар. Вот я и ставлю "1", однако судя по всему, данные не поступают. Пробовал менять на другие цифры, но результат не меняется :(

 

после 

ExtVolBuffer[i] = High[i] - Low[i];

можно попробовать Print(Higt[i]," ",Low[i]," ", ExtVolBuffer[i]), High-Low может быть равно нулю 

 

В случаях деления возьмите за правило - всегда проверять делитель на ноль. И обрабатывать эту ситуацию.

Zero divide - противная ошибка. Есть даже такая байка, как разбился самолет пролетая над 'мертвым морем'. Оно ниже реального уровня моря.  На нулевой высоте управление типа напоролось на Zero divide )) 

'out of range' кстати, наверно на втором месте по вредности)))

 

Всем спасибо за помощь!

Все-таки допилил))

pronych, да, благодарю, именно так и поступил. Увидь я Ваше сообщение чуть раньше, цены бы ему не было :) Теперь буду учитывать этот момент.

Для тех, кому нужен конечный результат, прикрепляю исходник. Он еще дает какие-то сбои, но пользоваться можно.

И второй файл - это индикатор, опять же, Ларри Вильямса, но построенный по его формуле:

"(MovingAvg (Close Low VAR1) / Avg True Range (VAR1)) * 100", который считает "Price Cycle".

 P.S. Тему можно закрывать.

Файлы:
 

так же порекомендую ВСЕГДА ставить фигурные скобки после условных операторов

 

if (HCPBuffer[i] <= Procent && LCPBuffer[i] > Procent)

         {BuyBarBuffer[i] = HCPBuffer[i];}
это предотвратит ваще глупые но труднообнаружимые ошибки. когда допишешь к условию и не обратишь внимание что скобок нет