RSI Formula used in iRSI?

 
Hi there,

For my own purposes I need to write a script that calculates the RSI
but I don't want to use the iRSI formula (long story).

However, I want to make sure my values match up with the iRSI.
However, I cannot figure out what formula iRSI uses. I am using the
formula (as best I can tell) for RSI but I cannot get it to match what
MQL's iRSI outputs.

Could you please copy and paste the RSI formula used with iRSI so I
can accomplish my task?

Thanks so much!

Cheers,

stepwise
 
stepwise:
Hi there,

For my own purposes I need to write a script that calculates the RSI
but I don't want to use the iRSI formula (long story).

However, I want to make sure my values match up with the iRSI.
However, I cannot figure out what formula iRSI uses. I am using the
formula (as best I can tell) for RSI but I cannot get it to match what
MQL's iRSI outputs.

Could you please copy and paste the RSI formula used with iRSI so I
can accomplish my task?

Thanks so much!

Cheers,

stepwise

Did you ever get an answer to this? Because as near as I can tell the suggested RSI code and iRSI still differ....

 
IYHAYKICYH:

Did you ever get an answer to this? Because as near as I can tell the suggested RSI code and iRSI still differ....

Hi, that is my opinion too.

It would be very nice to see how iRSI is caculating.

Unfortunaly I do not understand russia, so can anybody please explain what this says:

'Один эксперт у одного брокера на разных терминалах и счетах, результат разный.'

 

babelfish is your friend at these times! http://uk.babelfish.yahoo.com/translate_txt

is of course open to interpretation! but the idea is there and the site viewed via babelfish is not to bad... + much info to ponder on.
 

I am unable to get the below method to equal the values returned by iRSI .. any suggestions?>

double getRSI(int RSIperiod, int shift)
{
double rel,negative,positive;
if(Bars<=RSIperiod) return(0);

double sumn=0.0,sump=0.0;
int k=shift+RSIperiod-1;
//---- initial accumulation
while(k>=shift)
{
rel=Close[k]-Close[k+1];
if(rel>0) sump+=rel;
else sumn-=rel;
k--;
}
positive=sump/RSIperiod;
negative=sumn/RSIperiod;

if(negative==0.0) return(0.0);
else return(100.0-100.0/(1+positive/negative));
}

 
hamishd:

I am unable to get the below method to equal the values returned by iRSI .. any suggestions?>

See https://www.mql5.com/en/forum/124630
 

how would this look in the above method for a single bar .. I have matched the RSI.mql provided by metaquotes which has no EMA calcs

 
hamishd:

I have matched the RSI.mql provided by metaquotes which has no EMA calcs

Er, no. If you look at the RSI.mq4 code, then all values apart from the first bar ("i==Bars-RSIPeriod-1") are calculated using the RSI value which was calculated on the previous bar. For example, "positive=(PosBuffer[i+1]*(RSIPeriod-1)+sump)/RSIPeriod". The code contains the explicit comment "//---- smoothed moving average"

The trouble with this kind of smoothed average (or any smoothed/exponential average in general) is that values at the start of the data series affect all the subsequent values, albeit by increasingly trivial amounts. As the Wikipedia page says in relation to Cutler's RSI: "Cutler had found that since Wilder used an exponential moving average to calculate RSI, the value of Wilder's RSI depended upon where in the data file his calculations started". In the attached spreadsheet - see below - try changing cell F2 (the first close price) to a very large value such as 999999999999999999, and watch how the RSI values are affected all the way down the spreadsheet.

In turn, this means that to exactly replicate the MT4 RSI calculation for bar N, you have to calculate the RSI for all the bars from the start of the history up to N:

// Replicates the MT4 RSI calculation for a specific bar. Very slow, because it 
// works by calculating the value for the first bar, and then calculating the 
// smoothed values for each subsequent bar up to the one requested by the
// shift parameter. Could be made faster, at the cost of minimal loss of accuracy,
// by only starting a relatively small number of bars back (e.g. 10 x RSIperiod),
// rather than going back to the very first bar 

double getRSI(int RSIperiod, int shift)
{
   double vSumUp = 0, vSumDown = 0, vDiff = 0;

   // Need to get the RSI on the very first bar, 
   int iStartBar = Bars - RSIperiod - 1;
   for (int iFirstCalc = iStartBar; iFirstCalc < iStartBar + RSIperiod; iFirstCalc++) {
      vDiff = Close[iFirstCalc] - Close[iFirstCalc + 1];
      if (vDiff > 0) {
         vSumUp += vDiff;
      } else {
         vSumDown += MathAbs(vDiff);
      }
   }
   double vAvgUp = vSumUp / RSIperiod;
   double vAvgDown = vSumDown / RSIperiod;
   
   // And now, we have to calculate the smoothed RSI value for 
   // each subsequent bar until we get to the one requested
   for (int iRepeat = iStartBar - 1; iRepeat >= shift; iRepeat--) {
      vDiff = Close[iRepeat] - Close[iRepeat + 1];

      if (vDiff > 0) {
         vAvgUp = ((vAvgUp * (RSIperiod - 1)) + vDiff) / RSIperiod;
         vAvgDown = ((vAvgDown * (RSIperiod - 1))) / RSIperiod;
      } else {
         vAvgUp = ((vAvgUp * (RSIperiod - 1))) / RSIperiod;
         vAvgDown = ((vAvgDown * (RSIperiod - 1)) + MathAbs(vDiff)) / RSIperiod;
      }
   }

   if (vAvgDown == 0) 
      return 0;
   else
      return(100.0 - 100.0/(1+(vAvgUp/vAvgDown)));
}

The attached spreadsheet replicates MT4's RSI calculation, and the above code produces values which match against MT4 and against column N in the spreadsheet. But it's not pretty. Smoothed/exponential averages are optimised for scenarios where you are calculating a sequence of values.

Files:
 

thank you jjc.

Reason: