RSI indicator

ashishjindal89
I am trying to calculate the RSI values but they are not matching with zerodha's RSI. I am using following algo to compute RSI :
public static double getRSI(List<Candle> candles){
double avgU = 0;
double avgD = 0;
int N = candles.size();
for(int i = 0;i <N-1;i++){
double delta = candles.get(i+1).getClose() - candles.get(i).getClose();
if(delta < 0)
avgD += Math.abs(delta);
else
avgU += delta;
}
avgU = avgU/(N-1);
avgD = avgD/(N-1);
if(avgD == 0)
return 100.0;
double rs = avgU/avgD;
double rsi = 100 - 100/(1 + rs);
return rsi;
}
Please tell me where i am wrong.
  • perfectatdat
    There could be two things.

    1) Can you match your RSI values with the actual RSI from the beginning of a stock price?
    2) You can try to take the previous Average up/ average down and multiply it with N-1 and add to the current Up/down values to calculate the current average up/down values.

    The tried the above two things and i was able to get the same RSI values which Zerodha produces.
  • tahseen
    @ashishjindal89

    Zerodha Kite Chart it seems uses Exponential Weight Moving Average not Simple Moving Average.
    And I can see you are using SMA for Average Gain/Loss

    Additionally, even in SMA, you are ending up averaging last N-1 elements, while I think you are trying to find RSI of N Period. You should be taking more elements (preferably N+1 elements for N period) than exact because 1st element has no previous element to get Delta. Unless you understand that what you are getting is N-1 Period RSI
  • Vaga
    Vaga edited December 2019
    @ashishjindal89 you can check out this code. Courtesy inuvest.tech

    def addRSILayer(self, layer_name='RSI', period=14, base='Close'):
    price = self.data
    price['Diff'] = price[base].diff()

    price['gains'] = price['Diff'][price['Diff'] > 0]
    price['gains'].fillna(0, inplace=True)
    price['losses'] = price['Diff'][price['Diff'] < 0]
    price['losses'].fillna(0, inplace=True)

    # price['AvgGains'] = price['gains'].rolling(period).mean()
    price['AvgGains'] = self.EMA(price['gains'], window=int(period), alpha=True)
    # price['AvgLosses'] = abs(price['losses'].rolling(period).mean())
    price['AvgLosses'] = abs(self.EMA(price['losses'], window=int(period), alpha=True))

    price['RS'] = price['AvgGains'] / price['AvgLosses']
    price[layer_name] = (100 - 100 / (1 + price['RS']))
    price.drop(['Diff', 'gains', 'losses', 'AvgGains', 'AvgLosses', 'RS'], inplace=True)
  • infotrade
    i don't think that you can ever match RSI with Zerodha as It is all relative EMA starting from unknown date. Best solution is to fetch RSI record from third party API as there is no RSI based API available in Zerodha. I am also looking for same solution for a long time.
  • tahseen
    @infotrade depends on the RSI period. If your data size is N and your RSI period is 10% of N then even if superset size is 1 billion ticks, it doesn't matter. After few panning window of RSI of [N/10] period, error would reduce exponentially and the values would start matching
  • infotrade
    @tahseen , If we need to fetch 5 minutes candle/RSI, how far do we need to go back to match it up with Zerodha?
  • tahseen
    @infotrade how far depends on your RSI Period. If you have RSI period of N, then a 2-3 times of N would be good enough to reduce variance drastically. And if you want to further reduce variance to virtually zero you can increase the size by another N candles

    But let me tell you, the word indicator means indicating, not that you have to rely on them by way of their exact value. Whether RSI is 90% or 90.5% or 90.75%, will it really make a change in your profitability by 100x ? No, it won't
  • neckpatel
    neckpatel edited June 2021
    Can anyone please check my code and let me know where I'm doing mistake. My RSI value is not matching to Zerodha.

    public static double AddDataPoint(List dataPoints, int lookback)
    {
    double weightingMultiplier = 2.0 / (lookback + 1);
    double PreviousRsiGainLoss = 0;

    double RsiGain = 0;
    double RsiLoss = 0;

    var prevClose = dataPoints[0];
    int i;
    for (i = 1; i < dataPoints.Count - 1; i++)
    {
    if (dataPoints[i] - prevClose > 0)
    {
    var gain = ((dataPoints[i] - prevClose) * weightingMultiplier) + PreviousRsiGainLoss;
    RsiGain += gain;
    PreviousRsiGainLoss = gain;
    }
    else
    {
    var loss = ((prevClose - dataPoints[i]) * weightingMultiplier) + PreviousRsiGainLoss;
    RsiLoss += loss;
    PreviousRsiGainLoss = loss;
    }
    prevClose = dataPoints[i];
    }
    var currentRsiGain = dataPoints[i] - prevClose < 0 ? 0 : ((dataPoints[i] - prevClose) * weightingMultiplier) + PreviousRsiGainLoss;
    var currentRsiLoss = prevClose - dataPoints[i] < 0 ? 0 : ((prevClose - dataPoints[i]) * weightingMultiplier) + PreviousRsiGainLoss;
    double FinalRsiGain = ((RsiGain * 13) + currentRsiGain) / lookback;
    double FinalRsiLoss = ((RsiLoss * 13) + currentRsiLoss) / lookback;
    if (FinalRsiGain == 0) return 0;
    var rS = FinalRsiGain / FinalRsiLoss;
    double rsi = 100 - (100 / (1 + rS));
    return rsi;
    }
  • dineshgawde09
    RSI default period is 14 so if we pass historical data of 14 days or more than 14 days then not exact but we get RSI near to kites values.. This is my observation... For example... for 3 min candle of XYZ option I am getting RSI value by function 53.15 and kite showing 54.37
  • Manish963
    Manish963 edited February 2023
    @perfectatdat hi there i tried your steps on nifty feb 2023 futures with rsi 3 i can successfully calculated first 2 rsi and it matches perfectly, but for rest it just not matched can any help me
Sign In or Register to comment.