Algorithmic Trading & Indicators
Advanced
Calculate Larry Connors RSI (CRSI) 3-Component Mean Reversion Indicator in Python
Implement Larry Connors' composite Connors RSI (CRSI) in Python Pandas combining 3-period RSI, Up/Down Streak Length RSI, and 100-day Percent Rank.
#pandas#numpy
Problem Statement
Standard 14-period RSI is too slow for short-term equity and ETF mean reversion. Connors RSI averages 3-period price momentum, consecutive up/down streak duration, and 100-bar return percentile rank to pinpoint extreme 2-to-5 day snapback setups.
Formula / Core Logic
CRSI(3, 2, 100) = [ RSI(Close, 3) + RSI(Streak, 2) + PercentRank(Ret_1d, 100) ] / 3
Buy when CRSI < 10 and Close > 200 SMA; Exit when CRSI > 70.
Installation
pip install pandas numpy
connors-rsi-crsi-mean-reversion-strategy-python.py
import pandas as pd
import numpy as np
def rsi_wilder(series, period):
delta = series.diff()
gain = delta.clip(lower=0).ewm(alpha=1/period, adjust=False).mean()
loss = (-delta.clip(upper=0)).ewm(alpha=1/period, adjust=False).mean()
rs = gain / loss.replace(0, np.nan)
return (100 - (100 / (1 + rs))).fillna(50)
def calculate_connors_rsi(df, rsi_len=3, streak_rsi_len=2, rank_len=100):
df = df.copy()
c_rsi = rsi_wilder(df['Close'], rsi_len)
# Compute consecutive up/down close streak
diff = df['Close'].diff()
streak = np.zeros(len(df))
for i in range(1, len(df)):
if diff.iloc[i] > 0:
streak[i] = streak[i-1] + 1 if streak[i-1] > 0 else 1
elif diff.iloc[i] < 0:
streak[i] = streak[i-1] - 1 if streak[i-1] < 0 else -1
else:
streak[i] = 0
s_rsi = rsi_wilder(pd.Series(streak, index=df.index), streak_rsi_len)
ret = df['Close'].pct_change()
pct_rank = ret.rolling(rank_len).apply(lambda x: (np.sum(x[:-1] < x[-1]) / (len(x) - 1)) * 100, raw=True)
df['CRSI'] = ((c_rsi + s_rsi + pct_rank) / 3.0).round(2)
return df
Get the Complete 100+ Python Quant & Automation Bundle
Instant lifetime access to all production-ready scripts, valuation models, and trading bots ($19).
Buy Full Bundle on Gumroad ($19) →Frequently Asked Questions
Q: Why should Connors RSI long entries only be taken above the 200-day SMA?
Buying oversold dips (`CRSI < 10`) strictly in stocks trading above their 200-day moving average avoids catching falling knives in structural bear trends.