## What is the Relative Strength Index?

The Relative Strength Index (RSI) on a stock is a technical indicator.

The relative strength index (RSI) is a momentum indicator used in technical analysis that measures the magnitude of recent price changes to evaluate overbought or oversold conditions in the price of a stock or other asset.

https://www.investopedia.com/terms/r/rsi.asp

A technical indicator is a mathematical calculation based on past prices and volumes of a stock. The RSI has a value between 0 and 100. It is said to be overbought if above 70, and oversold if below 30.

## Step 1: How to calculate the RSI

To be quite honest, I found the description on investopedia.org a bit confusing. Therefore I went for the Wikipedia description of it. It is done is a couple of steps, so let us do the same.

- If previous price is lower than current price, then set the values.
**U = close_now – close_previous****D = 0**

- While if the previous price is higher than current price, then set the values
**U = 0****D = close_previous – close_now**

- Calculate the Smoothed or modified moving average (SMMA) or the exponential moving average (EMA) of
**D**and**U**. To be aligned with the Yahoo! Finance, I have chosen to use the (EMA). - Calculate the relative strength (
**RS**)**RS = EMA(U)/EMA(D)**

- Then we end with the final calculation of the Relative Strength Index (
**RSI**).**RSI = 100 – (100 / (1 + RSI))**

Notice that the **U** are the price difference if positive otherwise 0, while **D** is the absolute value of the the price difference if negative.

## Step 2: Get a stock and calculate the RSI

We will use the Pandas-datareader to get some time series data of a stock. If you are new to using Pandas-datareader we advice you to read this tutorial.

In this tutorial we will use Twitter as an examples, which has the **TWTR **ticker. It you want to do it on some other stock, then you can look up the ticker on Yahoo! Finance here.

Then below we have the following calculations.

```
import pandas_datareader as pdr
import datetime as dt
ticker = pdr.get_data_yahoo("TWTR", dt.datetime(2020,1,1), dt.datetime.now())
delta = ticker['Close'].diff()
up = delta.clip(lower=0)
down = -1*delta.clip(upper=0)
ema_up = up.ewm(com=13, adjust=False).mean()
ema_down = down.ewm(com=13, adjust=False).mean()
rs = ema_up/ema_down
print(ticker)
```

To have a naming that is close to the definition and also aligned with Python, we use **up **for **U** and **down **for **D**.

This results in the following output.

```
High Low Open ... Volume Adj Close RSI
Date ...
2020-01-02 32.500000 31.959999 32.310001 ... 10721100 32.299999 NaN
2020-01-03 32.099998 31.260000 31.709999 ... 14429500 31.520000 0.000000
2020-01-06 31.709999 31.160000 31.230000 ... 12582500 31.639999 1.169582
2020-01-07 32.700001 31.719999 31.799999 ... 13712900 32.540001 9.699977
2020-01-08 33.400002 32.349998 32.349998 ... 14632400 33.049999 14.218360
... ... ... ... ... ... ... ...
2020-08-11 39.000000 36.709999 37.590000 ... 20486000 37.279999 58.645030
2020-08-12 38.000000 36.820000 37.500000 ... 11013300 37.439999 59.532873
2020-08-13 38.270000 37.369999 37.430000 ... 13259400 37.820000 61.639293
2020-08-14 37.959999 37.279999 37.740002 ... 10377300 37.900002 62.086731
2020-08-17 38.090000 37.270000 37.950001 ... 10186900 37.970001 62.498897
```

This tutorial was written 2020-08-18, and comparing with the RSI for twitter on Yahoo! Finance.

As you can see in the lower left corner, the RSI for the same ending day was 62.50, which fits the calculated value. Further checks reveal that they also fit the values of Yahoo.

## Step 3: Visualize the RSI with the daily stock price

We will use the matplotlib library to visualize the RSI with the stock price. In this tutorial we will have two rows of graphs by using the subplots function. The function returns an array of axis (along with a figure, which we will not use).

The axis can be parsed to the Pandas DataFrame plot function.

```
import pandas_datareader as pdr
import datetime as dt
import matplotlib.pyplot as plt
ticker = pdr.get_data_yahoo("TWTR", dt.datetime(2019,1,1), dt.datetime.now())
delta = ticker['Close'].diff()
up = delta.clip(lower=0)
down = -1*delta.clip(upper=0)
ema_up = up.ewm(com=13, adjust=False).mean()
ema_down = down.ewm(com=13, adjust=False).mean()
rs = ema_up/ema_down
ticker['RSI'] = 100 - (100/(1 + rs))
# Skip first 14 days to have real values
ticker = ticker.iloc[14:]
print(ticker)
fig, (ax1, ax2) = plt.subplots(2)
ax1.get_xaxis().set_visible(False)
fig.suptitle('Twitter')
ticker['Close'].plot(ax=ax1)
ax1.set_ylabel('Price ($)')
ticker['RSI'].plot(ax=ax2)
ax2.set_ylim(0,100)
ax2.axhline(30, color='r', linestyle='--')
ax2.axhline(70, color='r', linestyle='--')
ax2.set_ylabel('RSI')
plt.show()
```

Also, we we remove the x-axis of the first graph (**ax1**). Adjust the y-axis of the second graph (**ax2**). Also, we have set two horizontal lines to indicate overbought and oversold at 70 and 30, respectively. Notice, that Yahoo! Finance use 80 and 20 as indicators by default.

i think there is a basic typo / error in the RSI formula:

instead of:

RSI = 100 – (100 / (1 – RSI))

it should be:

RSI = 100 – (100 / (1 + RSI))

Hi,

Yes, I can see that. Thank you for letting me know. I have updated it now.

Cheers,

Rune

Thanks Rune, fantastic job! I’d like to develop a Strategic (backtesting) where we buy in 30 and sell when go down 70, but I’m not getting😔. Could you give me the key to get it?

Hi Hugo,

Great question.

If I understand you want to create a “Signal” when to BUY, SELL, or KEEP.

This can be done as follows:

`ticker['Signal'] = 'KEEP'`

ticker.loc[ticker['RSI'] > 70, 'Signal'] = 'SELL'

ticker.loc[ticker['RSI'] < 30, 'Signal'] = 'BUY'

Cheers,

Rune