Array Out of Range Error

Einloggen oder registrieren, um einen Kommentar zu schreiben
Ingo Christ
23
Ingo Christ  

Hallo zusammen, 


ich bin zwar lange hier angemeldet aber nun befasse ich mich erst wieder richtig mit MQL  5 und mach Anfängerfehler.
Kann mir jemand hierbei helfen? Der EA lässt sich fehlerfrei kompilieren aber in Zeile 66 beendet er sich beim Teststart mit einem ArrayOutOfRange-Error.
Zeile 66 ist die erste Zeile in der For-Schleife in der OnTick Funktion. 

Ich hoffe, dass das hier das richtige Unterforum ist und bedanke mich im Voraus. 

#property copyright "Copyright 2019, Ingo Christ"
#property link      "https://www.ingochrist.com"
#property version   "1.00"

#include <Trade/Trade.mqh>

input double SupertrendPeriod1 = 14;
input double Multiplier1 = 3;
input double SupertrendPeriod2 = 14;
input double Multiplier2 = 3;

input double LotSize = 0.01;

// EA FUNKTIONIERT BIS JETZT NUR IM M5


int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }


void OnDeinit(const int reason)
  {
//---
   
  }


void OnTick()
{
   bool IsBullish1[];          //true: Super trend is green and below candles, red: the opposite
   double SupertrendValue1[];  

   bool IsBullish2[];          //For higher Timeunit - as a Trendfilter - true: Super trend is green and below candles, red: the opposite
   double SupertrendValue2[];
   
   double PrevLow1[];
   double PrevLow2[];   

   ArraySetAsSeries(SupertrendValue1,true);
   ArraySetAsSeries(IsBullish1,true);
   ArraySetAsSeries(SupertrendValue2,true);
   ArraySetAsSeries(IsBullish2,true);
   ArraySetAsSeries(PrevLow1,true);
   ArraySetAsSeries(PrevLow2,true);
   
   int STHandle1 = iCustom(_Symbol,PERIOD_CURRENT,"\\Eigene\\Supertrend",SupertrendPeriod1,Multiplier1,PRICE_CLOSE);
   CopyBuffer(STHandle1,2,0,3,SupertrendValue1);
   
   int STHandle2 = iCustom(_Symbol,PERIOD_H1,"\\Eigene\\Supertrend",SupertrendPeriod2,Multiplier2,PRICE_CLOSE);
   CopyBuffer(STHandle2,2,0,3,SupertrendValue2);
   
   Comment(SupertrendValue1[1]);
   
   for(int i=0;i<=Bars(_Symbol,PERIOD_M5)-5;i++)   
      {
      PrevLow1[i] = iLow(_Symbol,PERIOD_CURRENT,i+1); //Low of previous Candle on current Timeframe      
      if(PrevLow1[i]>SupertrendValue1[i+1]) IsBullish1[i] = true;
      else {Comment("Bullish/Bearish Error");}
      }
   
   for(int i=0;i<=Bars(_Symbol,PERIOD_H1)-5;i++)  
      {
      PrevLow2[i] = iLow(_Symbol,PERIOD_H1,i+1); //Low of previous Candle on current Timeframe      
      if(PrevLow2[i]>SupertrendValue2[i+1]) IsBullish2[i] = true;
      else {Comment("Bullish/Bearish Error");}
      }
   
   if(IsBullish1[1])Comment("IsBullish1 = true");
   if(IsBullish2[1])Comment("IsBullish2 = true");
}    

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

//ensuring its a new candle
bool IsNewCandle()
      {
      static int BarsOnChart=0;
   
      if(Bars(_Symbol,PERIOD_CURRENT) == BarsOnChart)
      return(false);
      BarsOnChart = Bars(_Symbol,PERIOD_CURRENT);
      return(true);
      }
Carl Schreiber
Moderator
8067
Carl Schreiber  
Du weist keinem Deiner Arrays in OnTick mit ArrayResize() eine Größe zu - dann haben sie die Größe Null und jeder Zugriff erzeugt Dein Fehler.
Otto Pauser
1494
Otto Pauser  

Der Code ist langsam wie Schnecke, da gehört viel in die OnInit() ausgelagert.
Hast wohl zu viel YT Kanal vom R.B angesehen, der nix mit der OnInit() anzufangen weis.

#property copyright "Copyright 2019, Ingo Christ"
#property link      "https://www.ingochrist.com"
#property version   "1.00"

#include <Trade/Trade.mqh>

input double SupertrendPeriod1 = 14;
input double Multiplier1 = 3;
input double SupertrendPeriod2 = 14;
input double Multiplier2 = 3;
input double LotSize = 0.01;

int      STHandle1;
int      STHandle2;
bool     IsBullish1[];          //true: Super trend is green and below candles, red: the opposite
double   SupertrendValue1[];  

bool     IsBullish2[];          //For higher Timeunit - as a Trendfilter - true: Super trend is green and below candles, red: the opposite
double   SupertrendValue2[];

double   PrevLow1[];
double   PrevLow2[];   

int OnInit()
{
   STHandle1 = iCustom(_Symbol,PERIOD_CURRENT,"\\Eigene\\Supertrend",SupertrendPeriod1,Multiplier1,PRICE_CLOSE);
   STHandle2 = iCustom(_Symbol,PERIOD_H1     ,"\\Eigene\\Supertrend",SupertrendPeriod2,Multiplier2,PRICE_CLOSE);
   return(INIT_SUCCEEDED);
   ArraySetAsSeries(SupertrendValue1,true);
   ArraySetAsSeries(IsBullish1,true);
   ArraySetAsSeries(SupertrendValue2,true);
   ArraySetAsSeries(IsBullish2,true);
   ArraySetAsSeries(PrevLow1,true);
   ArraySetAsSeries(PrevLow2,true);
}

Jedes Speicher allozieren in Funktionen kostet Zeit.

Handles zu Indikatoren zu erzeugen kosten extrem viel Zeit.

ArraySetAsSeries() muss nur einmal ausgeführt werden!

Wenn du CopyHigh() und CopyLow() verwendest, brauchst du dich nicht um das Array kümmern. Das machen diese Funktionem selber.

Und die OnDeInit() kannst du weglassen oder mit Comment("") den Kommentar löschen.

Hab ich recht mit dem YT-Kanal? Tät mich interessieren!

Ingo Christ
23
Ingo Christ  

Vielen lieben Dank für die guten Antworten und Tipps. 

Momentan sieht mein Code so aus und wirft den gleichen Fehler aus. 

#include <Trade/Trade.mqh>;

input int MagicNumber = 5527;
input double SupertrendPeriod1 = 14;
input double Multiplier1 = 3;
input double SupertrendPeriod2 = 14;
input double Multiplier2 = 3;

input double TradeVolume = 0.01;

// EA FUNKTIONIERT BIS JETZT NUR IM M5


int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }


void OnDeinit(const int reason)
  {
//---
   
  }


void OnTick()
{
   bool IsBullish1[];          //true: Super trend is green and below candles, red: the opposite
   double SupertrendValue1[];  

   bool IsBullish2[];          //For higher Timeunit - as a Trendfilter - true: Super trend is green and below candles, red: the opposite
   double SupertrendValue2[];
   
   double PrevLow1[];
   double PrevLow2[];   
   
   int  BarsOnChart1 = Bars(Symbol(),PERIOD_M5);
   int  BarsOnChart2 = Bars(Symbol(),PERIOD_H1);

   ArrayResize(SupertrendValue1, BarsOnChart1,10);
   ArrayResize(IsBullish1,BarsOnChart1,10);
   ArrayResize(SupertrendValue2, BarsOnChart2);
   ArrayResize(IsBullish2, BarsOnChart2,10);
   ArrayResize(PrevLow1, BarsOnChart1,10);
   ArrayResize(PrevLow2, BarsOnChart2,10);
   
   ArraySetAsSeries(SupertrendValue1,true);
   ArraySetAsSeries(IsBullish1,true);
   ArraySetAsSeries(SupertrendValue2,true);
   ArraySetAsSeries(IsBullish2,true);
   ArraySetAsSeries(PrevLow1,true);
   ArraySetAsSeries(PrevLow2,true);
     
   int STHandle1 = iCustom(_Symbol,PERIOD_CURRENT,"\\Eigene\\Supertrend",SupertrendPeriod1,Multiplier1,PRICE_CLOSE);
   CopyBuffer(STHandle1,2,0,3,SupertrendValue1);
   
   int STHandle2 = iCustom(_Symbol,PERIOD_H1,"\\Eigene\\Supertrend",SupertrendPeriod2,Multiplier2,PRICE_CLOSE);
   CopyBuffer(STHandle2,2,0,3,SupertrendValue2);
   
   Comment(SupertrendValue1[1]);
    
   for(int i=1;i<BarsOnChart1-10;i++)   
      {
      PrevLow1[i] = iLow(_Symbol,PERIOD_CURRENT,i+1); //Low of previous Candle on current Timeframe      
      if(PrevLow1[i]>SupertrendValue1[i+1]) IsBullish1[i] = 0;
      else {Comment("Bullish/Bearish Error");}
      }
   
   for(int i=0;i<BarsOnChart2-10;i++)  
      {
      PrevLow2[i] = iLow(_Symbol,PERIOD_H1,i+1); //Low of previous Candle on current Timeframe      
      if(PrevLow2[i]>SupertrendValue2[i+1]) IsBullish2[i] = true;
      else {Comment("Bullish/Bearish Error");}
      }
   
   if(IsBullish1[1])Comment("IsBullish1 = true");
   if(IsBullish2[1])Comment("IsBullish2 = true");
}    

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

//ensuring its a new candle
bool IsNewCandle()
      {
      static int BarsOnChart=0;
   
      if(Bars(_Symbol,PERIOD_CURRENT) == BarsOnChart)
      return(false);
      BarsOnChart = Bars(_Symbol,PERIOD_CURRENT);
      return(true);
      }

Ich werde es mit CopyHigh versuchen. Vielen Dank!
Dass der Code mehr als nötig bei jedem Tick macht ist mir inzwischen auch aufgefallen. Er müsste ja z.B. auch nur die letzten Paar Kerzen ansehen und nicht jedes Mal alle. 

Tatsächlich habe ich einiges über YouTube gelernt. Hauptsächlich aber über den Kanal von BM Trading. 
Ich setze die Tipps mal um und poste hier wie es gelaufen ist. 

Ingo Christ
23
Ingo Christ  

Update:

Problem gelöst. Ich hatte bei den Copy...()-Funktionen weniger Werte kopieren lassen, als ich sie in den For-Schleifen habe abfragen lassen. 

Carl Schreiber
Moderator
8067
Carl Schreiber  

Mach es so, wie Otto es gezeigt hat - sonst crasht entweder das Terminal oder Dein PC!

Mit jedem Tick machst Du zwei neue Handle (iCustom) auf ohne sie zu schließen - irgendwann ist es dann vorbei!

Ingo Christ
23
Ingo Christ  

Sooo hier wieder ein Update. 
Ich habe mich an Eure Ratschläge gehalten und viel in die OnInit ausgelagert. 

Vielen Dank!!!

Den Externen Indikator rufe ich nurnoch ab, damit er im Strategietester gezeichnet wird. 
Den Supertrend lasse ich jetzt direkt im EA bestimmen. Das funktioniert leider noch nicht. IsBullish zeigt er mir leider immer falsch an
und gibt deshalb auch den Falschen Suuptertrendwert aus. 
Seht Ihr da den Fehler?

Liebe Grüße

#property copyright "Copyright 2019, Ingo Christ"
#property link      "https://www.ingochrist.com"
#property version   "1.00"


input int MagicNumber = 5527;
input double SupertrendPeriod1 = 14;
input double Multiplier1 = 3;
input int ATRPeriod = 10; 
input double SupertrendPeriod2 = 14;
input double Multiplier2 = 3;

input double TradeVolume = 0.01;

#include <Trade/Trade.mqh>

// EA FUNKTIONIERT BIS JETZT NUR IM M5

bool IsBullish[];
double Supertrend[];

bool IsBullish1[];          //true: Super trend is green and below candles, red: the opposite
double SupertrendValue1[];  

bool IsBullish2[];          //For higher Timeunit - as a Trendfilter - true: Super trend is green and below candles, red: the opposite
double SupertrendValue2[];

int atrHandle;

bool ChangeOfTrend;

int OnInit()
  {
   ArraySetAsSeries(IsBullish1,true);
   ArraySetAsSeries(IsBullish2,true);
   ArraySetAsSeries(IsBullish,true);
   ArraySetAsSeries(Supertrend,true);

   ArrayResize(IsBullish1,20);
   ArrayResize(IsBullish2,20);
   ArrayResize(IsBullish,20);
   ArrayResize(Supertrend,20);
   atrHandle=iATR(_Symbol,_Period,ATRPeriod);
   int STHandle1 = iCustom(_Symbol,PERIOD_CURRENT,"\\Eigene\\Supertrend",SupertrendPeriod1,Multiplier1,false);
   int STHandle2 = iCustom(_Symbol,PERIOD_H1,"\\Eigene\\Supertrend",SupertrendPeriod2,Multiplier2,false);
   
   return(INIT_SUCCEEDED);
  }

void OnTick()
{

   Supertrend(); 
   Comment("Supertrend= ", Supertrend()," IsBullish = ", IsBullish[1]," ChangeOfTrend = ",ChangeOfTrend);    
 /*  if(IsNewCandle())
   {
   Supertrend();
   
   int  BarsOnChart1 = Bars(Symbol(),PERIOD_M5);
   int  BarsOnChart2 = Bars(Symbol(),PERIOD_H1);
   

           
   
   CopyBuffer(STHandle1,2,0,20,SupertrendValue1);
   
   
   CopyBuffer(STHandle2,2,0,20,SupertrendValue2);
   

   }*/   
}    

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

//ensuring its a new candle
bool IsNewCandle()
      {
      static int BarsOnChart=0;
   
      if(Bars(_Symbol,PERIOD_CURRENT) == BarsOnChart)
      return(false);
      BarsOnChart = Bars(_Symbol,PERIOD_CURRENT);
      return(true);
      }
      
double Supertrend()
   { 
   double LowerSupertrend[];
   double LowValues[];
   int LastLowPosition;

   double UpperSupertrend[];
   double HighValues[];
   int LastHighPosition; 
   
   double CloseValues[];
   
   double MiddleValues[];
   
   ArraySetAsSeries(MiddleValues,true);
   ArraySetAsSeries(LowerSupertrend,true);
   ArraySetAsSeries(UpperSupertrend,true);
   
   ArrayResize(MiddleValues,20,20);
   ArrayResize(LowerSupertrend,20,20);
   ArrayResize(UpperSupertrend,20,20);
   
   double ATRValues[];
   CopyBuffer(atrHandle,0,19,SupertrendPeriod1,ATRValues);  

   CopyLow(NULL,PERIOD_M5,0,19,LowValues);
   LastLowPosition = ArrayMinimum(LowValues,0,14);
   
   CopyHigh(NULL,PERIOD_M5,0,19,HighValues);
   LastHighPosition = ArrayMaximum(HighValues,0,14);
   
   CopyClose(NULL,PERIOD_M5,0,19,CloseValues);

   for(int i=1;i<10;i++)
     {
      MiddleValues[i] = (HighValues[i]+LowValues[i])/2;
      LowerSupertrend[i] = MiddleValues[i]-(ATRValues[i]*Multiplier1);
      UpperSupertrend[i] = MiddleValues[i]+(ATRValues[i]*Multiplier1);          
      
      if(CloseValues[i]<LowerSupertrend[i+1] || CloseValues[i]>UpperSupertrend[i+1])
      ChangeOfTrend=true;
      else ChangeOfTrend = false;
      
      if (IsBullish[i+1]==true && CloseValues[i]<LowerSupertrend[i+1])
      IsBullish[i] = false;
      
      if (IsBullish[i+1]==false && CloseValues[i]>UpperSupertrend [i+1])
      IsBullish[i] = true;         
     }
   

   
   if(IsBullish[1]==true)Supertrend[1]=LowerSupertrend[1];
   if(IsBullish[1]==false)Supertrend[1]=UpperSupertrend[1];
   
   return(Supertrend[1]);
   }
/*      
int ExecuteShort()
{
   int ticket;
   ticket = OrderSend(Symbol(),OP_SELL,TradeVolume,Bid,1000,0,0,"Kommentar",MagicNumber,0,clrNONE);
   return ticket;
} 
*/
/*
void OnDeinit(const int reason)
  {
   
  }
*/    
amando
1673
amando  

Du hast ja copybuffer in der ontick auskommentiert, das muss rein


dann musst du schauen, welchen buffer vom indicator du auslesen willst, kenne den indi nicht, aber eventuell hat er mehr buffer

Ingo Christ
23
Ingo Christ  

Danke amando,


Den Buffer, den ich auskommentiert habe brauche ich aber gar nicht mehr. Habe ihn nurnoch im Code, damit der Indikator im Chart beim testen gezeichnet wird.  

Einloggen oder registrieren, um einen Kommentar zu schreiben