EA - Array out of range

 

Hi all,


The below code compiles fine, but comes up with "Array out of range" when implemented in the strategy tester. I've had a look through but I can't figure out why this is happeneing. 


#include <Trade\Trade.mqh>
CTrade  trade;

//--Input Parameters
input int EA_Magic = 123;

//--Bollinger Band Handles
int EMA20_15M_Handle;
int EMA200_15M_Handle;
int Standard_Deviation_20_15M_Handle;
int Standard_Deviation_200_15M_Handle;

int Stochastic_Handle;

double LowerBB_20_15M;
double UpperBB_20_15M;
double LowerBB_200_15M;
double UpperBB_200_15M;

//--Bollinger Band Values
double valEMA20_15M[];
double valEMA200_15M[];
double valStandard_Deviation_20_15M[];
double valStandard_Deviation_200_15M[];

double KArray[];
double DArray[];

//--RSI Handles
int RSI_28_15M_Handle;

//--RSI Values
double valRSI_28_15M[];


//--EMA Handles
int EMA9_15M_Handle;

//--EMA Values
double valEMA9_15M[];
double valEMA200_at_open;

int EMA_crossover_long_positioncount()
   {
   int count = 0;
   for(int x = PositionsTotal(); x >= 0; x--)
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "EMA crossover long")
            {
            count++;
            }
         }
      }
   return(count); 
   }     
   
int EMA_crossover_short_positioncount()
   {
   int count = 0;
   for(int x = PositionsTotal(); x >= 0; x--)
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "EMA crossover short")
            {
            count++;
            }
         }
      }
   return(count);  
   }

//--Open position arrays
double BBands_long_opens[];
double BBands_short_opens[];
double RSI_long_opens[];
double RSI_short_opens[];

int OnInit()
   {
   EMA20_15M_Handle = iMA(_Symbol, PERIOD_M15, 20, 0, 1, PRICE_CLOSE);
   EMA200_15M_Handle = iMA(_Symbol, PERIOD_M15, 200, 0, 1, PRICE_CLOSE);
   EMA9_15M_Handle = iMA(_Symbol, PERIOD_M15, 9, 0, 1, PRICE_CLOSE);
   Standard_Deviation_200_15M_Handle = iStdDev(_Symbol, PERIOD_M15, 200, 0, 1, PRICE_CLOSE);
   Standard_Deviation_20_15M_Handle = iStdDev(_Symbol, PERIOD_M15, 20, 0, 1, PRICE_CLOSE);
   RSI_28_15M_Handle = iRSI(_Symbol, PERIOD_M15, 28, PRICE_CLOSE);
   Stochastic_Handle = iStochastic(_Symbol, PERIOD_M15, 8, 3, 5, MODE_SMA, STO_LOWHIGH);
   return(INIT_SUCCEEDED);
   }
   
void OnDeinit(const int reason)
   {
   IndicatorRelease(EMA20_15M_Handle);
   IndicatorRelease(EMA200_15M_Handle);
   IndicatorRelease(EMA9_15M_Handle);
   IndicatorRelease(Standard_Deviation_200_15M_Handle);
   IndicatorRelease(Standard_Deviation_20_15M_Handle);
   IndicatorRelease(RSI_28_15M_Handle);
   IndicatorRelease(Stochastic_Handle);
   }

void OnTick()
   //--Is there a new bar?
   {
   static datetime Old_Time;
   datetime New_Time[1];
   bool IsNewBar = false;

//--copying the last bar time to the element New_Time[0]
   int copied = CopyTime(_Symbol, PERIOD_M15, 0, 1, New_Time);
   if(copied > 0)
      {
      if(Old_Time!= New_Time[0])
         {
         IsNewBar = true;
         Old_Time = New_Time[0];
         }
      }
   else
      {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
      }

//--- EA should only check for new trade if we have a new bar
   if(IsNewBar == false)
      {
      return;
      }
      
   MqlTick latest_price;
   MqlTradeRequest mrequest;
   MqlTradeResult mresult;
   MqlRates mrates15M[];
   ZeroMemory(mrequest);
   ArraySetAsSeries(mrates15M, true);
   ArraySetAsSeries(valEMA20_15M, true);
   ArraySetAsSeries(valEMA200_15M, true);
   ArraySetAsSeries(valStandard_Deviation_20_15M, true);
   ArraySetAsSeries(valStandard_Deviation_200_15M, true);
   ArraySetAsSeries(KArray, true);
   ArraySetAsSeries(DArray, true);
   ArraySetAsSeries(valRSI_28_15M, true);
   ArraySetAsSeries(valEMA9_15M, true);
   
   SymbolInfoTick(_Symbol, latest_price);
   CopyRates(_Symbol, PERIOD_M15, 0, 2, mrates15M);
   CopyBuffer(EMA20_15M_Handle, 0, 0, 2, valEMA20_15M);
   CopyBuffer(EMA200_15M_Handle, 0, 0, 2, valEMA200_15M);
   CopyBuffer(Standard_Deviation_20_15M_Handle, 0, 0, 2, valStandard_Deviation_20_15M);
   CopyBuffer(Standard_Deviation_200_15M_Handle, 0, 0, 2, valStandard_Deviation_200_15M);
   CopyBuffer(Stochastic_Handle, 0, 0, 2, KArray);
   CopyBuffer(Stochastic_Handle, 1, 0, 2, DArray);
   CopyBuffer(RSI_28_15M_Handle, 0, 0, 2, valRSI_28_15M);
   CopyBuffer(EMA9_15M_Handle, 0, 0, 2, valEMA9_15M);
   
//--Ask and Bid
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
   double Spread = Ask - Bid;

//--BB calcs
   LowerBB_20_15M = valEMA20_15M[1] - (2 * valStandard_Deviation_20_15M[1]);
   UpperBB_20_15M = valEMA20_15M[1] + (2 * valStandard_Deviation_20_15M[1]);
   LowerBB_200_15M = valEMA200_15M[1] - (0.5 * valStandard_Deviation_200_15M[1]);
   UpperBB_200_15M = valEMA200_15M[1] + (0.5 * valStandard_Deviation_200_15M[1]);
   
//--Price details of previous candle
   double p_close = mrates15M[1].close;
   double p_open = mrates15M[1].open;

//-----------------------------------------------------------------------------------------------------------------------
//--TRADE CONDITIONS

//--BBand long conditions
   bool BBand_long_condition_1 = p_close < valEMA200_15M[1];
   bool BBand_long_condition_2 = p_close < p_open;
   
   for(int x=PositionsTotal(); x >= 0; x--)  
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "BBands long")
            {
            ArrayResize(BBands_long_opens, PositionsTotal(), 0);
            BBands_long_opens[x] = PositionGetDouble(POSITION_PRICE_OPEN);
            }
         }
      } 
   
   bool BBand_long_condition_3 = p_close < BBands_long_opens[ArrayMinimum(BBands_long_opens, 0, WHOLE_ARRAY)];
   bool BBand_long_condition_4 = p_close < LowerBB_20_15M;
   
//--BBand short conditions
   bool BBand_short_condition_1 = p_close > valEMA200_15M[1];
   bool BBand_short_condition_2 = p_close > p_open;
   
   for(int x=PositionsTotal(); x >= 0; x--)  
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "BBands short")
            {
            ArrayResize(BBands_short_opens, PositionsTotal(), 0);
            BBands_short_opens[x] = PositionGetDouble(POSITION_PRICE_OPEN);
            }
         }
      }    
   
   bool BBand_short_condition_3 = p_close > BBands_short_opens[ArrayMaximum(BBands_short_opens, 0, WHOLE_ARRAY)];
   bool BBand_short_condition_4 = p_close > UpperBB_20_15M;
   
//--RSI long conditions
   bool RSI_long_condition_1 = p_close < p_open;
   bool RSI_long_condition_2 = valRSI_28_15M[1] < 30;
   
   for(int x=PositionsTotal(); x >= 0; x--)  
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "RSI long")
            {
            ArrayResize(RSI_long_opens, PositionsTotal(), 0);
            RSI_long_opens[x] = PositionGetDouble(POSITION_PRICE_OPEN);
            }
         }
      }   
   
   bool RSI_long_condition_3 = p_close < RSI_long_opens[ArrayMinimum(RSI_long_opens, 0, WHOLE_ARRAY)];
   
//--RSI short conditions
   bool RSI_short_condition_1 = p_close > p_open;
   bool RSI_short_condition_2 = valRSI_28_15M[1] > 70;
   
   for(int x=PositionsTotal(); x >= 0; x--)  
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "RSI short")
            {
            ArrayResize(RSI_short_opens, PositionsTotal(), 0);
            RSI_short_opens[x] = PositionGetDouble(POSITION_PRICE_OPEN);
            }
         }
      }    

   bool RSI_short_condition_3 = p_close > RSI_short_opens[ArrayMaximum(RSI_short_opens, 0, WHOLE_ARRAY)];

//--EMA crossover long conditions
   bool EMA_crossover_long_condition_1 = valEMA9_15M[2] < valEMA20_15M[2];
   bool EMA_crossover_long_condition_2 = valEMA9_15M[1] > valEMA20_15M[1];
   bool EMA_crossover_long_condition_3 = p_close > valEMA200_15M[1];
   bool EMA_crossover_long_condition_4 = EMA_crossover_long_positioncount() == 0;
   
//--EMA crossover short conditions
   bool EMA_crossover_short_condition_1 = valEMA9_15M[2] > valEMA20_15M[2];
   bool EMA_crossover_short_condition_2 = valEMA9_15M[1] < valEMA20_15M[2];
   bool EMA_crossover_short_condition_3 = p_close < valEMA200_15M[1];  
   bool EMA_crossover_short_condition_4 = EMA_crossover_short_positioncount() == 0;
   
//-----------------------------------------------------------------------------------------------------------------------
//--TRADE ENTRY COMMANDS

//--BBand entry commands
   if(IsNewBar)
      {
      if(BBand_long_condition_1 && BBand_long_condition_2)
         {
         if(BBand_long_condition_3 && BBand_long_condition_4)  
            {
            trade.Buy(0.01, NULL, Bid, 0, valEMA200_15M[0], "BBands long");
            }
         } 
      }

   if(IsNewBar)
      {
      if(BBand_short_condition_1 && BBand_short_condition_2)
         {
         if(BBand_short_condition_3 && BBand_short_condition_4)
            {
            trade.Sell(0.01, NULL, Ask, 0, valEMA200_15M[0], "BBands short");
            }
         }
      }
      
//--RSI entry commands
   if(IsNewBar)
      {
      if(RSI_long_condition_1 && RSI_long_condition_2)
         {
         if(RSI_long_condition_3)
            {
            trade.Buy(0.01, NULL, Bid, 0, valEMA200_15M[0], "RSI long");
            }
         }
      }

   if(IsNewBar)
      {
      if(RSI_short_condition_1 && RSI_short_condition_2)
         {
         if(RSI_short_condition_3)
            {
            trade.Sell(0.01, NULL, Ask, 0, valEMA200_15M[0], "RSI long");
            }
         }
      }

//--EMA crossover entry commands
   if(IsNewBar)
      {
      if(EMA_crossover_long_condition_1 && EMA_crossover_long_condition_2)
         {
         if(EMA_crossover_long_condition_3 && EMA_crossover_long_condition_4)
            {
            trade.Buy(0.01, NULL, Bid, 0, 0, "EMA crossover long");
            valEMA200_at_open = valEMA200_15M[1];
            }
         }
      }
      
   if(IsNewBar)
      {
      if(EMA_crossover_short_condition_1 && EMA_crossover_short_condition_2)
         {
         if(EMA_crossover_short_condition_3 && EMA_crossover_short_condition_4)
            {
            trade.Sell(0.01, NULL, Ask, 0, 0, "EMA crossover short");
            valEMA200_at_open = valEMA200_15M[1];
            }
         }
      }
      
//-----------------------------------------------------------------------------------------------------------------------
//--TRADE MODIFIERS

//--BBand trade modifiers
   if(IsNewBar)
      {
      for(int x = PositionsTotal(); x >= 0; x--)
         {
         ulong current_ticket = PositionGetTicket(x);
         if(PositionSelectByTicket(current_ticket))
            {
            if(PositionGetString(POSITION_COMMENT) == "BBands long")
               {
               trade.PositionModify(current_ticket, 0, valEMA200_15M[0]);
               }
            }
         }
      }
      
   if(IsNewBar)
      {
      for(int x = PositionsTotal(); x >= 0; x--)
         {
         ulong current_ticket = PositionGetTicket(x);
         if(PositionSelectByTicket(current_ticket))
            {
            if(PositionGetString(POSITION_COMMENT) == "BBands short")
               {
               trade.PositionModify(current_ticket, 0, valEMA200_15M[0]);
               }
            }
         }
      }
      
//--RSI trade modifiers
   if(IsNewBar)
      {
      for(int x = PositionsTotal(); x >= 0; x--)
         {
         ulong current_ticket = PositionGetTicket(x);
         if(PositionSelectByTicket(current_ticket))
            {
            if(PositionGetString(POSITION_COMMENT) == "RSI long")
               {
               trade.PositionModify(current_ticket, 0, valEMA200_15M[0]);
               }
            }
         }
      }
      
   if(IsNewBar)
      {
      for(int x = PositionsTotal(); x >= 0; x--)
         {
         ulong current_ticket = PositionGetTicket(x);
         if(PositionSelectByTicket(current_ticket))
            {
            if(PositionGetString(POSITION_COMMENT) == "RSI short")
               {
               trade.PositionModify(current_ticket, 0, valEMA200_15M[0]);
               }
            }
         }
      }
      
//--EMA crossover trade modifiers
/* 
   -Get position profit
   -Get val200EMA at the time of the position opening
   -Adjust stop accordingly
*/  

   for(int x = PositionsTotal(); x >= 0; x--)
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "EMA crossover long")
            {
            if((PositionGetDouble(POSITION_PRICE_CURRENT) - PositionGetDouble(POSITION_PRICE_OPEN)) >= (PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open) * 1.5)
               {
               trade.PositionModify(current_ticket, 0, (PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open));
               }
            }
         }
      }

   for(int x = PositionsTotal(); x >= 0; x--)
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "EMA crossover long")
            {
            if((PositionGetDouble(POSITION_PRICE_CURRENT) - PositionGetDouble(POSITION_PRICE_OPEN)) >= (PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open) * 2.5)
               {
               trade.PositionModify(current_ticket, 0, ((PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open)) * 1.5);
               }
            }
         }
      }

   for(int x = PositionsTotal(); x >= 0; x--)
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "EMA crossover long")
            {
            if((PositionGetDouble(POSITION_PRICE_CURRENT) - PositionGetDouble(POSITION_PRICE_OPEN)) >= (PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open) * 3.5)
               {
               trade.PositionModify(current_ticket, 0, ((PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open)) * 2.5);
               }
            }
         }
      }     

   for(int x = PositionsTotal(); x >= 0; x--)
      {
      ulong current_ticket = PositionGetTicket(x);
      if(PositionSelectByTicket(current_ticket))
         {
         if(PositionGetString(POSITION_COMMENT) == "EMA crossover long")
            {
            if((PositionGetDouble(POSITION_PRICE_CURRENT) - PositionGetDouble(POSITION_PRICE_OPEN)) >= (PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open) * 4.5)
               {
               trade.PositionModify(current_ticket, (PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open) * 3.5, (PositionGetDouble(POSITION_PRICE_OPEN) - valEMA200_at_open) * 5);
               }
            }
         }
      } 

//-----------------------------------------------------------------------------------------------------------------------
//--TRADE CLOSERS
//--For mean reversions, close on stochastic crossovers with 0.5 Std. Devs. of 200 EMA
//--For EMA crossovers, close if price closes above 20 EMA     

//--Mean reversion long closers
   if(IsNewBar)
      {
      if(KArray[2] > 80 && DArray[2] > 80)
         {
         if(KArray[2] < DArray[2] && KArray[1] > DArray[1])
            {
            if(p_close > LowerBB_200_15M)
               {
               for(int x = PositionsTotal(); x >= 0; x--)
                  {
                  ulong current_ticket = PositionGetTicket(x);
                  if(PositionSelectByTicket(current_ticket))
                     {
                     if(PositionGetString(POSITION_COMMENT) == "BBands long")
                        {
                        trade.PositionClose(current_ticket, -1);
                        }
                     }
                  }
               }
            }
         }
      }
   
   if(IsNewBar)
      {
      if(KArray[2] > 80 && DArray[2] > 80)
         {
         if(KArray[2] < DArray[2] && KArray[1] > DArray[1])
            {
            if(valEMA200_15M[0] > p_close > LowerBB_200_15M)
               {
               for(int x = PositionsTotal(); x >= 0; x--)
                  {
                  ulong current_ticket = PositionGetTicket(x);
                  if(PositionSelectByTicket(current_ticket))
                     {
                     if(PositionGetString(POSITION_COMMENT) == "RSI long")
                        {
                        trade.PositionClose(current_ticket, -1);
                        }
                     }
                  }
               }
            }
         }
      }
      
//--Mean reversion short closers
   if(IsNewBar)
      {
      if(KArray[2] < 20 && DArray[2] < 20)
         {
         if(KArray[2] > DArray[2] && KArray[1] < DArray[1])
            {
            if(valEMA200_15M[0] < p_close < UpperBB_200_15M)
               {
               for(int x = PositionsTotal(); x >= 0; x--)
                  {
                  ulong current_ticket = PositionGetTicket(x);
                  if(PositionSelectByTicket(current_ticket))
                     {
                     if(PositionGetString(POSITION_COMMENT) == "BBands short")
                        {
                        trade.PositionClose(current_ticket, -1);
                        }
                     }
                  }
               }
            }
         }
      }   
         
   if(IsNewBar)
      {
      if(KArray[2] < 20 && DArray[2] < 20)
         {
         if(KArray[2] > DArray[2] && KArray[1] < DArray[1])
            {
            if(valEMA200_15M[0] < p_close < UpperBB_200_15M)
               {
               for(int x = PositionsTotal(); x >= 0; x--)
                  {
                  ulong current_ticket = PositionGetTicket(x);
                  if(PositionSelectByTicket(current_ticket))
                     {
                     if(PositionGetString(POSITION_COMMENT) == "RSI short")
                        {
                        trade.PositionClose(current_ticket, -1);
                        }
                     }
                  }
               }
            }
         }
      }
      
//--EMA crossover long closers
   if(IsNewBar)
      {
      if(p_close < valEMA200_15M[1])
         {
         for(int x = PositionsTotal(); x >= 0; x--)
            {
            ulong current_ticket = PositionGetTicket(x);
            if(PositionSelectByTicket(current_ticket))
               {
               if(PositionGetString(POSITION_COMMENT) == "EMA crossover long")
                  {
                  trade.PositionClose(current_ticket, -1);
                  }
               }
            }
         }
      }
      
   if(IsNewBar)
      {
      if(p_close > valEMA200_15M[1])
         {
         for(int x = PositionsTotal(); x >= 0; x--)
            {
            ulong current_ticket = PositionGetTicket(x);
            if(PositionSelectByTicket(current_ticket))
               {
               if(PositionGetString(POSITION_COMMENT) == "EMA crossover short")
                  {
                  trade.PositionClose(current_ticket, -1);
                  }
               }
            }
         }
      }     
      
      
   
   }
 

Finding an error is easy.

As soon as we got the error window:


click 'OK' and you get to the line with the error:


 
Vladimir Karputov:

Finding an error is easy.

As soon as we got the error window:


click 'OK' and you get to the line with the error:


Hmmm, it doesn't seem to take me to the line with the error after I click OK. Thanks for your help anyway.

 
//--Bollinger Band Values
double valEMA20_15M[];
double valEMA200_15M[];
double valStandard_Deviation_20_15M[];
double valStandard_Deviation_200_15M[];

The problem may be because the nowhere is the size of these arrays defined. So when you do CopyBuffer, it copies into a void.

Possibly try the following and see what happens:

//--Bollinger Band Values
double valEMA20_15M[3];
double valEMA200_15M[3];
double valStandard_Deviation_20_15M[3];
double valStandard_Deviation_200_15M[3];

Check other arrays that store indicator values for their sizing, too.