Setting up a MA on RSI

 

I am trying to set up 2 MAs ontop of an RSI, using the Previous Indicators Data, and place a sell/buy when they cross. However I just can't seem to get my head around it and get it working and placing the buy/sell at the correct place.

Any help is appreciated.

My current code (mql4):

  double RSIBuffer[];
   
   int signal1 = 2;
   double MAofRSIBuffer1[];
   
   int signal2 = 30;
   double MAofRSIBuffer2[];
   
   
   ArrayResize(RSIBuffer, signal1 * 2);
   ArrayResize(MAofRSIBuffer1 , signal1 + 2);
   ArrayResize(MAofRSIBuffer2, signal2 + 2);
   
   for(int i=0 ; i<signal1 * 2 ; i++)
   {
      RSIBuffer[i] = iRSI(_Symbol, _Period, 13, PRICE_CLOSE, i);
   }
    
   ArraySetAsSeries(RSIBuffer,true);

   //First Moving Average
   for(int i=0; i <signal1 + 2; i++)
   {
     MAofRSIBuffer1[i] = iMAOnArray(RSIBuffer, 0, signal1, 0, MODE_EMA, i);
   }
   
   //Second Moving Average
   for(int i=0; i <signal2 + 2; i++)
   {
     MAofRSIBuffer2[i]=iMAOnArray(RSIBuffer, 0, signal2, 0, MODE_EMA, i);
   }
   
   //If cross
   if(MAofRSIBuffer1[0] > MAofRSIBuffer2[0] && MAofRSIBuffer1[1] < MAofRSIBuffer2[1])
   {
      //do buy or sell here 
   }
 
Can anyone help?
 

Hi

//+------------------------------------------------------------------+
//|                                                      rsi_mas.mq4 |
//|                       Copyright 2022, Republic Of Purple Carrots |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//inputs the periods and rsi settings 
input int RsiPeriod=14;//Rsi Period 
input ENUM_APPLIED_PRICE RsiPrice=PRICE_CLOSE;//Rsi Price
input int FastMa=7;//Fast Period (of rsi ma)
input int SlowMa=21;//Slow Period (of rsi ma)
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
/*
First the array
*/
double rsi[];
//then , we need to know if a new bar has formed , we will use time 
datetime barstamp=0;
//finally , for a cross strategy , we may need up to 3 values of a buffer so
double fast_ma[],slow_ma[];


int OnInit()
  {
//---
  /*
  the first thing to do is size our arrays
  we need the maximum ma's period worth of rsi items + 2 to accomodate for 3 latest values
  that's easy : 
  */ 
  int rsi_array_size=(int)MathMax(FastMa,SlowMa)+2;
  //resize it 
    ArrayResize(rsi,rsi_array_size,0);
  //then resize fast and slow ma with 3 items each
    ArrayResize(fast_ma,3,0);
    ArrayResize(slow_ma,3,0);
  /*
    we will navigate like so : 
    fast_ma[2] is the fast moving average of the rsi 3 bars ago
    fast_ma[1] is the fast moving average of the rsi on the most recently closed bar
    fast_ma[0] is the fast moving average of the rsi on the live bar
    
  */
  //step one : fill up the rsi
    for(int i=0;i<ArraySize(rsi);i++)
    {
    //we maintain symmetry with the charts indices and the array so , straight up call it 
      rsi[i]=iRSI(_Symbol,_Period,RsiPeriod,RsiPrice,i);
    }
  //step two : fill up the mas
    for(int i=0;i<ArraySize(fast_ma);i++)
    {
    fast_ma[i]=ma_this(rsi,i,FastMa,true);
    slow_ma[i]=ma_this(rsi,i,SlowMa,true);
    }
  //step three mark the time
    barstamp=Time[0];
  //on to tick()
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  //Question 1 : do we have a new bar ? 
    if(Time[0]>barstamp)
    {
    //set the new barstamp
      barstamp=Time[0];
    //pull all the bars down (imagine zero is the top) in our arrays
      for(int i=ArraySize(rsi)-1;i>=1;i--)
         {
         //the rsi on i gets the rsi on i-1 (the theoretically more recent one
           rsi[i]=rsi[i-1];
         }
    //same for the mas
      for(int i=ArraySize(fast_ma)-1;i>=1;i--)
         {
         fast_ma[i]=fast_ma[i-1];
         slow_ma[i]=slow_ma[i-1];
         }
    //get new values for bars [0] and [1]
      rsi[0]=iRSI(_Symbol,_Period,RsiPeriod,RsiPrice,0);
      rsi[1]=iRSI(_Symbol,_Period,RsiPeriod,RsiPrice,1);
      //calculate mas on 0 and 1
      for(int i=0;i<=1;i++)
      {
      fast_ma[i]=ma_this(rsi,i,FastMa,true);
      slow_ma[i]=ma_this(rsi,i,SlowMa,true);
      }
    //if you wish to trade only on new bars then you check : 
      //bullish
        if(fast_ma[2]<slow_ma[2]&&fast_ma[1]>slow_ma[1]){}
      //bearish
        else if(fast_ma[2]>slow_ma[2]&&fast_ma[1]<slow_ma[1]){}
    }
    else//no new bar 
    {
    //get new rsi value on running bar 
      rsi[0]=iRSI(_Symbol,_Period,RsiPeriod,RsiPrice,0);
    //update mas on running bar
      fast_ma[0]=ma_this(rsi,0,FastMa,true);
      slow_ma[0]=ma_this(rsi,0,SlowMa,true);
    //if you wish to trade live 
      //bullish
        if(fast_ma[1]<slow_ma[1]&&fast_ma[0]>slow_ma[0]){}
      //bearish
        else if(fast_ma[1]>slow_ma[1]&&fast_ma[0]<slow_ma[0]){}      
    } 
  }
//+------------------------------------------------------------------+

  
  //our simple ma function
               //what               ,where    ,how much  ,right to left?
double ma_this(const double &array[],int where,int period,bool pretend_its_series){
double sum=0.0,items=0.0;
//series
  if(pretend_its_series){
  //where is the rightmost value and the smallest in the average so we period out into the array for an average 
  //so we ma until ...
    int until=where+period-1;//we add a value because the index reduces as we move to the present
              //we subtract one from the period as where is included in it 
    if(until>ArraySize(array)-1){until=ArraySize(array)-1;}//if we exceed the size of the array we limit it
    //we move into the past (++) and add up values
    for(int i=where;i<=until;i++)
       {
       sum+=array[i];items+=1.0;
       }
    if(items>0.0){sum/=items;}
  }
//non series
  else{
  //where is the rightmost value and the bigest in the average so we period out into the array for an average 
  //so we ma until ...
    int until=where-period+1;//we subtract a value because the index increases as we move to the present
              //we add one to the period as where is included in it
    if(until<0){until=0;}//if we exceed the start of the array we stop
    //we move into the past (--) and add up values
    for(int i=where;i>=until;i--)
       {
       sum+=array[i];items+=1.0;
       }
    if(items>0.0){sum/=items;}  
  }
return(sum);
}  

 

Thank you very much for this.

The comments are also very useful and helped me understand what is happening.

 

What type of MA is this using? Is it "Previous Indicators Data"? 

Is there any way I can switch between different options?

 
Idi #:

What type of MA is this using? Is it "Previous Indicators Data"? 

Is there any way I can switch between different options?

It is a simple moving average on the rsi .

You can utilize the iMaOnArray for the other types 

  //step two : fill up the mas
    for(int i=0;i<ArraySize(fast_ma);i++)
    {
    fast_ma[i]=ma_this(rsi,i,FastMa,true);
    slow_ma[i]=ma_this(rsi,i,SlowMa,true);
    //fast_ma[i]=iMAOnArray(rsi,0,FastMa,0,MODE_SMA,i);
    //slow_ma[i]=iMAOnArray(rsi,0,SlowMa,0,MODE_SMA,i);      
    }

      //calculate mas on 0 and 1
      for(int i=0;i<=1;i++)
      {
      fast_ma[i]=ma_this(rsi,i,FastMa,true);
      slow_ma[i]=ma_this(rsi,i,SlowMa,true);
      //fast_ma[i]=iMAOnArray(rsi,0,FastMa,0,MODE_SMA,i);
      //slow_ma[i]=iMAOnArray(rsi,0,SlowMa,0,MODE_SMA,i);      
      }

    //update mas on running bar
      fast_ma[0]=ma_this(rsi,0,FastMa,true);
      slow_ma[0]=ma_this(rsi,0,SlowMa,true);
      //fast_ma[0]=iMAOnArray(rsi,0,FastMa,0,MODE_SMA,0);
      //slow_ma[0]=iMAOnArray(rsi,0,SlowMa,0,MODE_SMA,0);
Reason: