Instantly share code, notes, and snippets.

# jmoz/rsi.py

Created September 27, 2019 07:41
Show Gist options
• Save jmoz/1f93b264650376131ed65875782df386 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 import pandas as pd def rsi(ohlc: pd.DataFrame, period: int = 14) -> pd.Series: """See source https://github.com/peerchemist/finta and fix https://www.tradingview.com/wiki/Talk:Relative_Strength_Index_(RSI) Relative Strength Index (RSI) is a momentum oscillator that measures the speed and change of price movements. RSI oscillates between zero and 100. Traditionally, and according to Wilder, RSI is considered overbought when above 70 and oversold when below 30. Signals can also be generated by looking for divergences, failure swings and centerline crossovers. RSI can also be used to identify the general trend.""" delta = ohlc["close"].diff() up, down = delta.copy(), delta.copy() up[up < 0] = 0 down[down > 0] = 0 _gain = up.ewm(com=(period - 1), min_periods=period).mean() _loss = down.abs().ewm(com=(period - 1), min_periods=period).mean() RS = _gain / _loss return pd.Series(100 - (100 / (1 + RS)), name="RSI")

### jmoz commented Sep 27, 2019

To calculate RSI in Python and match Tradingview calculation.

### jmoz commented Apr 18, 2020

Can confirm that this works correctly 18/04/20.

### Chene1 commented May 14, 2020

Code Result : 46.916845

### ghost commented Jun 18, 2020

I have a problem with this implementation with the amount of total candles close to the period. For example, try 20 candles with 14 period and 200 candles with the same period, you will be getting different values for common candles in these datasets.

### andyquek commented Aug 1, 2020 • edited

`` interval = mt5.TIMEFRAME_M30
time = utc_from
bars = 1000
rates = mt5.copy_rates_from(currency, interval, time, bars)
rates_frame = pd.DataFrame(rates)
rates_frame['close_time'] = rates['time']
rates_frame['time'] = pd.to_datetime(rates_frame['time'], unit='s')
df = rates_frame

``````dfnew = pd.DataFrame(df.iloc[0:1000])

close = dfnew['close']
high = dfnew['high']
low = dfnew['low']
volume = dfnew['tick_volume']
ema = EMA(close, timeperiod=7)
rsi = RSI(close, timeperiod=14)
mfi = MFI(high,low,close,volume, timeperiod=14)
atr = ATR(dfnew.high, dfnew.low, dfnew.close, timeperiod=21)

dfnew["RSI"] = rsi
dfnew["ATR"] = atr
dfnew["mfi"] = mfi

dfnew = dfnew.sort_values(by='close_time', ascending=True)
dfnew.reset_index(drop=True, inplace=True)
dfnew.set_index(np.arange(len(dfnew.index)))``
``````

Hi I'm new to python and im trying to create a trading bot. I've been using TA-lib for the RSI indicator but its quite off from tradingview. Above is my code where i pass in dataframe.

So my question is how do i use dataframe with finta?

### sword134 commented Feb 20, 2021

This no longer works. The RSI is different from Tradingviews

### lukaszbinden commented Mar 15, 2021

here is an implementation in Python that is equivalent to the current one in TradingView. Happy trading.

### Mablung commented Apr 30, 2021 • edited

here is an implementation in Python that is equivalent to the current one in TradingView. Happy trading.

Hello. I just want to know value of rsi. Can i do this by using this?

### johanekb commented Jun 10, 2021

here is an implementation in Python that is equivalent to the current one in TradingView. Happy trading.

I implemented your implemenation with data from yahoo finance. The vast majority of them work, But I found that they differ on AAPL, MSFT and WMT. Do you know why this is?

### olliebakhtiari commented Jul 23, 2021

@lukaszbinden many thanks chief

### brandonros commented Aug 7, 2022 • edited

``````pine_sma(x, y) =>
sum = 0.0
for i = 0 to y - 1
sum := sum + x[i] / y
sum
pine_rma(src, length) =>
alpha = 1/length
sum = 0.0
sum := na(sum[1]) ?
pine_sma(src, length) :
alpha * src + (1 - alpha) * nz(sum[1])
sum
pine_rsi(x, y) =>
u = math.max(x - x[1], 0) // upward ta.change
d = math.max(x[1] - x, 0) // downward ta.change
rs = pine_rma(u, y) / pine_rma(d, y)
res = 100 - 100 / (1 + rs)
res
``````