An array is out of range

 

Hello!

 I'm quite new to MQL and rarely use forums for my programing, but since I had such plesant time when last time I used a forum, I thought I might try.

 So I'm trying to make a quite simple EA, just to try out myself and hopefully I will be able to keep up with my friend ideas about how to make a profitable one. I made what I could, and I think it should work well enough (apart from not being able to handle a different sell and buy position on the same symbol, would 2 different magick number help? sorry back to track...)  but I seems to run in to a "usual" array sizeing problem i guess. I dont get anything on debugging but when I try to start my EA I get an array out of reach in 'EA1'(x,y).

 I think I'm using dynamic arrays so not sure how this happend but please feel free to lecture me if I'm doing anything stupid here.

 I tried to comment out every line where an array is sued but nothing (probably missed one)

Does any of you see something? (also If I understand correctly, the ontick function is called when ever there is a price change right? not just with new bars, I'm sorry I know that I should really just put one question to a thread not three but the other two should be basic for anyone who understand mql5 on some level, sorry if code is bit spagetthi, haven't programmed for like a year....)

 

Thanks for the insight and the help! Have a nice day :) 

void OnTick
{
//trades open?-----------------------------------------
   bool Buy_opened=false;  
   bool Sell_opened=false;
   
    if(PositionSelect(Symbol)==true) // we have an opened position
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_opened=true;  //It is a Buy
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_opened=true; // It is a Sell
        }
     }
   
  //-----------------------------------------------------
  //watching for new bars--------------------------------
      static datetime Old_Time = TimeCurrent();
      //Miért volt itt a példában static? static nem bassza el újra indításnál?
      datetime New_Time[1];
      bool IsNewBar=false;
      
  int CopiedTime=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(CopiedTime>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time. 1970? Nope 
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
         p_high[0]=0;//ZeroMemory(p_high);
         p_low[0]=0;//ZeroMemory(p_low);
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }
     
   MqlTick last_tick;      
   MqlTradeRequest mrequest;  
   MqlTradeResult mresult;    
   MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   ZeroMemory(mrequest);      // wiping of mrequest structure
   
   ArraySetAsSeries(mrate,true);
   ArraySetAsSeries(p_high,true);
   ArraySetAsSeries(p_low,true);
   //ArrayFree
   //ArrayInitialize
   
   if(IsNewBar=true)
   {
   p_close = mrate[1].close;
   }
   else
   {
   p_close = 0;
   }

   int copied=SymbolInfoTick(Symbol,last_tick);
  
   if(copied && IsNewBar)
      {
      p_high[0] = last_tick.bid; //bid ha veszünk
      p_low[0] = last_tick.ask; //ask ha eladunk
      }
   
   if(last_tick.bid>p_high[0])
      {
      p_high[0]=last_tick.bid;
      }
   
   if(last_tick.ask<p_low[0])
      {
      p_low[0]=last_tick.ask;
      }
   
   bool BuyCondition = (p_high[0] = p_close);
   bool SellCondition = (p_low[0] = p_close);
   
   if(BuyCondition && !Buy_opened && !Sell_opened) //ORDER TIMEEEE!!!
   {
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(last_tick.bid,_Digits);           // latest ask price
         mrequest.sl = NormalizeDouble(last_tick.bid - STP*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(last_tick.bid + TKP*_Point,_Digits); // Take Profit
         mrequest.symbol = Symbol;                                            // currency pair
         mrequest.volume = Lot;                                                 // number of lots to trade
         mrequest.magic = EA_Magic;                                             // Order Magic Number
         mrequest.type = ORDER_TYPE_BUY;                                        // Buy Order
         mrequest.type_filling = ORDER_FILLING_FOK;                             // Order execution type
         mrequest.deviation=100;                                                // Deviation from current price
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed according to a lovely post
           {
            Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
    }
 
   if(SellCondition && !Buy_opened && !Sell_opened) //ORDER TIMEEEE!!!
   {
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(last_tick.ask,_Digits);           // latest ask price
         mrequest.sl = NormalizeDouble(last_tick.ask - STP*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(last_tick.ask + TKP*_Point,_Digits); // Take Profit
         mrequest.symbol = Symbol;                                            // currency pair
         mrequest.volume = Lot;                                                 // number of lots to trade
         mrequest.magic = EA_Magic;                                             // Order Magic Number
         mrequest.type = ORDER_TYPE_SELL;                                        // Sell Order
         mrequest.type_filling = ORDER_FILLING_FOK;                             // Order execution type
         mrequest.deviation=100;                                                // Deviation from current price
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
    }
}
 
A dynamic array means you can change its size, not it will size automatically. You have to use ArrayResize() on p_high, p_low.
 
Alain Verleyen:
A dynamic array means you can change its size, not it will size automatically. You have to use ArrayResize() on p_high, p_low.

Of course!! Thank you!

 The page on the link you gave, shows an example in the OnInit function, but can I somehow make it in the onTick function? Since I would like to refresh the array size on every tick with one, so it would grow as long as its needed, and "wipe" them on every new Bar.

I wouldn't say that the OnTick is like a for cycle but its called on everythick, so I belive I can use something like this:

  int i=0;
  i++;
  ArrayResize(p_high,i,i);
  ArrayResize(p_low,i,i);

 On the start of the OnInit.

I'm not sure if what I'm doing is bad, but when I try to run my EA its pop a masseage window (or alert window) about array size instead of just write it on the expert tab. And then It jumps to this part of the code with a break point at the mrate (which I havent put there).

   if(IsNewBar=true)
   {
   p_close = mrate[1].close;
   }

 Should I resize the mrate as well? (I "copied" an EA for practice, thanks to the creator of that article) There was no problem of mrate size.

 I will try to figure this out myself but I'm not to confident right now, but If i figure it out I post my results.

 Thanks again for the help! 

 
Please post the full code if you need help.
 
Alain Verleyen:
Please post the full code if you need help.
Sorry, here is the full code: (edit: I left the ArrayResize part on the oninit, because just now I started to play with the array resizin on the initialization, but I would like it more in the OnTick)
int OnInit()
  {
  // So we can change SL or TP
   STP = StopLoss;
   TKP = TakeProfit;
   //Ezt itt másoltam, és nem értem miért.... Edőcs?
    if(_Digits==5 || _Digits==3)
     {
      STP = STP*10;
      TKP = TKP*10;
     }
//Setting arraysize----------------------------------------------------

for(int i=1;i<=300000;i++)
     {
     ArrayResize(p_high,i,3000000);
     }
for(int i=1;i<=300000;i++)
     {
     ArrayResize(p_low,i,300000);
     }
//---------------------------------------------------------------------  
//object for receiving symbol settings
   CSymbolInfo symbol_info;
//set the name for the appropriate symbol
   symbol_info.Name(Symbol);
//receive current rates and display
   symbol_info.RefreshRates();
   Print(symbol_info.Name()," (",symbol_info.Description(),")",
         "  Bid=",symbol_info.Bid(),"   Ask=",symbol_info.Ask());
//receive minimum freeze levels for trade operations
   Print("StopsLevel=",symbol_info.StopsLevel()," pips, FreezeLevel=",
         symbol_info.FreezeLevel()," pips");
//receive the number of decimal places and point size
   Print("Digits=",symbol_info.Digits(),
         ", Point=",DoubleToString(symbol_info.Point(),symbol_info.Digits()));
//spread info
   Print("SpreadFloat=",symbol_info.SpreadFloat(),", Spread(current)=",
         symbol_info.Spread()," pips");
//request order execution type for limitations
   Print("Limitations for trade operations: ",EnumToString(symbol_info.TradeMode()),
         " (",symbol_info.TradeModeDescription(),")");
//clarifying trades execution mode
   Print("Trades execution mode: ",EnumToString(symbol_info.TradeExecution()),
         " (",symbol_info.TradeExecutionDescription(),")");
//clarifying contracts price calculation method
   Print("Contract price calculation: ",EnumToString(symbol_info.TradeCalcMode()),
         " (",symbol_info.TradeCalcModeDescription(),")");
//sizes of contracts
   Print("Standard contract size: ",symbol_info.ContractSize(),
         " (",symbol_info.CurrencyBase(),")");
//minimum and maximum volumes in trade operations
   Print("Volume info: LotsMin=",symbol_info.LotsMin(),"  LotsMax=",symbol_info.LotsMax(),
         "  LotsStep=",symbol_info.LotsStep());
   Print("Initialization completed");

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  int i=0;
  i++;
  ArrayResize(p_high,i,i);
  ArrayResize(p_low,i,i);


  //trades open?-----------------------------------------
   bool Buy_opened=false;  
   bool Sell_opened=false;
   
    if(PositionSelect(Symbol)==true) // we have an opened position
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_opened=true;  //It is a Buy
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_opened=true; // It is a Sell
        }
     }
   
  //-----------------------------------------------------

  //watching for new bars--------------------------------
      static datetime Old_Time = TimeCurrent();
      //Miért volt itt a példában static? static nem bassza el újra indításnál?
      datetime New_Time[1];
      bool IsNewBar=false;
      
  int CopiedTime=CopyTime(_Symbol,_Period,0,1,New_Time);
   if(CopiedTime>0) // ok, the data has been copied successfully
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time. 1970? Nope 
        {
         IsNewBar=true;   // if it isn't a first call, the new bar has appeared
         if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
         Old_Time=New_Time[0];            // saving bar time
         p_high[0]=0;//ZeroMemory(p_high);
         p_low[0]=0;//ZeroMemory(p_low);
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      return;
     }
     
   MqlTick last_tick;      
   MqlTradeRequest mrequest;  
   MqlTradeResult mresult;    
   MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   ZeroMemory(mrequest);      // wiping of mrequest structure
   
   ArraySetAsSeries(mrate,true);
   ArraySetAsSeries(p_high,true);
   ArraySetAsSeries(p_low,true);
   ArrayResize(p_high,i,i);
   ArrayResize(p_low,i,i);
   ArrayResize(mrate,i,i);
   if(IsNewBar=true)
   {
   p_close = mrate[1].close;
   }
   else
   {
   p_close = 0;
   }

   int copied=SymbolInfoTick(Symbol,last_tick);
  
   if(copied && IsNewBar)
      {
      p_high[0] = last_tick.bid; //bid ha veszünk
      p_low[0] = last_tick.ask; //ask ha eladunk
      }
   
   if(last_tick.bid>p_high[0])
      {
      p_high[0]=last_tick.bid;
      }
   
   if(last_tick.ask<p_low[0])
      {
      p_low[0]=last_tick.ask;
      }
   
   bool BuyCondition = (p_high[0] = p_close);
   bool SellCondition = (p_low[0] = p_close);
   
   if(BuyCondition && !Buy_opened && !Sell_opened) //ORDER TIMEEEE!!!
   {
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(last_tick.bid,_Digits);           // latest ask price
         mrequest.sl = NormalizeDouble(last_tick.bid - STP*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(last_tick.bid + TKP*_Point,_Digits); // Take Profit
         mrequest.symbol = Symbol;                                            // currency pair
         mrequest.volume = Lot;                                                 // number of lots to trade
         mrequest.magic = EA_Magic;                                             // Order Magic Number
         mrequest.type = ORDER_TYPE_BUY;                                        // Buy Order
         mrequest.type_filling = ORDER_FILLING_FOK;                             // Order execution type
         mrequest.deviation=100;                                                // Deviation from current price
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed according to a lovely post
           {
            Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
    }
 
   if(SellCondition && !Buy_opened && !Sell_opened) //ORDER TIMEEEE!!!
   {
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // immediate order execution
         mrequest.price = NormalizeDouble(last_tick.ask,_Digits);           // latest ask price
         mrequest.sl = NormalizeDouble(last_tick.ask - STP*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(last_tick.ask + TKP*_Point,_Digits); // Take Profit
         mrequest.symbol = Symbol;                                            // currency pair
         mrequest.volume = Lot;                                                 // number of lots to trade
         mrequest.magic = EA_Magic;                                             // Order Magic Number
         mrequest.type = ORDER_TYPE_SELL;                                        // Sell Order
         mrequest.type_filling = ORDER_FILLING_FOK;                             // Order execution type
         mrequest.deviation=100;                                                // Deviation from current price
         //--- send order
         OrderSend(mrequest,mresult);
         // get the result code
         if(mresult.retcode==10009 || mresult.retcode==10008) //Request is completed or order placed
           {
            Alert("A Buy order has been successfully placed with Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("The Buy order request could not be completed -error:",GetLastError());
            ResetLastError();           
            return;
           }
    }
  
   
   
   
   
  }
 
GergelyB:
Sorry, here is the full code: (edit: I left the ArrayResize part on the oninit, because just now I started to play with the array resizin on the initialization, but I would like it more in the OnTick)
  int i=0;
  i++;
  ArrayResize(p_high,i,i);
  ArrayResize(p_low,i,i);

This makes no sense, first you declare int i and set it to zero.

Then you add 1 to it ++ on a new tick.

But on the next tick you (re)set it back to

int i=0;

zero again and

 i++;

you add one to it again...

int i will never be more then 1 on the first incoming tick.

 
Marco vd Heijden:

This makes no sense, first you declare int i and set it to zero.

Then you add 1 to it ++ on a new tick.

But on the next tick you set it back to

zero again and

you add one to it again...

int i will never be more then 1 on the first incoming tick.

True enough, sorry I haven't coded for a while and thats why I make such rookie mistakes... I moved int i =0 next to the input parameters as a global variable (If I recall this is how they are called) so it can be reached from everywhere, and left the rest as it is. This seems to solve the array size problem.

It seems now my EA would like to place an order wich fails with error 4756.

I try to figure out why is that (and why my EA tries to place a buy when It shouldn't do it, but I need to check OrderSend for that) 

 

Edit: Actually no, I still have the problem with the array size, just for some reason  it tried to open a position first for some reasons....

 
for(int i=1;i<=300000;i++)
     {
     ArrayResize(p_high,i,3000000);
     }
for(int i=1;i<=300000;i++)
     {
     ArrayResize(p_low,i,300000);
     }

What's that ? Are you trying to crash your MT4 ? :-D

 

I think sharing with you my goal would help this a lot.

 I would like to identify the bars where ther last price is the highest or lowest in the bar (basicly that means in a japancandelstick graph that there is no little "wick"? or how its called on the top or bottom of the candle, coming to the conclusion that the market is on a up or down trend respectively (at least for the next few ticks) and I try to use zeromemory if i find newbars.

Opening the position and close it shortly after (with relativly low take profit) 

 
Alain Verleyen:

What's that ? Are you trying to crash your MT4 ? :-D

I'm using mql5

 No, in arraysize example it said that the max size is something 2147483647.  I just made these from the example, I left that in as a mistake basicly. Didn't really understand the 3. variable reserve_size in ArrayResize, its for to preoccupy the memory for the array right?

Edit: I thought that in a longer periodicity there could be a lot of thick in one bar, still not sure why this would crash the  terminal.

 
GergelyB:

I'm using mql5. 

 No, in arraysize example it said that the max size is something 2147483647.  I just made these from the example, I left that in as a mistake basicly. Didn't really understand the 3. variable reserve_size in ArrayResize, its for to preoccupy the memory for the array right?

Edit: I thought that in a longer periodicity there could be a lot of thick in one bar, still not sure why this would crash the  terminal.

Of course I mean MT5.

If you need an array with 300,000 items, just use :

ArrayResize(myarray,300000);

If you need to add an item on each tick without knowing how much, use :

ArrayResize(myarray,ArraySize(myarray)+1);

but this is very inefficient, as the memory will re-allocate memory for the array on each item.

So you should use something like :

ArrayResize(myarray,ArraySize(myarray)+1,1000);

This way memory will be re-allocated only every 1000 items.

And the funny part is you don't need to work with ticks and such array at all for your purpose.

Reason: