RSI Code

22

Hi everybody

I wrote a mql4 program to get the RSI value in every tick. But now I have a problem and get different values. could you please help me to find out my mistake?

```double get_RSI_value (double & price[][6], double period) {

double tmp = 0.0;
double Avg_Positive = 0.0;
double Avg_Negative = 0.0;
double sum_negative = 0.0;
double sum_positive = 0.0;
double RS = 0.0;
double RSI = 0.0;

for (int i = 1 ; i <= period ; i++) {
tmp = price[i][4] - price[i-1][4];
if (tmp >= 0) {
sum_positive += tmp;
} else {
sum_negative = (-1 * tmp) + sum_negative;
// sum_negative -= tmp;
}
}

if (period < 2) return 0;

Avg_Negative = sum_negative / period;
Avg_Positive = sum_positive / period;

if (Avg_Negative != 0.0) {
RS = Avg_Positive / Avg_Negative;
RSI = 100.0 - (100.0 / (1.0 + RS));
}
else {
if(Avg_Positive != 0.0)
RSI = 100.0;
else
RSI = 50.0;
}

return RSI;
}```

16105

 Play video Please edit your post. For large amounts of code, attach it.
22

Code placed in SRC mode. (updated)

please someone help, Why I get various value in compare with meta-trader RSI indicator?

16105

 nitro_man: Why I get various value in compare with meta-trader RSI indicator?```      tmp = price[i][4] - price[i-1][4]; ``` Because you're computing it backwards. Change is Current Close minus Previous Close, not Current Close minus Future close.
22

WHRoeder:
 nitro_man: Why I get various value in compare with meta-trader RSI indicator? Because you're computing it backwards. Change is Current Close minus Previous Close, not Current Close minus Future close.

Thanks, But I double check the RSI indicator formula, that's correct. In this indicator we have: current close price - previous close price

I checked this on wikipedia too: https://en.wikipedia.org/wiki/Relative_strength_index

5127

nitro_man:

Hi everybody

I wrote a mql4 program to get the RSI value in every tick. But now I have a problem and get different values. could you please help me to find out my mistake?

period is an integer. The dynamic array should be resized before doing calculations.

```double get_RSI_value (double & price[][6], int period) {

double tmp = 0.0;
double Avg_Positive = 0.0;
double Avg_Negative = 0.0;
double sum_negative = 0.0;
double sum_positive = 0.0;
double RS = 0.0;
double RSI = 0.0;

if (period < 2) return 0;

ArrayResize(price,period);
for (int i = 1 ; i <= period ; i++) {
tmp = price[i][4] - price[i-1][4];
if (tmp >= 0) {
sum_positive += tmp;
} else {
sum_negative = (-1 * tmp) + sum_negative;
// sum_negative -= tmp;
}
}

Avg_Negative = sum_negative / period;
Avg_Positive = sum_positive / period;

if (Avg_Negative != 0.0) {
RS = Avg_Positive / Avg_Negative;
RSI = 100.0 - (100.0 / (1.0 + RS));
}
else {
if(Avg_Positive != 0.0)
RSI = 100.0;
else
RSI = 50.0;
}

return RSI;
}```
22

pipPod:

period is an integer. The dynamic array is usually the last dimension and should be resized before doing calculations.

thanks dude, I checked that, I think the solution you said couldn't solve it but now I have much better results. I changed function to this:

```double get_RSI (double period) {

double tmp = 0.0;
double Avg_Positive = 0.0;
double Avg_Negative = 0.0;
double sum_negative = 0.0;
double sum_positive = 0.0;
double RS = 0.0;
double RSI = 0.0;

double prices[][6];
ArrayCopyRates(prices, NULL, 0);
RefreshRates();

for (int i = 0 ; i < period ; i++) {

tmp = prices[i][4] - prices[i+1][4];
if (tmp >= 0) {
sum_positive += tmp;
} else {
sum_negative -= tmp;
}
}

if (period < 2) return 0;

Avg_Negative = sum_negative / period;
Avg_Positive = sum_positive / period;

if (Avg_Negative != 0.0) {
RS = Avg_Positive / Avg_Negative;
RSI = 100.0 - (100.0 / (1.0 + RS));
}
else {
if(Avg_Positive != 0.0)
RSI = 100.0;
else
RSI = 50.0;
}
return RSI;
}
```
22

I did:

```double prices[][6];
ArrayCopyRates(prices, NULL, 0); ```
`RefreshRates(); `

I thinks I must refresh prices in the function and do refresh them before calculation. Am I right?

5127

nitro_man:

I did:

I thinks I must refresh prices in the function and do refresh them before calculation. Am I right?

I don't think RefreshRates() is necessary, but you still have to make sure the right prices(indexes) are copied.
16105

 nitro_man: I double check the RSI indicator formula, that's correct. In this indicator we have: current close price - previous close price`      tmp = price[i][4] - price[i-1][4];` nitro_man: I changed function to this: ```      tmp = prices[i][4] - prices[i+1][4];     ```nitro_man: I did:```double prices[][6];    ArrayCopyRates(prices, NULL, 0); ``` WHRoeder: Because you're computing it backwards. Change is Current Close minus Previous Close, not Current Close minus Future close. It is supposed to be the previous close price. That is what I said. But that is NOT what you were computing.RefreshRates is necessary only if you don't return from start, after sleep, or between multiple server calls to update Bid, Ask, Close[0], or OrderClosePrice() on open orders.If you change to the new ACR, your code would be self documenting as well as avoiding the large allocation/copy and convert elements that you are doing with the double version.```MqlRates prices[];    ArrayCopyRates(prices, NULL, 0); :      tmp = prices[i].close - prices[i+1].close; ```
22

WHRoeder:
 nitro_man: I double check the RSI indicator formula, that's correct. In this indicator we have: current close price - previous close price nitro_man: I changed function to this: nitro_man: I did: WHRoeder: Because you're computing it backwards. Change is Current Close minus Previous Close, not Current Close minus Future close. It is supposed to be the previous close price. That is what I said. But that is NOT what you were computing.RefreshRates is necessary only if you don't return from start, after sleep, or between multiple server calls to update Bid, Ask, Close[0], or OrderClosePrice() on open orders.If you change to the new ACR, your code would be self documenting as well as avoiding the large allocation/copy and convert elements that you are doing with the double version.

thanks alot WHRoeder.

now I have this code with different RSI value in same time with RSI indicator :(

```MqlRates prices[];
ArrayCopyRates(prices, NULL, 0);
double RSI_value = get_RSI_value (prices, FA_Period);

double get_RSI_value (MqlRates & peices_arg[], double period) {

double Avg_Positive = 0.0;
double Avg_Negative = 0.0;
double sum_negative = 0.0;
double sum_positive = 0.0;
double tmp = 0.0;
double RS = 0.0;
double RSI = 0.0;

for (int i = 1 ; i <= period ; i++) {
tmp = peices_arg[i].close - peices_arg[i+1].close;
if (tmp >= 0) {
sum_positive += tmp;
} else {
sum_negative -= tmp;
}
}

if (period < 2) return 0;

Avg_Negative = sum_negative / period;
Avg_Positive = sum_positive / period;

if (Avg_Negative != 0.0) {
RS = Avg_Positive / Avg_Negative;
RSI = 100.0 - (100.0 / (1.0 + RS));
}
else {
if(Avg_Positive != 0.0)
RSI = 100.0;
else
RSI = 50.0;
}

return RSI;
}```

RSI indicator in meta trader software itself has a condition like this:

```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[],
{
int    i,pos;
double diff;
//---
if(Bars<=InpRSIPeriod || InpRSIPeriod<2)
return(0);
//--- counting from 0 to rates_total
ArraySetAsSeries(ExtRSIBuffer,false);
ArraySetAsSeries(ExtPosBuffer,false);
ArraySetAsSeries(ExtNegBuffer,false);
ArraySetAsSeries(close,false);
//--- preliminary calculations
pos=prev_calculated-1;
if(pos<=InpRSIPeriod)
{
//--- first RSIPeriod values of the indicator are not calculated
ExtRSIBuffer[0]=0.0;
ExtPosBuffer[0]=0.0;
ExtNegBuffer[0]=0.0;
double sump=0.0;
double sumn=0.0;
for(i=1; i<=InpRSIPeriod; i++)
{
ExtRSIBuffer[i]=0.0;
ExtPosBuffer[i]=0.0;
ExtNegBuffer[i]=0.0;
diff=close[i]-close[i-1];
if(diff>0)
sump+=diff;
else
sumn-=diff;
}
//--- calculate first visible value
ExtPosBuffer[InpRSIPeriod]=sump/InpRSIPeriod;
ExtNegBuffer[InpRSIPeriod]=sumn/InpRSIPeriod;
if(ExtNegBuffer[InpRSIPeriod]!=0.0)
ExtRSIBuffer[InpRSIPeriod]=100.0-(100.0/(1.0+ExtPosBuffer[InpRSIPeriod]/ExtNegBuffer[InpRSIPeriod]));
else
{
if(ExtPosBuffer[InpRSIPeriod]!=0.0)
ExtRSIBuffer[InpRSIPeriod]=100.0;
else
ExtRSIBuffer[InpRSIPeriod]=50.0;
}
//--- prepare the position value for main calculation
pos=InpRSIPeriod+1;
}
//--- the main loop of calculations
for(i=pos; i<rates_total && !IsStopped(); i++)
{
diff=close[i]-close[i-1];
ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(InpRSIPeriod-1)+(diff>0.0?diff:0.0))/InpRSIPeriod;
ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(InpRSIPeriod-1)+(diff<0.0?-diff:0.0))/InpRSIPeriod;
if(ExtNegBuffer[i]!=0.0)
ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
else
{
if(ExtPosBuffer[i]!=0.0)
ExtRSIBuffer[i]=100.0;
else
ExtRSIBuffer[i]=50.0;
}
}
return(rates_total);
}```

what is "the main loop of calculations" part for?

I think this part is difference part.