Array out of range, and it is confounding me...

 

Hi. I'm not a newbie programmer. But, I'm a serious newbie to mql5 and never did anything with mql4.

I am writing an indicator that simply detect engulfing Bull and Bear patterns and then I want to send along the price to an EA.

But, I'm having a crazy issue where this thing just keeps spitting out an array out of range message. It strangely (to me anyway) seems to occur after 51 iterations of a for(i... loop.

Here's the code... I hope someone out there can point me in the right direction... Thanks in advance.

#property copyright "Copyright 2017, Gary Pfeffer"
#property link      "https://www.garypfeffer.net"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot BUY
#property indicator_label1  "BUY"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrDarkGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot SELL
#property indicator_label2  "SELL"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- indicator buffers
double                      BUYBuffer[];
double                      SELLBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BUYBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SELLBuffer,INDICATOR_DATA);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(0,PLOT_ARROW,233);
   PlotIndexSetInteger(1,PLOT_ARROW,234);
   PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,10);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-10);

  
//---
   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[])
  {
//---

//--- Calculation loop
   int i;
   for(i=1;i<rates_total;i++){
     // clear buffers
     BUYBuffer[i]=0;
     SELLBuffer[i]=0;
     // Look for SELL Signal
     if ((close[i-1]>open[i-1])&&(open[i]>close[i])&&(open[i]>=close[i-1])&&(open[i-1]>=close[i])&&((open[i]-close[i])>(close[i-1]-open[i-1]))&&((high[i-1] - low[i-1])>=(50 *_Point))) {
         SELLBuffer[i]=high[i];
     }
     // Look for Buy Signal
     if ((open[i-1]>close[i-1])&&(close[i]>open[i])&&(close[i]>=open[i-1])&&(close[i-1]>=open[i])&&((close[i]-open[i])>(open[i-1]-close[i-1]))&&((low[i-1] - high[i-1])<=(50 *_Point))) {
         BUYBuffer[i]=low[i];
     }
    Print("BUY ", i, " = ", BUYBuffer[i], " -- SELL = ", SELLBuffer[i]);
    
    
   }
//--- return value of prev_calculated for next call
// i've no idea what to do with this.
// it seems like only rates_total is returned no matter what I try. So, I've just left rates_total in there for now
   if(BUYBuffer[i]>0){
 //     int buyreturn;
  //    buyreturn = MathRound(BUYBuffer[i]);
      return(rates_total);
  
   }
   if(SELLBuffer[i]>0){
  //    int sellreturn;
  //    sellreturn = MathRound(SELLBuffer[i]);
      return(rates_total);
   }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Print Output from Indicator

Automated Trading and Strategy Testing
Automated Trading and Strategy Testing
  • www.mql5.com
Choose a suitable trading strategy and subscribe to it with a few clicks. All Signals are provided with detailed statistics and informative charts. Become a trading signal provider and sell subscriptions to thousands of traders around the world. With the Signals service, your successful strategy can generate income with a small start-up budget...
 

Actually, to add a little clarity...

When the indicator is attached to a chart, the array out of range message occurs on the last bar only.

When referenced in an EA, it gives the message after 51 iterations of a for loop.

Further, the size of SELLBuffer 906 and BUYBuffer is 1016. And, as stated in the documentation the dynamic buffers can not be resized. These seem like terribly small sizes for all of the technical work done over large windows. I am missing something here, I am sure.


Ok. It appears that I was moving one bar into the future (lol) by looping to rates_total and not (rates_total - 1). Am I correct?

The array message is gone from the indicator. And, when it is called my an EA, there is no more array error message after 51 iterations of i. However, i resorts to the value '1' again. And, them loops through to 51, and then resets itself to 1 ... over and over again. I am not doing this with my code. It's just one for loop that should be running up to around 1000.


So, I'm still confused, but making progress. haha.

 
  1. When you post code please use the SRC button! Please edit your post.
              General rules and best pratices of the Forum. - General - MQL5 programming forum

  2. gary0318: Ok. It appears that I was moving one bar into the future (lol) by looping to rates_total and not (rates_total - 1). Am I correct?
      int i;
       for(i=1;i<rates_total;i++){
         :
       }
       if(BUYBuffer[i]>0){
     //     int buyreturn;
    That is exactly what you are doing. You loop runs from 1 to rates_total-1. It exits when i == rates_total. You are using it after the loop.
  3. Next time when you have the line number, point to it when you have a code snipit do we know what line it is.
  4. You are using the arrays as non-series including the buffers. Buffers are as-series, per SetIndexBuffer. Heed the note there.
Reason: