What is the Coppock Curve?
The Coppock Curve, developed by Edwin Coppock, is a momentum oscillator primarily designed to identify long-term buying opportunities in a bear market and, conversely, selling opportunities in a bull market. It typically uses monthly data to provide broad, reliable signals, though it can be applied to other timeframes. The indicator is calculated as a sum of two smoothed Rates of Change (ROC), which are then smoothed themselves using a Weighted Moving Average (WMA). Coppock created this indicator after observing that market bottoms are often preceded by a period of panic, followed by a period of calm (reflected in the ROCs), which is then smoothed to identify turning points.
In Pine Script, the Coppock Curve is a valuable tool for patient traders and investors looking for higher probability, longer-term trend reversal signals, especially after significant price movements.
Components and Calculation
The calculation of the Coppock Curve involves three main steps, using standard periods of 14, 11, and 10:
- Long-Period Rate of Change (ROC_Long): Calculate the `length1`-period Rate of Change of the closing price (e.g., 14 periods).
`ROC_Long = ((close - close[length1]) / close[length1]) * 100` - Short-Period Rate of Change (ROC_Short): Calculate the `length2`-period Rate of Change of the closing price (e.g., 11 periods).
`ROC_Short = ((close - close[length2]) / close[length2]) * 100` - Sum of ROCs: Add the two ROC values together.
`Sum_ROCs = ROC_Long + ROC_Short` - Weighted Moving Average (WMA) of Sum_ROCs: Finally, apply a `length3`-period Weighted Moving Average to the `Sum_ROCs`. This is the Coppock Curve value.
`Coppock Curve = WMA(Sum_ROCs, length3)` (e.g., 10 periods)
The curve oscillates around a zero line and typically does not have fixed overbought/oversold levels like RSI, as its primary use is zero-line crossovers and directional changes.
Basic Coppock Curve Implementation in Pine Script
Pine Script v5 provides a built-in function `ta.cci()` for Commodity Channel Index and `ta.roc()` for Rate of Change, but for Coppock Curve, we'll need to combine these or custom implement the calculation steps as `ta.coppock` is not a direct built-in function.
//@version=5
indicator("My Coppock Curve", overlay=false) // overlay=false to plot in a separate pane
// Inputs for Coppock Curve lengths (standard parameters by Edwin Coppock)
rocLongLength = input.int(14, title="Long ROC Length", minval=1)
rocShortLength = input.int(11, title="Short ROC Length", minval=1)
wmaLength = input.int(10, title="WMA Smoothing Length", minval=1)
// Calculate the two Rate of Change components
rocLong = ta.roc(close, rocLongLength)
rocShort = ta.roc(close, rocShortLength)
// Sum the two ROCs
sumRocs = rocLong + rocShort
// Apply the Weighted Moving Average to the sum
coppockCurve = ta.wma(sumRocs, wmaLength)
// Plot the Coppock Curve line
plot(coppockCurve, title="Coppock Curve", color=color.new(color.blue, 0), linewidth=2)
// Plot the Zero Line
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted)
Practical Coppock Curve Trading Strategies
1. Zero Line Crossover (Primary Signal)
The most important signal from the Coppock Curve is its crossover of the zero line. This indicates a significant shift in long-term momentum.
- Buy Signal: Coppock Curve crosses above the zero line. This suggests a new long-term bullish trend is potentially beginning or an existing bear market is ending.
- Sell Signal: Coppock Curve crosses below the zero line. This suggests a new long-term bearish trend is potentially beginning or an existing bull market is ending.
//@version=5
strategy("Coppock Curve Zero Line Strategy", overlay=true)
// Inputs for Coppock Curve lengths
rocLongLength = input.int(14, title="Long ROC Length", minval=1)
rocShortLength = input.int(11, title="Short ROC Length", minval=1)
wmaLength = input.int(10, title="WMA Smoothing Length", minval=1)
// Calculate Coppock Curve
rocLong = ta.roc(close, rocLongLength)
rocShort = ta.roc(close, rocShortLength)
sumRocs = rocLong + rocShort
coppockCurve = ta.wma(sumRocs, wmaLength)
// Plot Coppock Curve in a separate pane for visualization
plot(coppockCurve, "Coppock Curve", color.blue, display=display.pane_only)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted, display=display.pane_only)
// Define conditions for entries
longSignal = ta.crossover(coppockCurve, 0)
shortSignal = ta.crossunder(coppockCurve, 0)
// Strategy entries/exits
if (longSignal)
strategy.entry("Long", strategy.long)
if (shortSignal)
strategy.entry("Short", strategy.short)
2. Coppock Curve Trough/Peak Reversals
Beyond zero-line crossovers, a more nuanced signal involves the Coppock Curve turning upwards from a trough (especially while still below zero) or turning downwards from a peak (especially while still above zero). This can signal the very early stages of a reversal within an existing trend.
- Buy Signal (Trough Turn): Coppock Curve forms a trough (reaches a local minimum) and then turns upwards. If this happens while the curve is below the zero line, it's considered a strong long-term buying opportunity.
- Sell Signal (Peak Turn): Coppock Curve forms a peak (reaches a local maximum) and then turns downwards. If this happens while the curve is above the zero line, it's considered a strong long-term selling opportunity.
//@version=5
indicator("Coppock Curve Trough/Peak Signals", overlay=true)
// Inputs for Coppock Curve lengths
rocLongLength = input.int(14, title="Long ROC Length", minval=1)
rocShortLength = input.int(11, title="Short ROC Length", minval=1)
wmaLength = input.int(10, title="WMA Smoothing Length", minval=1)
// Calculate Coppock Curve
rocLong = ta.roc(close, rocLongLength)
rocShort = ta.roc(close, rocShortLength)
sumRocs = rocLong + rocShort
coppockCurve = ta.wma(sumRocs, wmaLength)
// Plot Coppock Curve in a separate pane
plot(coppockCurve, "Coppock Curve", color.blue)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted)
// Detect upward turn from a trough (potential buy)
bullishTurn = coppockCurve > coppockCurve[1] and coppockCurve[1] < coppockCurve[2]
// Detect downward turn from a peak (potential sell)
bearishTurn = coppockCurve < coppockCurve[1] and coppockCurve[1] > coppockCurve[2]
plotshape(bullishTurn and coppockCurve < 0, title="Bullish Turn Below Zero", location=location.belowbar, color=color.new(color.green, 0), style=shape.triangleup, size=size.small)
plotshape(bearishTurn and coppockCurve > 0, title="Bearish Turn Above Zero", location=location.abovebar, color=color.new(color.red, 0), style=shape.triangledown, size=size.small)
alertcondition(bullishTurn and coppockCurve < 0, "Coppock Bullish Turn", "Coppock Curve turning up from a trough below zero.")
alertcondition(bearishTurn and coppockCurve > 0, "Coppock Bearish Turn", "Coppock Curve turning down from a peak above zero.")
3. Divergence (Advanced Confirmation)
As with many oscillators, divergence between price and the Coppock Curve can offer strong confirmation of a potential trend reversal, suggesting that the underlying momentum is not confirming the price action.
- Bullish Divergence: Price makes a lower low, but Coppock Curve makes a higher low. This indicates weakening bearish momentum and a strong potential upward reversal.
- Bearish Divergence: Price makes a higher high, but Coppock Curve makes a lower high. This indicates weakening bullish momentum and a strong potential downward reversal.
//@version=5
indicator("Coppock Curve Divergence Scanner", overlay=true)
// Inputs for Coppock Curve lengths
rocLongLength = input.int(14, title="Long ROC Length", minval=1)
rocShortLength = input.int(11, title="Short ROC Length", minval=1)
wmaLength = input.int(10, title="WMA Smoothing Length", minval=1)
// Calculate Coppock Curve
rocLong = ta.roc(close, rocLongLength)
rocShort = ta.roc(close, rocShortLength)
sumRocs = rocLong + rocShort
coppockCurve = ta.wma(sumRocs, wmaLength)
// Plot Coppock Curve in a separate pane
plot(coppockCurve, "Coppock Curve", color.blue)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted)
// Simple divergence detection (conceptual, robust detection requires advanced pivot logic)
// This is a simplified example focusing on price vs Coppock Curve divergence.
// Bullish Divergence (Price lower low, Coppock Curve higher low)
bullishDivergence = close[2] > close[1] and close[1] > close and coppockCurve[2] < coppockCurve[1] and coppockCurve[1] < coppockCurve
// Bearish Divergence (Price higher high, Coppock Curve lower high)
bearishDivergence = close[2] < close[1] and close[1] < close and coppockCurve[2] > coppockCurve[1] and coppockCurve[1] > coppockCurve
plotshape(bullishDivergence, title="Bullish Divergence", location=location.belowbar, color=color.new(color.green, 0), style=shape.triangleup, size=size.small)
plotshape(bearishDivergence, title="Bearish Divergence", location=location.abovebar, color=color.new(color.red, 0), style=shape.triangledown, size=size.small)
alertcondition(bullishDivergence, "Bullish Coppock Divergence", "Potential bullish reversal based on Coppock Curve divergence.")
alertcondition(bearishDivergence, "Bearish Coppock Divergence", "Potential bearish reversal based on Coppock Curve divergence.")
Optimizing Coppock Curve Performance
To get the most from the Coppock Curve in Pine Script:
- Timeframe Selection: The Coppock Curve was originally designed for *monthly* charts to catch major long-term market turns. While it can be applied to weekly or even daily charts, its effectiveness diminishes on shorter timeframes where noise increases.
- Standard Parameters are Recommended: The default lengths (14, 11, 10) are well-researched and generally provide reliable signals. Significant deviation from these can alter the indicator's behavior.
- Combine with Price Action: Coppock Curve signals are strongest when confirmed by actual price action. For a buy signal, look for price breaking resistance or forming bullish candlestick patterns. For a sell signal, look for price breaking support or bearish patterns.
- Volume Confirmation: For added conviction, observe volume. A strong buy signal (Coppock crossing zero from below) is more reliable if accompanied by increasing volume.
- Avoid Choppy Markets: While the WMA smooths the curve, it can still produce false signals in prolonged sideways or highly choppy markets. It performs best in environments where clear trends develop.
Common Coppock Curve Pitfalls
- Lag: Despite its aim to reduce lag, the Coppock Curve is still a lagging indicator due to its multiple smoothing components. It will not perfectly pinpoint exact tops or bottoms.
- Not for Short-Term Trading: Using Coppock Curve for intraday or very short-term trading is generally not recommended due to its long-term nature and inherent lag.
- False Signals: Even on longer timeframes, no indicator is foolproof. The Coppock Curve can produce false signals, especially if not confirmed by other technical analysis tools.
- No Fixed Overbought/Oversold Levels: Unlike some oscillators, Coppock Curve doesn't typically rely on fixed overbought/oversold thresholds. Its primary signals are zero-line crossovers and directional changes.
- Requires Patience: Signals from the Coppock Curve on long timeframes are infrequent, requiring patience to wait for high-conviction setups.
Conclusion
The Coppock Curve is a sophisticated and highly valuable momentum oscillator in Pine Script for TradingView, particularly for long-term traders and investors. Its unique calculation, combining smoothed Rates of Change with a Weighted Moving Average, allows it to effectively filter out noise and identify significant, high-probability buying opportunities in bear markets and selling opportunities in bull markets. By understanding its construction, thoughtfully utilizing its standard parameters, and integrating its zero-line crossovers, directional turns, and divergence signals strategically with other forms of technical analysis, you can leverage the Coppock Curve to gain deeper insights into long-term market cycles and enhance your trading decisions.