Calculating MA of RSI in an Expert Advisor

 

Hi guys,

Appreciate your help in advance:

input int    RSILength =12;
input int    RSIMASlow =50;
input int    RSIMAFast =25;

void OnTick(void)
  {
   int i;
   double RSI1[];
   double RSI2[];
   
   ArrayResize(RSI1,RSIMASlow); 
   ArraySetAsSeries(RSI1,true);
   for(i=0; i<RSIMASlow; i++)
   {
   RSI1[i] = iRSI(NULL,0,RSILength,PRICE_CLOSE,i);
   }

   ArrayResize(RSI2,RSIMAFast);
   ArraySetAsSeries(RSI2,true); 
   for(i=0; i<RSIMAFast; i++)
   {
   RSI2[i] = iRSI(NULL,0,RSILength,PRICE_CLOSE,i);
   }

   double RSIMASlowCurrent=iMAOnArray(RSI1,0,RSIMASlow,0,MODE_EMA,0);
   double RSIMASlowPrevious=iMAOnArray(RSI1,0,RSIMASlow,0,MODE_EMA,1);
   double RSIMAFastCurrent=iMAOnArray(RSI2,0,RSIMAFast,0,MODE_EMA,0);
   double RSIMAFastPrevious=iMAOnArray(RSI2,0,RSIMAFast,0,MODE_EMA,1);


I'm trying to calculate the moving average of RSI and using the crossover in an Expert Advisor, but I kept getting the error Array out of range. Any idea why?

Thanks again!

 
  1. You don't even state what line the error occurs.
         How To Ask Questions The Smart Way. (2004)
              Be precise and informative about your problem

  2. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?
              Code debugging - Developing programs - MetaEditor Help
              Error Handling and Logging in MQL5 - MQL5 Articles (2015)
              Tracing, Debugging and Structural Analysis of Source Code - MQL5 Articles (2011)
              Introduction to MQL5: How to write simple Expert Advisor and Custom Indicator - MQL5 Articles (2010)

 
Sorry it’s my first time trying to do this. The error is with the line starting RSI1[i] = , it compiles without error but when debugging it says Array out of range.

But thanks for the info, will try looking at debugging after reading some of the links you provided.
 

Hi, following the previous topic:

I've managed to get past the Array out of range error, but now when I try to use the array in iMAOnArray, all the values of the array becomes 0.

For example, when I remove all the iMAOnArray functions, there are values for RSI[], but when I use RSI[] in any iMAOnArray functions, the values become 0.

See the highlighted line below as I try to check the values in the array:

#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "Moving Average sample expert advisor"

#define MAGICMA  9614

//--- Inputs
input double              Lots              =0.8;
input int                 RSIPeriod         =30;
input int                 RSISlowMAPeriod   =50;
input int                 RSIFastMAPeriod   =20;
input ENUM_APPLIED_PRICE  PriceType         =PRICE_CLOSE;
input ENUM_MA_METHOD      MA_Method         =MODE_SMA;
input int                 StopLoss          =200;

// Definition of an hour. This is necessary for a drop down menu for hours input.
enum ENUM_HOUR
{
   h00 = 00, // 00:00
   h01 = 01, // 01:00
   h02 = 02, // 02:00
   h03 = 03, // 03:00
   h04 = 04, // 04:00
   h05 = 05, // 05:00
   h06 = 06, // 06:00
   h07 = 07, // 07:00
   h08 = 08, // 08:00
   h09 = 09, // 09:00
   h10 = 10, // 10:00
   h11 = 11, // 11:00
   h12 = 12, // 12:00
   h13 = 13, // 13:00
   h14 = 14, // 14:00
   h15 = 15, // 15:00
   h16 = 16, // 16:00
   h17 = 17, // 17:00
   h18 = 18, // 18:00
   h19 = 19, // 19:00
   h20 = 20, // 20:00
   h21 = 21, // 21:00
   h22 = 22, // 22:00
   h23 = 23, // 23:00
};

input ENUM_HOUR StartHour = h13; // Start operation hour
input ENUM_HOUR LastHour = h23; // Last operation hour

//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }

//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {int res;
   
   // Set operations disabled by default.
   bool OperationsAllowed = false;
   // Check if the current hour is between the allowed hours of operations. If so, return true.
   if ((StartHour == LastHour) && (Hour() == StartHour))
      OperationsAllowed = true;
   if ((StartHour < LastHour) && (Hour() >= StartHour) && (Hour() <= LastHour))
      OperationsAllowed = true;
   if ((StartHour > LastHour) && (((Hour() >= LastHour) && (Hour() <= 23)) || ((Hour() <= StartHour) && (Hour() > 0))))
      OperationsAllowed = true;
   
   double RSI[];
   ArrayResize(RSI,100); 
   ArraySetAsSeries(RSI,true);
   for(int i=0; i<100; i++)
   {
   RSI[i] = iRSI(NULL,0,RSIPeriod,PriceType,i+1);
   }
   
   Print(DoubleToString(RSI[50],2));
      
//--- get Moving Average 
   double FastMA      =iMAOnArray(RSI,0,RSIFastMAPeriod,0,MA_Method,0);
   double SlowMA      =iMAOnArray(RSI,0,RSISlowMAPeriod,0,MA_Method,0);
  
   double FastMA1     =iMAOnArray(RSI,0,RSIFastMAPeriod,0,MA_Method,1);
   double SlowMA1     =iMAOnArray(RSI,0,RSISlowMAPeriod,0,MA_Method,1);   
   
//--- sell conditions
   if(OperationsAllowed && FastMA<SlowMA && FastMA1>SlowMA1)
     {
      res=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//--- buy conditions
   if(OperationsAllowed && FastMA>SlowMA && FastMA1<SlowMA1)
     {
      res=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {   
//--- go trading only for first ticks of new bar
   if(Volume[0]>1) return;   
   
   double RSI[];
   ArrayResize(RSI,100); 
   ArraySetAsSeries(RSI,true);
   for(int i=0; i<100; i++)
   {
   RSI[i] = iRSI(NULL,0,RSIPeriod,PriceType,i+1);
   }
   
//--- get Moving Average 
   double FastMA      =iMAOnArray(RSI,0,RSIFastMAPeriod,0,MA_Method,0);
   double SlowMA      =iMAOnArray(RSI,0,RSISlowMAPeriod,0,MA_Method,0);
  
   double FastMA1     =iMAOnArray(RSI,0,RSIFastMAPeriod,0,MA_Method,1);
   double SlowMA1     =iMAOnArray(RSI,0,RSISlowMAPeriod,0,MA_Method,1);
//---
   for(int j=0;i<OrdersTotal();j++)
     {
      if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      //--- check order type 
      if(OrderType()==OP_BUY)
        {
         if( (TimeHour(TimeCurrent())==LastHour && TimeMinute(TimeCurrent())==58) || (FastMA<SlowMA && FastMA1>SlowMA1) )
           {
            if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,White))
               Print("OrderClose error ",GetLastError());
           }
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if( (TimeHour(TimeCurrent())==LastHour && TimeMinute(TimeCurrent())==58) || (FastMA>SlowMA && FastMA1<SlowMA1) )
           {
            if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White))
               Print("OrderClose error ",GetLastError());
           }
         break;
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//---
  }
//+------------------------------------------------------------------+

Anyone encountered such issues?

 
siaxiangbin #: Hi, following the previous topic: I've managed to get past the Array out of range error, but now when I try to use the array in iMAOnArray, all the values of the array becomes 0. For example, when I remove all the iMAOnArray functions, there are values for RSI[], but when I use RSI[] in any iMAOnArray functions, the values become 0. See the highlighted line below as I try to check the values in the array: Anyone encountered such issues?

Both your original problem, as well as your new problem, may be related to a recent bug discovered in MQL4, regarding the declaration and resizing of locally declared dynamic arrays.

Depending on whether it is compiled with or without "#property strict", it may or may not give an "array of range" error, but in both cases the array is not resized and using iMAOnArray will give a "0" result because the array is empty.

Forum on trading, automated trading systems and testing trading strategies

Array out of range

Fernando Carreiro, 2022.09.26 14:22

Yes, something seems wrong. I used the following code to check the return value and error code of "ArrayResize", and this is what I got ...

#property strict
void OnStart()
{
   double Array[];
   ResetLastError();
   int nSizeArray = ArrayResize(Array, 3);
   PrintFormat("Size: %d, Error: %d",nSizeArray,_LastError);
   Array[0] = 1.0;
   Array[1] = 1.0;
   Array[2] = 4.0;
   double ma = iMAOnArray(Array, 3, 3, 0, MODE_SMA, 0);
   Alert("result = ", ma);
}
2022.09.26 12:44:24.689 Script TestArray EURUSD,H1: removed
2022.09.26 12:44:24.689 TestArray EURUSD,H1: uninit reason 0
2022.09.26 12:44:24.689 TestArray EURUSD,H1: array out of range in 'TestArray.mq4' (8,9)
2022.09.26 12:44:24.689 TestArray EURUSD,H1: Size: -1, Error: 4029
2022.09.26 12:44:24.689 TestArray EURUSD,H1: initialized
2022.09.26 12:44:24.673 Script (Test)\TestArray EURUSD,H1: loaded successfully

4029

ERR_ARRAY_INVALID

Invalid array

However, if I then move the array declaration to the global scope, it then works ...

#property strict
double Array[];
void OnStart()
{
   ResetLastError();
   int nSizeArray = ArrayResize(Array, 3);
   PrintFormat("Size: %d, Error: %d",nSizeArray,_LastError);
   Array[0] = 1.0;
   Array[1] = 1.0;
   Array[2] = 4.0;
   double ma = iMAOnArray(Array, 3, 3, 0, MODE_SMA, 0);
   Alert("result = ", ma);
}
2022.09.26 12:51:31.420 Script TestArray EURUSD,H1: removed
2022.09.26 12:51:31.420 TestArray EURUSD,H1: uninit reason 0
2022.09.26 12:51:31.420 TestArray EURUSD,H1: Alert: result = 2.0
2022.09.26 12:51:31.420 TestArray EURUSD,H1: Size: 3, Error: 0
2022.09.26 12:51:31.420 TestArray EURUSD,H1: initialized
2022.09.26 12:51:31.404 Script (Test)\TestArray EURUSD,H1: loaded successfully

For some reason, it is not considering a locally scoped dynamic array as being dynamic.

I also tested the same concept on MetaTrader 5 and it worked correctly as expected, but it does not work in MetaTrader 4.

This seems to be a MQL4 bug.

EDIT: These tests were on MT4 Build 1356 (5th May 2022).


 
Fernando Carreiro #:

Both your original problem, as well as your new problem, may be related to a recent bug discovered in MQL4, regarding the declaration and resizing of locally declared dynamic arrays.

Depending on whether it is compiled with or without "#property strict", it may or may not give an "array of range" error, but in both cases the array is not resized and using iMAOnArray will give a "0" result because the array is empty.


Thanks! Your solution worked perfectly!
 
siaxiangbin #: Thanks! Your solution worked perfectly!
You are welcome!
Reason: