Oscillator & Mean Reversion Patterns
RSI Dynamic Oversold
Tags: mean_reversion, rsi, dynamic_threshold, turning_point
Functions: rsi
Description: Enters when RSI is below 30 and turning up (bounce beginning). Higher win rate than a simple RSI 30 downward cross.
Code:
rsi_val = rsi(close, 14)
# RSI < 30 AND RSI is turning up
long_cond = (rsi_val < 30) & (rsi_val > rsi_val.shift(1))
# Exit when RSI > 60
exit_cond = rsi_val > 60
emit(long_cond, entry(context["ticker"], "LONG", Weight(1.0), label="RSI_REV"))
emit(exit_cond, exit_position(context["ticker"]))
Bollinger Band Reversal (Inside Bar)
Tags: mean_reversion, bbands, candle_pattern, inside_bar
Functions: bollinger_bands
Description: Enters when the previous bar touches the lower Bollinger Band and the current bar is a green candle closing back inside the band.
Code:
upper, mid, lower = bollinger_bands(close, 20, 2.0)
# Previous bar touched lower band
prev_touch = low.shift(1) <= lower.shift(1)
# Current bar is green (Close > Open) and closes above lower band
reversal_bar = (close > open) & (close > lower)
long_cond = prev_touch & reversal_bar
exit_cond = close >= mid # Exit at mean (middle band)
emit(long_cond, entry(context["ticker"], "LONG", Weight(1.0), label="BB_REV"))
emit(exit_cond, exit_position(context["ticker"]))
Stochastic Divergence Logic
Tags: mean_reversion, stochastic, divergence, advanced, cross_check
Functions: stoch
Description: Implements a bullish divergence pattern where price makes a lower low but the Stochastic oscillator makes a higher low.
Code:
ticker = context['ticker']
slowk, slowd = stoch(high, low, close, 14, 3, 3)
# Simplified divergence: price making lower low but K making higher low
# Compare current vs 5 bars ago
price_lower = low < low.shift(5)
k_higher = slowk > slowk.shift(5)
# Bullish divergence: price lower low + stochastic higher low
bullish_div = price_lower & k_higher
# Entry on K crossing above D in oversold zone
cross_up = (slowk > slowd) & (slowk.shift(1) <= slowd.shift(1))
oversold = slowk < 30
long_cond = bullish_div & cross_up & oversold
exit_cond = slowk > 80
emit(long_cond, entry(ticker, 'LONG', Weight(1.0)))
emit(exit_cond, exit_position(ticker))