Need help coding RSI

alikim

Newbie
Dec 27, 2024
2
0
1
35
I wrote this function, it works, but the value doesn't match what MT4 shows me. What am I doing wrong?

MQL4:
void CalcRSI(int period, bool output = true) {
   int startDate = 2 * period;
   double gains[];
   double losses[];
   ArrayResize(gains, startDate + 1);
   ArrayResize(losses, startDate + 1);
 
   for (int i = startDate; i >= 0; i--) {
      double diff = Close[i] - Close[i + 1];
      gains[i] = diff > 0 ? diff : 0.0;
      losses[i] = diff > 0 ? 0.0 : -diff;
   }
 
   double avrGain = 0.0;
   double avrLoss = 0.0;
 
   // initial average
   for (int i = startDate; i > startDate - period; i--) {
      avrGain += gains[i];
      avrLoss += losses[i];
   }
   avrGain /= period;
   avrLoss /= period;
 
   // Wilder's smoothing
   for (int i = startDate - period; i >= 0; i--) {
      avrGain = (avrGain * (period - 1) + gains[i]) / period;
      avrLoss = (avrLoss * (period - 1) + losses[i]) / period;
   }
 
   double rs = avrGain / avrLoss;
   double rsi = 100 - (100 / (1 + rs));
 
   if(output) {
      Alert(StringFormat("RSI(%d): %.2f", period, rsi));
   }
}
 
Last edited by a moderator:

Lee-me

Trader
Apr 24, 2023
58
8
19
32
This might help:

void CalcRSI(int period, bool output = true) {
int startDate = period;
double gains[], losses[];
ArrayResize(gains, period);
ArrayResize(losses, period);

// Calculate the gains and losses for the period
for (int i = startDate; i > 0; i--) {
double diff = Close - Close[i + 1];
gains[i - 1] = diff > 0 ? diff : 0.0;
losses[i - 1] = diff < 0 ? -diff : 0.0;
}

// Calculate the initial average gain and loss
double avrGain = 0.0;
double avrLoss = 0.0;
for (int i = 0; i < period; i++) {
avrGain += gains;
avrLoss += losses;
}
avrGain /= period;
avrLoss /= period;

// Wilder's smoothing method for subsequent periods
for (int i = startDate; i < Bars - 1; i++) {
double diff = Close - Close[i + 1];
double gain = diff > 0 ? diff : 0.0;
double loss = diff < 0 ? -diff : 0.0;

avrGain = (avrGain * (period - 1) + gain) / period;
avrLoss = (avrLoss * (period - 1) + loss) / period;
}

// Calculate RS and RSI
double rs = (avrLoss == 0) ? 100 : avrGain / avrLoss; // Prevent division by zero
double rsi = 100 - (100 / (1 + rs));

if (output) {
Alert(StringFormat("RSI(%d): %.2f", period, rsi));
}
}
 

Enivid

Administrator
Staff member
Nov 30, 2008
19,306
1,530
144
Odesa
www.earnforex.com
This might help:

void CalcRSI(int period, bool output = true) {
int startDate = period;
double gains[], losses[];
ArrayResize(gains, period);
ArrayResize(losses, period);

// Calculate the gains and losses for the period
for (int i = startDate; i > 0; i--) {
double diff = Close - Close[i + 1];
gains[i - 1] = diff > 0 ? diff : 0.0;
losses[i - 1] = diff < 0 ? -diff : 0.0;
}

// Calculate the initial average gain and loss
double avrGain = 0.0;
double avrLoss = 0.0;
for (int i = 0; i < period; i++) {
avrGain += gains;
avrLoss += losses;
}
avrGain /= period;
avrLoss /= period;

// Wilder's smoothing method for subsequent periods
for (int i = startDate; i < Bars - 1; i++) {
double diff = Close - Close[i + 1];
double gain = diff > 0 ? diff : 0.0;
double loss = diff < 0 ? -diff : 0.0;

avrGain = (avrGain * (period - 1) + gain) / period;
avrLoss = (avrLoss * (period - 1) + loss) / period;
}

// Calculate RS and RSI
double rs = (avrLoss == 0) ? 100 : avrGain / avrLoss; // Prevent division by zero
double rsi = 100 - (100 / (1 + rs));

if (output) {
Alert(StringFormat("RSI(%d): %.2f", period, rsi));
}
}
Please use code highlighting. Otherwise, it becomes garbled.
 

Enivid

Administrator
Staff member
Nov 30, 2008
19,306
1,530
144
Odesa
www.earnforex.com
I wrote this function, it works, but the value doesn't match what MT4 shows me. What am I doing wrong?

MQL4:
void CalcRSI(int period, bool output = true) {
   int startDate = 2 * period;
   double gains[];
   double losses[];
   ArrayResize(gains, startDate + 1);
   ArrayResize(losses, startDate + 1);
 
   for (int i = startDate; i >= 0; i--) {
      double diff = Close[i] - Close[i + 1];
      gains[i] = diff > 0 ? diff : 0.0;
      losses[i] = diff > 0 ? 0.0 : -diff;
   }
 
   double avrGain = 0.0;
   double avrLoss = 0.0;
 
   // initial average
   for (int i = startDate; i > startDate - period; i--) {
      avrGain += gains[i];
      avrLoss += losses[i];
   }
   avrGain /= period;
   avrLoss /= period;
 
   // Wilder's smoothing
   for (int i = startDate - period; i >= 0; i--) {
      avrGain = (avrGain * (period - 1) + gains[i]) / period;
      avrLoss = (avrLoss * (period - 1) + losses[i]) / period;
   }
 
   double rs = avrGain / avrLoss;
   double rsi = 100 - (100 / (1 + rs));
 
   if(output) {
      Alert(StringFormat("RSI(%d): %.2f", period, rsi));
   }
}
What are you expecting it to match?
 

alikim

Newbie
Dec 27, 2024
2
0
1
35
I almost solved it, basically added one day in the first line:
Code:
int startDate = 2 * period + 1;
now it looks like this (cyan lines), compared to in-built RSI (blue lines):

1735390174856.png

my wild guess, since it differs at the beginning, where initial average is calculated, maybe MT4 calculates initial value also using Wilder's smoothing, and not as average. Another reason might be that startDate is rather 2 or 3 days shorter, haven't had time to run tests yet.
 

Enivid

Administrator
Staff member
Nov 30, 2008
19,306
1,530
144
Odesa
www.earnforex.com
I almost solved it, basically added one day in the first line:
Code:
int startDate = 2 * period + 1;
now it looks like this (cyan lines), compared to in-built RSI (blue lines):

View attachment 30885

my wild guess, since it differs at the beginning, where initial average is calculated, maybe MT4 calculates initial value also using Wilder's smoothing, and not as average. Another reason might be that startDate is rather 2 or 3 days shorter, haven't had time to run tests yet.
That's because Wilder's smoothing carries over previous values well beyond the period's length. Start calculating from the data's beginning and you'll get the same result as the MT4 built-in RSI. I also recommend checking the RSI.mq4 source code in the Indicators folder - it shows how MetaQuotes calculates this indicator.
 
  • 👍
Reactions: alikim