Relative Strength Index (RSI)

Haiyue
10min

I. What is RSI

The Relative Strength Index (RSI) is one of the most widely used momentum oscillators in technical analysis. It measures the speed and magnitude of price changes by comparing the extent of upward and downward movements over a given period, thereby determining whether an asset is overbought or oversold.

Historical Background

RSI was first introduced by American technical analysis pioneer J. Welles Wilder Jr. in 1978 in his classic book New Concepts in Technical Trading Systems. Wilder also invented ATR, ADX, Parabolic SAR, and several other indicators still widely used today. Due to its elegant logic and strong practical utility, RSI quickly became a standard indicator on all major trading platforms.

Indicator Classification

  • Type: Oscillator, displayed in a separate panel
  • Category: Momentum
  • Default Parameters: Period n=14n = 14, data source is Close price
  • Value Range: 0 — 100
Common Parameter Choices
  • Short-term: RSI(7) or RSI(9) — sensitive signals, suitable for short-term trading
  • Standard: RSI(14) — Wilder’s recommended default, balancing sensitivity and stability
  • Long-term: RSI(21) or RSI(25) — fewer but more reliable signals

II. Mathematical Principles and Calculation

Core Formulas

RSI is calculated in two steps: first compute the Relative Strength (RS), then normalize it to the 0-100 range.

Step 1: Calculate price changes

ΔPt=PtPt1\Delta P_t = P_t - P_{t-1}

Separate gains and losses:

  • Gain: Ut=max(ΔPt,0)U_t = \max(\Delta P_t, 0)
  • Loss: Dt=max(ΔPt,0)D_t = \max(-\Delta P_t, 0)

Step 2: Calculate average gains/losses using Wilder Smoothing (SMMA)

The initial calculation (at period nn) uses a simple average:

Un=1ni=1nUi,Dn=1ni=1nDi\overline{U}_n = \frac{1}{n}\sum_{i=1}^{n} U_i, \quad \overline{D}_n = \frac{1}{n}\sum_{i=1}^{n} D_i

Subsequent values use Wilder’s recursive smoothing (equivalent to EMA with α=1/n\alpha = 1/n):

Ut=(n1)Ut1+Utn,Dt=(n1)Dt1+Dtn\overline{U}_t = \frac{(n-1) \cdot \overline{U}_{t-1} + U_t}{n}, \quad \overline{D}_t = \frac{(n-1) \cdot \overline{D}_{t-1} + D_t}{n}

Step 3: Calculate RS and RSI

RS=UtDtRS = \frac{\overline{U}_t}{\overline{D}_t}

RSI=1001001+RSRSI = 100 - \frac{100}{1 + RS}

Equivalent form:

RSI=100UtUt+DtRSI = \frac{100 \cdot \overline{U}_t}{\overline{U}_t + \overline{D}_t}

Step-by-Step Calculation Logic

  1. Calculate daily price changes ΔPt\Delta P_t
  2. Separate positive and negative changes: gains as positive values, losses as absolute values
  3. Initialize: compute simple averages of gains and losses for the first nn periods
  4. Recursive smoothing: update each subsequent period using Wilder’s smoothing formula
  5. RS = Average Gain / Average Loss
  6. RSI = 100 - 100/(1+RS)
Why Use Wilder Smoothing?

Wilder Smoothing (SMMA) assigns gradually decaying weights to historical data, making RSI values more stable and less prone to sharp jumps from single-day extreme movements. This smoothing method is equivalent to an EMA with a period of 2n12n-1.


III. Python Implementation

import numpy as np
import pandas as pd


def rsi(close: pd.Series, period: int = 14) -> pd.Series:
    """
    Calculate the Relative Strength Index (RSI) using Wilder Smoothing

    Parameters
    ----------
    close : pd.Series
        Close price series
    period : int
        Calculation period, default 14

    Returns
    -------
    pd.Series
        RSI values (0-100)
    """
    delta = close.diff()

    gain = delta.where(delta > 0, 0.0)
    loss = (-delta).where(delta < 0, 0.0)

    # First average uses simple mean
    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()

    # Wilder recursive smoothing
    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
    rsi_values = 100 - 100 / (1 + rs)

    return rsi_values


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

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

    # Calculate RSI
    df["RSI_14"] = rsi(df["close"], period=14)

    # Generate overbought/oversold signals
    df["signal"] = np.where(
        df["RSI_14"] > 70, -1,     # Overbought -> Sell signal
        np.where(df["RSI_14"] < 30, 1, 0)  # Oversold -> Buy signal
    )

    print("=== RSI Results (last 15 rows) ===")
    print(df[["close", "RSI_14", "signal"]].tail(15).to_string())

    print("\n=== Overbought/Oversold Signal Points ===")
    signals = df[df["signal"] != 0]
    print(signals[["close", "RSI_14", "signal"]].to_string())

IV. Problems the Indicator Solves

1. Overbought / Oversold Detection

The most classic use of RSI is identifying extreme price conditions:

ZoneConditionMeaning
OverboughtRSI > 70Excessive short-term gains, potential pullback
OversoldRSI < 30Excessive short-term losses, potential bounce
Neutral30 <= RSI <= 70No extreme signal
Caution

In strong trending markets, RSI can remain in overbought or oversold territory for extended periods. Trading against the trend based solely on overbought/oversold readings can lead to significant losses. Consider combining with trend indicators (such as ADX) to confirm whether the market is trending.

2. Divergence Signals

Divergence is one of RSI’s most valuable signals:

  • Bearish Divergence: Price makes a new high, but RSI fails to make a new high — upward momentum is weakening, potential top
  • Bullish Divergence: Price makes a new low, but RSI fails to make a new low — downward momentum is weakening, potential bottom

3. Centerline Crossover

  • RSI crosses above 50 — upward momentum is strengthening, bullish
  • RSI crosses below 50 — downward momentum is strengthening, bearish

4. Failure Swing

Wilder considered the “failure swing” to be RSI’s most reliable signal:

  • Top Failure Swing: RSI breaks above 70, pulls back, fails to break above 70 again on the next rally, then breaks below the prior low — sell
  • Bottom Failure Swing: RSI breaks below 30, bounces, fails to break below 30 again on the next decline, then breaks above the prior high — buy

V. Advantages, Disadvantages, and Use Cases

Advantages

AdvantageDescription
Clear boundariesFixed 0-100 range with intuitive overbought/oversold thresholds
Leading natureDivergence signals often precede price reversals
UniversalityApplicable to stocks, futures, forex, cryptocurrencies, and all markets
Computationally efficientRecursive formula enables very fast real-time calculation

Disadvantages

DisadvantageDescription
False signals in trendsRSI can stay in overbought/oversold zones during strong trends, invalidating reversal signals
Parameter sensitiveDifferent RSI periods produce significantly different signals; requires tuning per market
Single dimensionBased solely on price change magnitude; ignores volume and other information
Saturation problemRSI becomes stuck at high or low levels in extreme market conditions, losing reference value

Use Cases

  • Range-bound markets: RSI performs best in sideways, oscillating markets with high overbought/oversold signal accuracy
  • Divergence detection: Finding reversal opportunities at the end of trends
  • Filter: Combined with trend indicators, e.g., “only go long when RSI < 40 and price is above the 200-day moving average”
ComparisonRSIStochasticCCI
Value Range0-1000-100Unbounded
SensitivityMediumHighHigh
Best TimeframeMedium to longShortMedium
Price DataClose onlyH/L/CH/L/C
Practical Tips
  1. Multi-timeframe confirmation: Observe both daily RSI(14) and weekly RSI(14) simultaneously; signals are more reliable when both align.
  2. Dynamic thresholds: In bull markets, raise the overbought threshold to 80 and lower oversold to 40; reverse in bear markets.
  3. Combine with volume: RSI divergence + declining volume = stronger reversal signal.
  4. Avoid using alone: RSI works best as a confirmation tool, not the sole entry signal.