Komischer "array out of range" - Fehler beim Indikator Buffer

 

Hallo,

manchmal sieht man den Wald vor lauter Bäumen nicht :-(
So erhalte ich bei meinem MTF Indikator einen "array out of range" -Error und zwar wenn ich in den Indikator-Buffer schreiben möchte.

int counted_bars = IndicatorCounted();
int iBS;  
int limit = Bars-counted_bars;
for(int i = limit; i>=0; i--)
{ 
      if
        ...
      else if(iPeriod == 60 && i<(iBars(Symbol(),PERIOD_H1)-VarArray[4][1]-1))
         {     
            SetIndexStyle(4,DRAW_LINE,StyleH1,WidthH1,clrRed);                 
                     
            if(iPeriod >= Period())
            { 
               iBS = iBarShift(NULL, iPeriod, Time[i]); 
               H1_MA1[i] = iMA(NULL,iPeriod,(int)VarArray[4][1],0,MODE_EMA,PRICE_CLOSE,iBS);
               ...
            }
         }
}


Der Fehler tritt leider nicht nachvollziehbar auf. So habe ich z.B. folgendes Verhalten beobachtet:
Ich habe H1 aktiviert, in allen Timeframes größer H1 hat der Indikator keine Probleme. Wenn ich auf H1 schalte heißt es dann "array out of range"; komischerweise nicht immer.

Wenn ich z.B. meinen Chart von D1 auf H4 dann H1 schalte funktioniert es. Wenn ich im Indikator H1 aktiviere und den Indikator gleich auf H1 ziehe, bekomme ich die Fehlermeldung.

Ist in diesem Codeabschnitt ein Fehler bzw. kann ich vor dem Füllen des Indikator-Buffers prüfen, ob das Array an der Stelle "existiert"?

 

Ich vermute, dass die Größe der Arrays nicht oder falsch gesetzt sind.

Um das zu erkennen hilft a) die wichtigen Parameter auszudrucken oder b) mit Comment() anzuzeigen.

Comment() (mit Zeilennummer) hat den Vorteil, dass die letzte Meldung vor dem Fehler stehen bleibt.

Oder man nimmt c) den Debugger..
 
Du fragst Indikatordaten zu mehreren Timeframes ab. Sobald Dein Indikator aufgerufen wird, ist nur garantiert, dass Kursdaten zum aktuellen Timeframe vorliegen. Kursdaten anderer Timeframes können, müssen aber nicht vorliegen. Je nachdem ob diese Daten im Hintergrund bereits geladen wurden oder nicht ergibt sich daraus, dass z.B. iBarShift oder iMA mal gehen und mal nicht. Das könnte dann den Index-Fehler verursachen.
 

Vielen Dank für die Erklärung! Das passt auch mit dem eigenartigen Verhalten beim Testen zusammen. Mich wundert es etwas, da ich auch bislang MTF Indikatoren in dieser Art und Weise programmiert habe und bislang eigentlich keine Probleme hatte!

Gibt es einen Weg / eine Abfrage, die den Absturz verhindern kann (- auch wenn die Werte dann icht komplett angezeigt werden)?

Oder könnte ich sie z.B. in der Init berechnen lassen?

 

Zumindest den Returnwert von iBarShift würde ich abfragen.

ResetLastError();
int iBS=iBarShift(...);
if(iBS<0)
  {
   // error, examine cause
   if(_LastError==ERR_HISTORY_NOT_FOUND) 
     {
      // try again later
      return 0;
     }
   ...
  }

Ich gehe davon aus, dass Du das OnCalculate() verwendest, obwohl der Code oben schon irgendwie old-style wirkt. Daher Rückgabe von 0 als nächsten Wert für prev_calculated.

 
sunshineh:

Ist in diesem Codeabschnitt ein Fehler bzw. kann ich vor dem Füllen des Indikator-Buffers prüfen, ob das Array an der Stelle "existiert"?

Geht mit:

https://www.mql5.com/en/docs/array/arrayrange

void OnStart()
  {
//--- create four-dimensional array
   double array[][5][2][4];
//--- set the size of the zero dimension
   ArrayResize(array,10,10);
//--- print dimensions
   int temp;
   for(int i=0;i<4;i++)
     {
      //--- receive the size of i dimension
      temp=ArrayRange(array,i);
      //--- print
      PrintFormat("dim = %d, range = %d",i,temp);
     }
//--- Result
// dim = 0, range = 10
// dim = 1, range = 5
// dim = 2, range = 2
// dim = 3, range = 4
  }

Sinnvoller Platz für DebugBreak() ist in der Klammer nach negativer Prüfung mit ArrayRange()

Gruß

Documentation on MQL5: Array Functions / ArrayRange
Documentation on MQL5: Array Functions / ArrayRange
  • www.mql5.com
Array Functions / ArrayRange - Reference on algorithmic/automated trading language for MetaTrader 5