Array out of Range Error

 

Hallo zusammen,


kann mir jemand helfen? Ich versuche gerade einen ADX-Indikator etwas umzubauen, allerdings bekomme ich immer einen Array out of Range Error in Zeile 142.

Ich stehe gerade auf dem Schlauch und komme nicht dahinter und wäre für jede Hilfe wirklich dankbar.

Sobald ich die Anzahl der indicator_buffers auf 6 erhöhe läuft das ganze durch und der Indikator wird auch korrekt berechnet, allerdings werden auch die Berechnungsbuffer als Linien dargestellt.


Grüße Hubert


//+------------------------------------------------------------------+
//|                                                  ADX - Final.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_label1 "ADX"
#property indicator_label2 "+DI"
#property indicator_label3 "-DI"


//---- buffers

double    ADX_Buffer[];
double    plusDI_Buffer[];
double    minusDI_Buffer[];
double    plusDI_calc_Buffer[];
double    minusDI_calc_Buffer[];
double    temp_Buffer[];

enum ENUM_LINE_WIDTH {thin = 1,         //1
                      mediumthin = 2,   //2
                      medium = 3,       //3
                      mediumthick = 4,  //4
                      thick =5          //5
                      };

//---- Input Variables

input    string place0 = "-------------------------";             //-------------------------
input    int ADX_period = 14;                                     //Period
input    ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT;              //Timeframe
input    ENUM_MA_METHOD MA_method = MODE_EMA;                     //Smoothing Method
input    ENUM_APPLIED_PRICE ADX_price = PRICE_CLOSE;              //Applied Price
input    int ADX_shift = 0;                                       //Shift
input    string place1 = "-------------------------";             //-------------------------
input    ENUM_LINE_STYLE ADX_style = 0;                           //ADX Style
input    ENUM_LINE_WIDTH ADX_width = 1;                           //ADX Width
input    color ADX_COLOR = Blue;                                  //ADX Color
input    string place2 = "-------------------------";             //-------------------------
input    ENUM_LINE_STYLE pDI_style = 2;                           //+DI Style
input    ENUM_LINE_WIDTH pDI_width = 1;                           //+DI Width
input    color pDI_COLOR = Green;                                 //+DI Color
input    string place3 = "-------------------------";             //-------------------------
input    ENUM_LINE_STYLE mDI_style = 2;                           //-DI Style
input    ENUM_LINE_WIDTH mDI_width = 1;                           //-DI Width
input    color mDI_COLOR = Red;                                   //-DI Color

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

   
   
   
   SetIndexStyle(0, DRAW_LINE, ADX_style, ADX_width, ADX_COLOR);
   SetIndexBuffer(0, ADX_Buffer, INDICATOR_DATA);
   SetIndexStyle(1, DRAW_LINE, pDI_style, pDI_width, pDI_COLOR);
   SetIndexBuffer(1, plusDI_Buffer, INDICATOR_DATA);
   SetIndexStyle(2, DRAW_LINE, mDI_style, mDI_width, mDI_COLOR);
   SetIndexBuffer(2 ,minusDI_Buffer, INDICATOR_DATA);
   
   SetIndexBuffer(3,plusDI_calc_Buffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,minusDI_calc_Buffer, INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,temp_Buffer, INDICATOR_CALCULATIONS);
   
   IndicatorShortName("ADX("+(string)ADX_period+")");
   
//---
   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 (rates_total < ADX_period)
      return (0);
      
   int bars = rates_total - ADX_period;
  
   if (prev_calculated > 0)
      bars = rates_total - prev_calculated;
      
      
   for(int i = bars; i >= 0; i--)
      {
      double price_high = iHigh(NULL, timeframe, i);
      double price_low = iLow(NULL, timeframe, i);
      
      double pdm = price_high - iHigh(NULL, timeframe, i+1);
      double mdm = iLow(NULL, timeframe, i+1) - price_low;;
      
      if (pdm < 0) 
         pdm = 0;  // +DM
      if (mdm < 0) 
         mdm = 0;  // -DM
      
      if (pdm == mdm) 
         {
         pdm = 0;
         mdm = 0;
         }
      else if (pdm < mdm)
         pdm = 0;
      else if (mdm < pdm)
         mdm = 0;
            
      double num1 = MathAbs(price_high - price_low);
      double num2 = MathAbs(price_high - iClose(NULL, timeframe, i+1));
      double num3 = MathAbs(price_low - iClose(NULL, timeframe, i+1));
      double tr = MathMax(num1, num2);
      tr = MathMax(tr, num3);
      
      if(tr == 0) 
         {
         plusDI_calc_Buffer[i] = 0; 
         minusDI_calc_Buffer[i] = 0; 
         }
      else      
         {
         plusDI_calc_Buffer[i] = 100.0 * pdm / tr;                   //      <--------- Zeile 142
         minusDI_calc_Buffer[i] = 100.0 * mdm / tr; 
         }
      }
      
      for(int i = 0; i <= bars; i++)
      plusDI_Buffer[i]= iMAOnArray(plusDI_calc_Buffer, Bars, ADX_period, 0, MODE_EMA, i);
      
      for(int i = 0; i <= bars; i++)
      minusDI_Buffer[i] = iMAOnArray(minusDI_calc_Buffer, Bars, ADX_period, 0, MODE_EMA, i);
   
     
      for (int i = bars; i >= 0; i--)
      {
      double div = MathAbs(plusDI_Buffer[i] + minusDI_Buffer[i]);
      
      if(div == 0.00) 
         temp_Buffer[i] = 0;
      else 
         temp_Buffer[i] = 100 * (MathAbs(plusDI_Buffer[i] - minusDI_Buffer[i]) / div);
      }
      
//---- ADX is exponential moving average on DX
      for(int i = 0; i < bars; i++)
         ADX_Buffer[i]= iMAOnArray(temp_Buffer, Bars, ADX_period, 0, MODE_EMA, i);

   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Welche Überprüfungen der Handelsroboter vor der Veröffentlichung in Market bestehen soll
Welche Überprüfungen der Handelsroboter vor der Veröffentlichung in Market bestehen soll
  • www.mql5.com
Alle Markets Produkte vor der Veröffentlichung bestehen eine obligatorische vorläufige Überprüfung, da ein kleiner Fehler in der Logik des EAs oder des Indikators zu den Verlusten auf dem Handelskonto führen kann. Gerade deshalb von uns wurde eine Serie der grundlegenden Überprüfungen entwickelt, die das notwendige Niveau der Qualität der...
Dateien:
ADX_-_Test.mq4  13 kb
 
  1. Ersteinmal herzlich Willkommen und gutes Gelingen.
  2. Um die Hilfe etwas leichter zu machen, wäre es schön die Zeile 142 zu kennzeichnen.
  3. Array out of Range passiert oft, wenn dem dynamischen Array keine Größe zugewiesen wurde (ArrayResize(..) oder aber auch durch SetIndexBuffer() (s.o.).
  4. Übrigens, um zu erkennen was welche Funktion macht, einfach den Kursor zB. auf  SetIndexBuffer stellen und F1 drücken.
Welche Überprüfungen der Handelsroboter vor der Veröffentlichung in Market bestehen soll
Welche Überprüfungen der Handelsroboter vor der Veröffentlichung in Market bestehen soll
  • www.mql5.com
Alle Markets Produkte vor der Veröffentlichung bestehen eine obligatorische vorläufige Überprüfung, da ein kleiner Fehler in der Logik des EAs oder des Indikators zu den Verlusten auf dem Handelskonto führen kann. Gerade deshalb von uns wurde eine Serie der grundlegenden Überprüfungen entwickelt, die das notwendige Niveau der Qualität der...
 

Dankeschön, hab die Zeile im Code als Kommentar markiert.

 

Da eingegeben ist:

#property indicator_buffers 3 // <= muss 6 sein

erkennt und behandelt der Indi. nur drei Puffer, die mit den Indices 0,1,2 (ist ein bisschen gewöhnungsbedürftig).

Ich habe aufgehört zu versuchen zu verstehen, ich such bis es funktioniert - im Nachhinein ergibt sich dann doch irgendwie eine Logik.

Dann musst Du die Darstellungsform für jeden Puffer extra angeben, entweder mit #property oder mit Funktionen in OnInit() - such Dir Beispiele aus der Codebase, geht am schnellsten.

Denk Dir, ausschlaggebend sind nicht Deine Ideen, wie es funktionieren müsste/sollte, sonder wie  es von MQ eingerichtet wurde.

 

Alles klar, danke.

habe noch die Zeile

SetIndexStyle(3, DRAW_NONE);

für die Buffer 3, 4 und 5 eingefügt.

Dann hat es funktioniert. Problematisch war allerdings, dass die Werte dann trotzdem im Datenfenster angezeigt wurden.


Das Einfügen der Funktion

 IndicatorBuffers(6);

in der OnInit() hat dann zum gewünschten Ergebnis geführt.

Jetzt muss aber

#property indicator_buffers 3
belassen werden.
 

Um Puffer nicht anzuzeigen gibt es auch eine Funktion:

#property indicator_buffers 6 // zu berechnen
#property indicator_plots   5 // zu zeichnen und zu zeigen

Grund der Beschwerde: