Here is a simple Python code that filters the dates when the RSI crosses above 80 and also computes the next 5-day, 10-day, and 20-day return. To calculate the RSI – the pandas_ta and yfinance libraries are used.
What is pandas_ta library?
The pandas_ta
(Technical Analysis) library is an extension of the popular pandas
library in Python. It provides additional functionality for performing technical analysis and provides more than 130 Indicators and Utility functions and more than 60 TA Lib Candlestick Patterns
Installing the necessary libraries
pip install yfinance
pip install pandas_ta
Simple RSI Crossover above 80 levels – python code
import yfinance as yf
import pandas as pd
import pandas_ta as ta
# Download historical data for a stock/index (e.g., ^NSEI. - Nifty 50)
ticker = '^NSEI'
df = yf.download(ticker, start="2010-01-01",end="2023-12-31")
# Calculate RSI
df['RSI'] = ta.rsi(df['Close'], length=14)
# Identify the dates where RSI crosses above 80
cross_above_80 = (df['RSI'] > 80) & (df['RSI'].shift(1) <= 80)
# Calculate returns for next 5, 10, and 20 days
df['Return_5d'] = df['Close'].pct_change(5).shift(-5)*100
df['Return_10d'] = df['Close'].pct_change(10).shift(-10)*100
df['Return_20d'] = df['Close'].pct_change(20).shift(-20)*100
# Filter rows where RSI crossed above 80
cross_above_80_df = df[cross_above_80][['RSI', 'Return_5d', 'Return_10d', 'Return_20d']]
# Round the returns to two decimals
cross_above_80_df = cross_above_80_df.round(2)
# Display the results in table format
print(cross_above_80_df)
Output
RSI Return_5d Return_10d Return_20d
Date
2010-09-15 80.01 2.21892 2.224035 6.363298
2014-04-02 80.23 0.649386 0.964082 -1.480922
2014-05-19 81.07 1.314784 1.362284 3.717191
2014-06-09 80.59 -1.581406 -2.106576 1.731636
2018-01-23 82.11 -0.505246 -5.47651 -6.324603
2020-12-17 80.77 0.062222 2.02173 5.043411
2021-01-12 80.92 -0.290452 -4.092095 3.728854
2021-08-31 82.49 1.34192 2.260364 3.380194
2022-08-12 80.48 -1.172163 -2.176781 2.101352
2023-07-20 80.57 -1.597916 -2.990618 -3.348491
2023-12-04 81.84 <NA> <NA> <NA>
Avoiding Interleaving issue to fix the t+5 return issue
If within 5 days any RSI value crosses above 80 again it will be ignored. That will fix the interleaving issues. Here is the updated Python code for the same.
import yfinance as yf
import pandas as pd
import pandas_ta as ta
# Download historical data for a stock/index (e.g., ^NSEI - NIFTY 50)
ticker = '^NSEI'
df = yf.download(ticker, start="2010-01-01")
# Calculate RSI using 'Adj Close'
df['RSI'] = ta.rsi(df['Adj Close'], length=14)
# Identify the dates where RSI crosses above 80
cross_above_80 = (df['RSI'] > 80) & (df['RSI'].shift(1) <= 80)
# Initialize columns for returns
df['Return_5d'] = pd.NA
df['Return_10d'] = pd.NA
df['Return_20d'] = pd.NA
skip_days = 0 # Days to skip after finding a cross above 80
# Calculate returns for next 5, 10, and 20 days with non-interleaving for 5-day returns
for i in range(len(df)):
if skip_days > 0:
# If any crossover happens interleaving then convert it to False
cross_above_80.iloc[i] = False
# Skip this day and decrement skip_days
skip_days -= 1
continue
if (cross_above_80.iloc[i]):
# Found a cross above 80, set skip_days
skip_days = 5
# Calculate returns
if i + 5 < len(df):
df.at[df.index[i], 'Return_5d'] = (df['Adj Close'].iloc[i + 5] / df['Adj Close'].iloc[i] - 1) * 100
if i + 10 < len(df):
df.at[df.index[i], 'Return_10d'] = (df['Adj Close'].iloc[i + 10] / df['Adj Close'].iloc[i] - 1) * 100
if i + 20 < len(df):
df.at[df.index[i], 'Return_20d'] = (df['Adj Close'].iloc[i + 20] / df['Adj Close'].iloc[i] - 1) * 100
# Filter rows where RSI crossed above 80
cross_above_80_df = df[cross_above_80][['RSI', 'Return_5d', 'Return_10d', 'Return_20d']]
# Round the returns to two decimals
cross_above_80_df = cross_above_80_df.round(2)
# Display the results in table format
print(cross_above_80_df)
Output
[*********************100%***********************] 1 of 1 completed
RSI Return_5d Return_10d Return_20d
Date
2010-09-15 80.01 2.21892 2.224035 6.363298
2014-04-02 80.23 0.649386 0.964082 -1.480922
2014-05-19 81.07 1.314784 1.362284 3.717191
2014-06-09 80.59 -1.581406 -2.106576 1.731636
2018-01-23 82.11 -0.505246 -5.47651 -6.324603
2020-12-17 80.77 0.062222 2.02173 5.043411
2021-01-12 80.92 -0.290452 -4.092095 3.728854
2021-08-31 82.49 1.34192 2.260364 3.380194
2022-08-12 80.48 -1.172163 -2.176781 2.101352
2023-07-20 80.57 -1.597916 -2.990618 -3.348491
2023-12-04 81.84 <NA> <NA> <NA>