Home » Three ways to calculate the RSI in Python

# Three ways to calculate the RSI in Python

One of the most widely used technical indicators in technical analysis is the Relative Strength Index. It measures the magnitude of recent price evolutions to evaluate if a price of an asset is overbought or oversold. In this blog post, I list the many ways you can calculate the RSI in Python.

🤓 Like stochastics, MACD, and ROC, RSI belongs to a group “loosely referred to as oscillators […] While the arcane names and imposing formulas of many oscillators may initially seem confusing, virtually all of these indicators are based on the concept of momentum, which, not surprisingly, refers to the rate (or speed) at which prices change.” Jack D. Schwager in Getting Started in Technical Analysis

The RSI was introduced by Welles Wilder Jr. in his 1978 book New Concepts in Technical Trading. However, there is no such thing as the relative strength index. There are many ways to calculate it. For each piece of code below, I’ll also discuss the methodological choices.

## Calculate the RSI using nothing but Pandas

In the following code chunk, there is a function that you can use to calculate RSI, using nothing but plain Python and pandas. You pass the function a DataFrame, the number of periods you want the RSI to be based on and if you’d like to use the simple moving average (SMA) or the exponential moving average (EMA). By default, it uses the EMA.

import pandas

def rsi(df, periods = 14, ema = True):
"""
Returns a pd.Series with the relative strength index.
"""
close_delta = df['close'].diff()

# Make two series: one for lower closes and one for higher closes
up = close_delta.clip(lower=0)
down = -1 * close_delta.clip(upper=0)

if ema == True:
# Use exponential moving average
ma_up = up.ewm(com = periods - 1, adjust=True, min_periods = periods).mean()
ma_down = down.ewm(com = periods - 1, adjust=True, min_periods = periods).mean()
else:
# Use simple moving average
ma_up = up.rolling(window = periods, adjust=False).mean()
ma_down = down.rolling(window = periods, adjust=False).mean()

rsi = ma_up / ma_down
rsi = 100 - (100/(1 + rsi))
return rsi

Visualized below is the difference in sensitivity between the RSI calculated with the EMA and the RSI calculated with the SMA. As you can see, there are more extremes if you use the SMA variant.

👀 Things to note regarding the ewm method:

• It is important that you use the min_periods parameter in the ewm method, in order not to calculate an RSI in the first periods of your time series, that is based on incomplete data.
• If you set the adjust parameter to True, a decaying adjustment factor will be used in the beginning of your time series. From the documentation: “Divide by decaying adjustment factor in beginning periods to account for imbalance in relative weightings (viewing EWMA as a moving average).

## Calculate RSI using the TA-lib Python wrapper

Installing TA-lib for Python can be somewhat of a nuisance, so please follow short my tutorial, especially if you use a custom notebook solution like Deepnote.

If you’re a fan of the widely used TA-lib library: good news! TA-lib supports the RSI out of the box.

import talib as ta

ta.RSI(df['close'], timeperiod=14)

TA-lib uses the same exponential moving average function as our custom function described earlier in this article. However, the first time it is calculated for a time series, it uses a simple moving average. That’s why it differs slightly at the beginning of our time series.

## Calculate RSI using the pandas-ta library

Another convenient package for technical analysis in Python is pandas-ta. Just like TA-lib, it uses an EMA version. However, here too, in the beginning of the time series, it differs from the initial function provided in this article. That’s because it uses Wilder’s Moving Average.

import pandas_ta as pta

pta.rsi(df['close'], length = 14)

It comes with extra parameters such as:

• scalar: multiply the RSI by a specific scalar — maybe you like base 1000 or 1?
• drift: instead of using the difference in closing price at each period (drift = 1), you can use the difference in closing price between periods over a longer time period. In the example below, I compare pandas-ta’s RSI with drift set to 1 and 10.

Great success!

### Say thanks, ask questions or give feedback

Technologies get updated, syntax changes and honestly… I make mistakes too. If something is incorrect, incomplete or doesn’t work, let me know in the comments below and help thousands of visitors.

## 35 thoughts on “Three ways to calculate the RSI in Python”

1. Can you guide how to calculate 14 day rsi , say I have after ohlc daily data, of past 200 days

1. df[“price_change”] = df[“close”] – df[“open”]
df[“up_move”] = df[“price_change”].apply(lambda x: x if x > 0 else 0)
df[“down_move”] = df[“price_change”].apply(lambda x: abs(x) if x < 0 else 0)
df["avg_up"] = df["up_move"].ewm(span=27).mean()
df["avg_down"] = df["down_move"].ewm(span=27).mean()
df["RS"] = df["avg_up"]/df["avg_down"]
df["RSI"] = df["RS"].apply(lambda x: 100-(100/(x+1)))

1. 27, because 2/(N+1) = 1/14 -> N = 27

2. Good article. There’s a small mistake in the first function in the if statement there should be a double equal sign. (if ema == True:)

Thanks for sharing!

1. Thanks, man. I fixed it!

1. Or you can just omit the “== True” altogether (simply yielding “if ema:”).
Thanks for sharing .. 🙂

3. Hello
I am doing some research about the RSI indicator and I often find different versions of the formula. The “official” one should be this: https://www.investopedia.com/terms/r/rsi.asp
which divides the calculation into two steps. Are there any particular differences?
Thanks

4. Thank you for the post!

5. Thank you…

6. Million dollar question, which is fastest, best, most reliable etc? I can’t get ta-lib to build a wheel on my Windows 10 machine with Python 311, so my choice is between the Python or Panda_ta version above. Thoughts? Thanks!

7. Your point of view caught my eye and was very interesting. Thanks. I have a question for you.

8. similique deserunt qui voluptatibus quisquam aperiam. a assumenda tempore quia et eaque et voluptatum ex nemo aliquam eos sint. accusamus eligendi est earum itaque quibusdam dolores nihil.

9. Шкафы предлагают вместительные
ящики https://italyanskaya-mebel.su/ и регулируемые полки.

10. everything that is for you necessary – is network.
specified provides a chance for you to manage everything from starting point,
https://www.infinito-wallet.com/, and conserve time and money.

11. in names of “https://bitcoindogs.io/”, I used some well-known cryptocurrencies and those
that I like for inspiration.

12. Heya i’m for the first time here. I came across this board and I find It truly useful & it helped
me out much. I hope to give something back and help others like you aided me.

13. Госномер на автомобиль – стиля и дизайна с логотипа или брендом
компании, фирмы, https://avto-nomeri.ru/ завода.

14. Hi my loved one! I want to say that this post is
awesome, great written and come with approximately all significant infos.

I’d like to peer extra posts like this .

15. In 2023, the twitter logo with birds was replaced with a
icon of the doge meme for you desktop computers, which led
to an increase in prices on http://doge-coin20.io/.

16. Everything is very open with a clear clarification of
the challenges. It was truly informative. Your website
is very helpful. Thanks for sharing!

17. This article will help the internet viewers for setting up new website or even a weblog from start to end.

18. I just could not leave your website prior to suggesting that I
extremely loved the standard info a person provide for your visitors?
Is gonna be again often in order to check out new posts

19. This piece of writing is actually a good one it assists new
net people, who are wishing for blogging.

20. 7espritgames – Discover the best quality urls about lottery segments.

21. Players enough https://bk-cupis.ru/.
also – do not have to worry about viruses, because
the utility is tested and protected.

22. 22kniterate – Discover the best quality urls about lottery segments.