Mean-Reversion Strategies
Learn to profit from prices that extreme amounts from their average, expecting them to bounce back.
Mean-Reversion: Buy the Dip
What goes down must come up—unless the company has broken structurally. Mean-reversion strategies capitalize on temporary extremes, betting on a return to normal.
RSI Mean-Reversion
RSI extreme values predict reversals
# RSI mean reversion
df['RSI'] = calculate_rsi(df['Close'], 14)
df['Signal'] = 0
df.loc[df['RSI'] < 30, 'Signal'] = 1 # Buy oversold
df.loc[df['RSI'] > 70, 'Signal'] = -1 # Sell overbought
df.loc[(df['RSI'] > 30) & (df['RSI'] < 70), 'Signal'] = 0 # Exit
# Take profits at RSI = 50 (mean)
df.loc[df['RSI'] == 50, 'Exit'] = True
Bollinger Band Bounce
Buy when price touches the lower band (oversold). Sell when price returns to the middle band or upper band.
bb_length = 20
bb_std = 2
df['SMA'] = df['Close'].rolling(bb_length).mean()
df['STD'] = df['Close'].rolling(bb_length).std()
df['Upper_BB'] = df['SMA'] + (bb_std * df['STD'])
df['Lower_BB'] = df['SMA'] - (bb_std * df['STD'])
# Buy at lower band, sell at SMA
df['Signal'] = 0
df.loc[df['Close'] < df['Lower_BB'], 'Signal'] = 1 # Buy
df.loc[df['Close'] > df['SMA'], 'Signal'] = -1 # Sell
Z-Score Reversion
How many standard deviations from the mean
z > 2 or < -2 indicates an extreme. z > 3 is VERY extreme. These tend to revert quickly.
Market Regime Matters
Mean-reversion works in RANGE-BOUND markets. Breaks down in TRENDING markets.
- Strong uptrend: "oversold" continues moving down (no reversion)
- Strong downtrend: "overbought" continues moving up... wait no, down
- Sideways/choppy market: Perfect for mean reversion (many bounces)
The Mean-Reversion Killer Trade
You buy an oversold stock thinking "this has to bounce." Instead, it keeps falling 50% more. It hasn't reverted to the mean—the company went bankrupt. Always use a stop-loss. Always have a time limit on the trade.
Regime Detection: Trade When Your Strategy Fits
Use a trend indicator to know when to trade mean-reversion vs. trend-following.
# Only use mean-reversion in choppy markets
df['Trend'] = np.where(df['Close'] > df['SMA_200'], 'UP', 'DOWN')
# Mean reversion only when market is not too trendy
df['Use_MR_Signal'] = (df['RSI'] < 30) & (df['Trend'] == 'SIDEWAYS')
Combine with Time Limit
Mean-reversion works best with a fixed time exit: "Hold for 3-5 days, then exit regardless." This prevents being in the trade when it trends further against you.
- Mean reversion: prices that move far from average tend to revert
- RSI < 30 and > 70 are reliable overbought/oversold signals
- Bollinger Band bounces work well in range-bound markets
- Mean reversion fails in strong directional moves (best used with filters)