Coppock Curve

Haiyue
10min

I. What is the Coppock Curve

The Coppock Curve (also known as the Coppock Indicator) is a long-term momentum indicator that applies a Weighted Moving Average (WMA) to the sum of two Rate of Change (ROC) values with different periods, in order to identify major market bottoms and the beginning of long-term bull markets. It was designed as a monthly-timeframe indicator, primarily used to determine when the market is recovering from a significant decline.

Historical Background

The Coppock Curve was invented by Edwin Sedgwick Coppock in 1962 and first published in Barron’s magazine. Interestingly, Coppock consulted bishops of the Episcopal Church and asked about the average time people need to recover from the loss of a loved one (11–14 months). He applied this “mourning period” to the market — believing that the market’s recovery from a bear market bottom follows a process similar to human psychological recovery. This is why he chose 11 months and 14 months as the ROC periods.

Indicator Classification

  • Type: Oscillator, displayed in a separate panel
  • Category: Momentum — long-term indicator
  • Default Parameters: WMA period =10= 10, long ROC =14= 14, short ROC =11= 11
  • Value Range: Unbounded, oscillates around the zero line
  • Original Design Timeframe: Monthly
What Makes the Coppock Curve Unique

This is one of the very few technical indicators designed based on “human psychological recovery cycles.” It does not seek frequent trades, but instead focuses on capturing major market bottoms — generating signals only once every several years.


II. Mathematical Principles and Calculation

Core Formula

Step 1: Calculate two ROC values with different periods

ROC14,t=CtCt14Ct14×100ROC_{14,t} = \frac{C_t - C_{t-14}}{C_{t-14}} \times 100

ROC11,t=CtCt11Ct11×100ROC_{11,t} = \frac{C_t - C_{t-11}}{C_{t-11}} \times 100

Step 2: Sum

Sumt=ROC14,t+ROC11,tSum_t = ROC_{14,t} + ROC_{11,t}

Step 3: Calculate Weighted Moving Average (WMA)

Coppockt=WMA(Sum,10)t=i=09(10i)Sumtii=09(10i)Coppock_t = WMA(Sum, 10)_t = \frac{\sum_{i=0}^{9} (10-i) \cdot Sum_{t-i}}{\sum_{i=0}^{9} (10-i)}

The WMA weights are: w0=10,w1=9,w2=8,,w9=1w_0 = 10, w_1 = 9, w_2 = 8, \ldots, w_9 = 1, with a denominator of 10+9+8++1=5510+9+8+\cdots+1 = 55.

Step-by-Step Calculation Logic

  1. Calculate ROC(14): Percentage change between current price and price 14 periods ago
  2. Calculate ROC(11): Percentage change between current price and price 11 periods ago
  3. Add them together: ROC(14) + ROC(11)
  4. WMA(10): Apply a 10-period weighted moving average to the sum

Why Use WMA?

WMA (Weighted Moving Average) assigns greater weight to recent data, providing better responsiveness to recent changes while maintaining smoothness. Compared to SMA, WMA turning points appear earlier.

Monthly vs Daily

Coppock’s original design uses monthly data (ROC measured in months). If applied to daily charts, parameters should be adjusted to approximately 294 days (14 months × 21 trading days) and 231 days (11 × 21), with WMA at 210 days (10 × 21). However, many traders use shorter periods on daily charts.


III. Python Implementation

import numpy as np
import pandas as pd


def wma(series: pd.Series, period: int) -> pd.Series:
    """Calculate Weighted Moving Average (WMA)"""
    weights = np.arange(1, period + 1, dtype=float)
    return series.rolling(window=period, min_periods=period).apply(
        lambda x: np.dot(x, weights) / weights.sum(), raw=True
    )


def coppock_curve(close: pd.Series,
                  wma_period: int = 10,
                  long_roc: int = 14,
                  short_roc: int = 11) -> pd.Series:
    """
    Calculate Coppock Curve

    Parameters
    ----------
    close : pd.Series
        Close price series (monthly data recommended)
    wma_period : int
        WMA period, default 10
    long_roc : int
        Long ROC period, default 14
    short_roc : int
        Short ROC period, default 11

    Returns
    -------
    pd.Series
        Coppock Curve values
    """
    roc_long = ((close - close.shift(long_roc)) / close.shift(long_roc)) * 100
    roc_short = ((close - close.shift(short_roc)) / close.shift(short_roc)) * 100

    roc_sum = roc_long + roc_short

    return wma(roc_sum, wma_period)


# ========== Usage Example ==========
if __name__ == "__main__":
    np.random.seed(42)

    # Simulate monthly data (5 years = 60 months)
    dates = pd.date_range("2019-01-01", periods=60, freq="ME")
    # Simulate a decline-then-recovery market cycle
    decline = np.linspace(0, -30, 20)
    recovery = np.linspace(-30, 20, 40)
    trend = np.concatenate([decline, recovery])
    noise = np.cumsum(np.random.randn(60) * 2)
    price = 100 + trend + noise

    df = pd.DataFrame({
        "date": dates,
        "close": price,
    })
    df.set_index("date", inplace=True)

    # Calculate Coppock Curve
    df["Coppock"] = coppock_curve(df["close"])

    print("=== Coppock Curve Results ===")
    print(df[["close", "Coppock"]].dropna().to_string())

    # Buy signal: Coppock turns up while below zero
    df["prev_coppock"] = df["Coppock"].shift(1)
    buy_signal = (
        (df["Coppock"] > df["prev_coppock"]) &  # Turning up
        (df["Coppock"] < 0)                       # Still below zero
    ) & (
        (df["prev_coppock"] <= df["Coppock"].shift(2))  # Previous period was declining
    )

    print("\n=== Buy Signals (Turning Up Below Zero) ===")
    print(df.loc[buy_signal, ["close", "Coppock"]].to_string())

IV. Problems the Indicator Solves

1. Identifying Major Market Bottoms

The Coppock Curve’s core use case is identifying the bottom area of major bear markets. When the curve turns upward while below the zero line, it suggests the market is recovering from a deep decline.

2. Long-term Buy Signals

Classic buy signal:

  • Coppock Curve is below the zero line (market has experienced a significant decline)
  • The curve’s direction changes from declining to rising (turns upward)
  • This signal indicates long-term momentum is recovering from the bottom

3. Bull Market Confirmation

When the Coppock Curve crosses above the zero line from negative territory, it confirms the long-term trend has shifted from bearish to bullish.

4. Sell Reference

Although Coppock originally designed the indicator as a buy-only tool, traders also use it in reverse:

  • Curve turns down while above the zero line -> sell warning
  • Curve crosses below zero -> long-term trend may be turning bearish
Note

The Coppock Curve is an extremely low-frequency signal tool. On the S&P 500 monthly chart, it may generate a buy signal only once every few years. Do not attempt to use it for short-term trading or frequent operations.


V. Advantages, Disadvantages, and Use Cases

Advantages

AdvantageDescription
Focused on major bottomsDesigned specifically to capture major market bottoms, historically validated
Very few false signalsLow-frequency signals naturally filter out most market noise
Unique logicDesign philosophy based on human psychological recovery cycles
High historical win rateBuy signals on the S&P 500 monthly chart have a very high historical win rate

Disadvantages

DisadvantageDescription
Very few signalsMay produce only one signal every several years, low daily utility
Monthly onlyOriginally designed for monthly charts; daily use requires major parameter adjustments
Significant lagLong-period ROC + WMA results in severely lagging signals
Not a sell indicatorOriginal design only provides buy signals; selling requires additional judgment

Use Cases

  • Long-term investors: Suitable for strategic position-building decisions measured in years
  • Index investing: Works best on broad-based indices (e.g., S&P 500, CSI 300)
  • Supplementary macro judgment: As a reference tool for judging major market cycle turning points
ComparisonCoppockMACDRSI
Time scaleMonthly/yearlyDaily/weeklyDaily/weekly
Signal frequencyVery lowMediumHigh
Best forLong-term positioningSwing tradingShort/medium-term
Best asset typeBroad indicesStocks/indicesStocks/ETFs
Practical Advice
  1. Monthly is king: Stick to using the Coppock Curve on monthly charts; its effectiveness on daily charts has not been fully validated.
  2. Combine with fundamentals: Coppock buy signal + leading economic indicators bottoming out = higher confidence long-term buy opportunity.
  3. Scale into positions: Don’t go all-in when the signal appears; build positions gradually over 3–6 months.
  4. Use other tools for selling: Coppock’s sell signals are less reliable than its buy signals. Consider using the 200-day moving average or monthly MACD to assist with sell decisions.