Skip to content
Open RaamTrade

StochasticRSI — Stochastic RSI

The stochastic applied to RSI instead of price: where RSI sits inside its own recent range, smoothed to %K and %D. Faster and twitchier than either parent — it pins to 0 or 100 for long stretches in a trend.

Signature

StochasticRSI(rsi_period, stoch_period, smooth_k, smooth_d, on=<source>)
Argument Type Required Notes
rsi_period int Param or literal Yes The RSI’s Wilder lookback. Default 14, bounds 2–100.
stoch_period int Param or literal Yes The stochastic window over RSI. Default 14, bounds 1–100.
smooth_k int Param or literal Yes SMA on raw stoch-RSI for %K. Default 3, bounds 1–50.
smooth_d int Param or literal Yes SMA on %K for %D. Default 3, bounds 1–50.
on= symbol, OHLCV field, or indicator No Source. Defaults to the trade symbol’s close.

Formula

$$ \text{StochRSI} = 100,\frac{RSI - \min(RSI, n)}{\max(RSI, n) - \min(RSI, n)}, \quad %K = \text{SMA}(\text{StochRSI}, s_k), \quad %D = \text{SMA}(%K, s_d) $$

RSI is computed internally with Wilder smoothing, seeded by the simple average of the first rsi_period changes.

Warmup

Stacks: rsi_period + stoch_period + smooth_k + smooth_d bars to full accuracy; 50 (neutral) during the RSI seed, and 50 when RSI is flat across the window.

Reading the value

sr.k
sr.d
sr.k < 20

Multi-value: cannot be chained onto or crossed.

Example

class StochRsiTimer(Strategy):
"""Buy the reset: StochRSI %K under 20 in a rising market."""
trade = Symbol()
sizing = FixedCapital()
def execute(self):
sr = StochasticRSI(14, 14, 3, 3, on=self.trade)
trend = SMA(100, on=self.trade)
if sr.k < 20 and self.trade.close > trend.value and self.trade.is_flat:
self.buy(self.trade, reason=f"StochRSI reset {sr.k:.0f}")
if sr.k > 80 and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="StochRSI stretched")

Notes

  • Chande & Kroll, The New Technical Trader (1994).
  • Because the RSI recursion carries state, the first ~3×rsi_period bars differ slightly from an implementation warmed on different history; values converge geometrically.
  • Proven by an assert-via-trade run on SPY daily: %D matched the average of the indicator’s own %K history exactly; %K stayed in [0, 100]; and both outputs converged to an independent strategy-side replication within 2 points once warm (zero alarm trades).