Проблема при портировании индикатора с MQL4 на MQL5. Array out of the range/

 

При портировании кода индикатора во время исполнения вылетает ошибка - буферный массив не инициализируется, хотя такой же код на 4-ре работал отлично. Подозреваю, что неправильно задал какие-то опции компиляции.


Код для мт5

задал опции компиляции


//+------------------------------------------------------------------+
//|                                                       VSwing.mq5 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_type1   DRAW_ARROW
#property indicator_color1 Red
#property indicator_width1 1
#property indicator_plots  1 // количество графических построений



связал массив с буфером


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//----
   SetIndexBuffer(0,Buf1,INDICATOR_DATA);
   PlotIndexSetInteger(0,PLOT_ARROW,code); 
//--- установим пустое значение 
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   //--- установим индексацию для буфера как в таймсерии
   //ArraySetAsSeries(Buf1,true);
   PlotIndexSetString(0, PLOT_LABEL, "Break");


   return(0);
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,      // размер входных таймсерий 
                 const int prev_calculated,  // обработано баров на предыдущем вызове 
                 const datetime& time[],     // Time 
                 const double& open[],       // Open 
                 const double& high[],       // High 
                 const double& low[],        // Low 
                 const double& close[],      // Close 
                 const long& tick_volume[],  // Tick Volume 
                 const long& volume[],       // Real Volume 
                 const int& spread[])         
  {

     здесь получаю ошибку
     
     i=nPoint1; BreakUp=false; BreakDn=false;
     while(i>=0 && BreakUp==false && BreakDn==false)
      {
       tmp=iHigh(NULL,0,nPoint1)-Speed*(nPoint1-i);
       tmp1=iHigh(NULL,0,nPoint1)-Speed*(nPoint1-i)-resultL;

       
       if(NormalizeDouble(iLow(NULL,0,i),Digits())<NormalizeDouble(tmp1,Digits()) && NormalizeDouble(iHigh(NULL,0,i),Digits())>NormalizeDouble(tmp,Digits()))
        {
         BreakUp=true;
!!!!!!!         if(channelbreak) Buf1[i]=tmp; !!!!!!!
         Comm="\nПробой вверх на уровне " + DoubleToString(tmp,Digits());
        } 
       else
       if(NormalizeDouble(iLow(NULL,0,i),Digits())<NormalizeDouble(tmp1,Digits()))
        {
         BreakDn=true;
         if(channelbreak) Buf1[i]=tmp1;
         Comm="\nПробой вниз на уровне "+DoubleToString(tmp1,Digits());
        }
       else
       if(NormalizeDouble(iHigh(NULL,0,i),Digits())>NormalizeDouble(tmp,Digits()))
        {

         BreakUp=true;
         if(channelbreak) Buf1[i]=tmp;
         Comm="\nПробой вверх на уровне "+DoubleToString(tmp,Digits());
        }
       else Comm="\nПробоя канала нет";
       //i--;
      }
    }
    
  


Ошибка вылетает время исполнения цикла while{} при присвоении значений буферному массиву Buf1[i]=tmp1;

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

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

Файлы:
 

i должно быть от 0 до rates_total-1

проверку вставте, и выходите из цикла когда до конца добрались

 
Igor Zakharov:

i должно быть от 0 до rates_total-1

проверку вставте, и выходите из цикла когда до конца добрались

Игорь, спасибо за ответ.

Там в коде значение nPoint1, которое потом присваивается i, назначается во входном параметре и равно 34. При перетаскивании фиботаймс оно изменяется на произвольное число в промежутке от 0 до rates_total-1(на самом деле там в цикле значение i будет всегда заведомо меньше  rates_total-1, а первое значение всегда заведомо больше нуля). Дело в том, что уже при первом присваивании вылетает ошибка. Проверял размерность массива, она равна нулю. Т.е. массив не инициализируется. Значения индекса на первом шаге равно 34.

 
KIPiA:

Игорь, спасибо за ответ.

Там в коде значение nPoint1, которое потом присваивается i, назначается во входном параметре и равно 34. При перетаскивании фиботаймс оно изменяется на произвольное число в промежутке от 0 до rates_total-1(на самом деле там в цикле значение i будет всегда заведомо меньше  rates_total-1, а первое значение всегда заведомо больше нуля). Дело в том, что уже при первом присваивании вылетает ошибка. Проверял размерность массива, она равна нулю. Т.е. массив не инициализируется. Значения индекса на первом шаге равно 34.

причина этой ошибки -- однозначный выход значения i за rates_total-1

вы привели код без той части, где идёт присвоение значения i -- т.е. без этой части дать точный ответ невозможно

 
KIPiA:

Игорь, спасибо за ответ.

Там в коде значение nPoint1, которое потом присваивается i, назначается во входном параметре и равно 34. При перетаскивании фиботаймс оно изменяется на произвольное число в промежутке от 0 до rates_total-1(на самом деле там в цикле значение i будет всегда заведомо меньше  rates_total-1, а первое значение всегда заведомо больше нуля). Дело в том, что уже при первом присваивании вылетает ошибка. Проверял размерность массива, она равна нулю. Т.е. массив не инициализируется. Значения индекса на первом шаге равно 34.

!!! это пятёрка - OnInit() 

int init() //все советчики, включая меня, проглядели :D
 
KIPiA:

При портировании кода индикатора во время исполнения вылетает ошибка - буферный массив не инициализируется, хотя такой же код на 4-ре работал отлично. Подозреваю, что неправильно задал какие-то опции компиляции.


Код для мт5


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

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

типичная ошибка, при этом освещённая в документации.. неявно конечно, но про неё сказано

при работе с массивами ВСЕГДА задавайте направление индексации.

то есть получив на входе в функцию anytype &arr[]; первое что надо делать это ArraySetAsSeries(arr, ...)

при выходе из функции желательно восстановить прежнее,иначе тоже проблемы

 
KIPiA:

... Т.е. массив не инициализируется. ...

пока не ясно, о чём вы здесь говорите -- но

PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);

-- это не инициализация массива -- это установка пустого значения, для которого нет отрисовки.

элементы индикаторного буфера надо инициализировать явно.

 
Andrey F. Zelinsky:

причина этой ошибки -- однозначный выход значения i за rates_total-1

вы привели код без той части, где идёт присвоение значения i -- т.е. без этой части дать точный ответ невозможно

Это не совсем так.

В приведенной мной части кода есть строка i=nPoint1;

Я дал пояснения, что nPoint1 - это индекс бара одной из точек построения временных фибо, которые двигаются руками. Изначально в input это значение равно 34. Пот ом в цикле while идет присвоение значения члену массива с индексом i. Там только есть ограничение через if. В остальном все как обычно.

 
пробовали заменить init() на OnInit()? 
 
Igor Zakharov:

!!! это пятёрка - OnInit() 

Игорь, спасибо. Заработало.
 
Andrey F. Zelinsky:

пояснения без кода стоят =0.

если хотите подсказки по этой ошибке -- надо видеть код.

если не хотите его в ветке показывать для всех -- то можете мне в личку прислать.

К первому посту прикреплен файл с кодом.

Спасибо, все заработало.

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