It looks like you're new here. If you want to get involved, click one of these buttons!
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.
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.
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
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)
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
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;
}