Stochastic RSI (StochRSI)

Haiyue
10min

I. What is StochRSI

The Stochastic RSI (StochRSI) is a composite indicator created by applying the Stochastic Oscillator formula to RSI values (rather than to prices). It measures the relative position of RSI within its own range over a given period, thereby amplifying the signal sensitivity of RSI.

Historical Background

StochRSI was first introduced by Tushar Chande and Stanley Kroll in 1994 in their book The New Technical Trader. They observed that standard RSI often lingers between 30-70 without triggering overbought/oversold signals in many situations. By applying the Stochastic transformation to RSI, more frequent and timely trading signals can be generated.

Indicator Classification

  • Type: Oscillator, displayed in a separate panel
  • Category: Momentum — second-order derived indicator
  • Default Parameters: RSI period =14= 14, Stochastic period =14= 14, %K smoothing =3= 3, %D smoothing =3= 3
  • Value Range: 0 — 1 (or 0 — 100)
Why StochRSI?

Standard RSI(14) typically oscillates within the 30-70 range and rarely reaches extreme values. StochRSI re-normalizes RSI values to the 0-1 range, distributing the indicator more evenly across its full range and significantly increasing the trigger frequency of overbought/oversold signals.


II. Mathematical Principles and Calculation

Core Formulas

Step 1: Calculate standard RSI

RSIt=1001001+RStRSI_t = 100 - \frac{100}{1 + RS_t}

Where RS=U/DRS = \overline{U}/\overline{D}, using Wilder Smoothing (see RSI tutorial for details).

Step 2: Apply Stochastic transformation to RSI

StochRSIt=RSItmin(RSI,n)max(RSI,n)min(RSI,n)StochRSI_t = \frac{RSI_t - \min(RSI, n)}{\max(RSI, n) - \min(RSI, n)}

Where:

  • min(RSI,n)\min(RSI, n) = lowest RSI value over the past nn periods
  • max(RSI,n)\max(RSI, n) = highest RSI value over the past nn periods
  • nn = Stochastic lookback period (default 14)

Step 3: Calculate %K and %D

%K=SMA(StochRSI,ksmooth)\%K = SMA(StochRSI, k_{smooth}) %D=SMA(%K,dsmooth)\%D = SMA(\%K, d_{smooth})

Step-by-Step Calculation Logic

  1. Calculate RSI(14): Using Wilder Smoothing
  2. Find RSI extremes: Highest and lowest RSI values over the past 14 periods
  3. Normalize: Map current RSI to the [0, 1] interval
  4. %K smoothing: Apply SMA(3) to StochRSI to get %K
  5. %D smoothing: Apply SMA(3) to %K to get %D

Mathematical Significance

StochRSI is essentially an “indicator of an indicator”:

  • RSI measures price momentum (normalized first-order derivative)
  • StochRSI measures the position of RSI momentum within its range (second-order information)

When StochRSI = 1, RSI is at its recent highest level; when StochRSI = 0, RSI is at its recent lowest level.

Value Range Note

Raw StochRSI ranges from 0-1. Some platforms multiply it by 100 to display as 0-100. When using thresholds, note the correspondence: 0.8 corresponds to 80, 0.2 corresponds to 20.


III. Python Implementation

import numpy as np
import pandas as pd


def rsi(close: pd.Series, period: int = 14) -> pd.Series:
    """Calculate RSI using Wilder Smoothing"""
    delta = close.diff()
    gain = delta.where(delta > 0, 0.0)
    loss = (-delta).where(delta < 0, 0.0)

    avg_gain = gain.copy()
    avg_loss = loss.copy()
    avg_gain.iloc[:period] = np.nan
    avg_loss.iloc[:period] = np.nan
    avg_gain.iloc[period] = gain.iloc[1:period + 1].mean()
    avg_loss.iloc[period] = loss.iloc[1:period + 1].mean()

    for i in range(period + 1, len(close)):
        avg_gain.iloc[i] = (avg_gain.iloc[i - 1] * (period - 1) + gain.iloc[i]) / period
        avg_loss.iloc[i] = (avg_loss.iloc[i - 1] * (period - 1) + loss.iloc[i]) / period

    rs = avg_gain / avg_loss
    return 100 - 100 / (1 + rs)


def stoch_rsi(close: pd.Series,
              rsi_period: int = 14,
              stoch_period: int = 14,
              k_smooth: int = 3,
              d_smooth: int = 3) -> pd.DataFrame:
    """
    Calculate Stochastic RSI

    Parameters
    ----------
    close : pd.Series
        Close price series
    rsi_period : int
        RSI calculation period, default 14
    stoch_period : int
        Stochastic lookback period, default 14
    k_smooth : int
        %K smoothing period, default 3
    d_smooth : int
        %D smoothing period, default 3

    Returns
    -------
    pd.DataFrame
        DataFrame with StochRSI, %K, and %D columns
    """
    rsi_values = rsi(close, rsi_period)

    rsi_min = rsi_values.rolling(window=stoch_period, min_periods=stoch_period).min()
    rsi_max = rsi_values.rolling(window=stoch_period, min_periods=stoch_period).max()

    stoch_rsi_raw = (rsi_values - rsi_min) / (rsi_max - rsi_min)

    k = stoch_rsi_raw.rolling(window=k_smooth, min_periods=k_smooth).mean()
    d = k.rolling(window=d_smooth, min_periods=d_smooth).mean()

    return pd.DataFrame({
        "StochRSI": stoch_rsi_raw,
        "K": k,
        "D": d
    }, index=close.index)


# ========== Usage Example ==========
if __name__ == "__main__":
    np.random.seed(42)
    dates = pd.date_range("2024-01-01", periods=150, freq="D")
    price = 100 + np.cumsum(np.random.randn(150) * 1.2)

    df = pd.DataFrame({
        "date": dates,
        "open":  price + np.random.randn(150) * 0.3,
        "high":  price + np.abs(np.random.randn(150) * 0.8),
        "low":   price - np.abs(np.random.randn(150) * 0.8),
        "close": price,
        "volume": np.random.randint(1000, 10000, size=150),
    })
    df.set_index("date", inplace=True)

    # Calculate StochRSI
    result = stoch_rsi(df["close"])
    df = pd.concat([df, result], axis=1)

    print("=== StochRSI Results (last 15 rows) ===")
    print(df[["close", "StochRSI", "K", "D"]].tail(15).to_string())

    # Overbought/Oversold signals
    df["signal"] = np.where(
        (df["K"] > 0.8) & (df["D"] > 0.8), -1,
        np.where((df["K"] < 0.2) & (df["D"] < 0.2), 1, 0)
    )
    signals = df[df["signal"] != 0]
    print("\n=== Overbought/Oversold Signals ===")
    print(signals[["close", "K", "D", "signal"]].head(15).to_string())

IV. Problems the Indicator Solves

1. Enhanced RSI Sensitivity

Standard RSI(14) spends most of its time drifting between 40-60, while StochRSI frequently reaches the extreme values of 0 and 1, providing more trading opportunities.

2. Overbought / Oversold Detection

ZoneConditionMeaning
Overbought%K > 0.8 and %D > 0.8RSI is at a relatively high level recently
Oversold%K < 0.2 and %D < 0.2RSI is at a relatively low level recently

3. Crossover Signals

  • %K crosses above %D (in oversold zone) — Buy signal
  • %K crosses below %D (in overbought zone) — Sell signal

4. Short-Term Timing

Since StochRSI is more sensitive than RSI, it is particularly suited for precise entry timing after the trend direction has already been confirmed.

Caution

StochRSI has a high signal frequency but also significant noise; the false signal rate when used alone is high. It must be combined with trend filters and other confirmation tools.


V. Advantages, Disadvantages, and Use Cases

Advantages

AdvantageDescription
Extremely sensitiveTriggers signals far more frequently than standard RSI
Uniform distributionMore evenly distributed in the 0-1 range, making thresholds easier to set
Precise timingIdeal for finding optimal entries after a trend is confirmed
Rich signalsDual signal system of overbought/oversold + crossovers

Disadvantages

DisadvantageDescription
High noiseHigh sensitivity brings more false signals
VolatileJumps rapidly between 0 and 1, requires smoothing
Second-order derivativeAs an indicator of an indicator, relationship to price is indirect
Many parametersFour parameters require tuning, increasing overfitting risk

Use Cases

  • Intraday trading: High sensitivity suits short-cycle operations
  • Entry timing: Use StochRSI to find precise entries after trend direction is confirmed
  • Paired with trend indicators: Works best with MACD, ADX, and other trend indicators
ComparisonStochRSIRSIStochastic
SensitivityVery highMediumHigh
False signal rateHighLowMedium
Best timeframeShort-termMedium to longShort-term
Data sourceRSI valuesClose priceH/L/C
Practical Tips
  1. Must pair with trend indicators: Using StochRSI alone produces too many false signals; combine with MACD or ADX.
  2. Smoothing parameters matter: The %K and %D smoothing periods (default 3) can be increased to reduce noise.
  3. Extreme value confirmation: When both %K and %D enter overbought/oversold territory simultaneously, the signal is more reliable than a single line.
  4. Suited for mean reversion strategies: In range-bound markets, StochRSI is an excellent reversal signal tool.