Pine Script CCI (Commodity Channel Index)

Master this versatile momentum oscillator in TradingView's Pine Script for identifying overbought/oversold conditions, new trends, and reversals.

Last Updated on: Expertise: Intermediate

What is the Commodity Channel Index (CCI)?

The Commodity Channel Index (CCI), developed by Donald Lambert, is a versatile momentum-based oscillator that measures the current price level relative to an average price level over a given period. It's designed to identify cyclical turns in commodities, but it can be applied to any financial instrument. CCI typically oscillates around a zero line and usually moves between -100 and +100, though it can move beyond these bounds during strong trends.

In Pine Script, CCI is a powerful tool for discerning new trends, extreme overbought/oversold conditions, and potential reversals by highlighting when price deviates significantly from its statistical mean.

Components and Calculation

The calculation of CCI involves several steps:

  1. Typical Price (TP): `(High + Low + Close) / 3`
  2. Simple Moving Average of Typical Price (SMATP): `SMA(TP, length)`
  3. Mean Deviation: This is the average of the absolute deviations of the Typical Price from the SMATP over the `length` period.
    • For each bar, calculate `abs(TP - SMATP)`.
    • Sum these absolute deviations over the `length` period.
    • Divide the sum by `length`.
  4. CCI Formula: `CCI = (TP - SMATP) / (0.015 * Mean Deviation)`

The constant `0.015` is a scaling factor used to ensure that approximately 70% to 80% of CCI values fall within the +100 to -100 range.

Basic CCI Implementation in Pine Script

Pine Script v5 provides a straightforward built-in function `ta.cci()` for calculating the Commodity Channel Index.

//@version=5
indicator("My CCI Indicator", overlay=false) // overlay=false to plot in a separate pane

// Input for CCI length
length = input.int(20, title="CCI Length", minval=1)

// Calculate CCI value using the built-in function
// ta.cci calculates based on Typical Price (TP = (high+low+close)/3) internally
cciValue = ta.cci(hlc3, length) // hlc3 refers to (high+low+close)/3

// Plot the CCI line
plot(cciValue, title="CCI", color=color.new(color.blue, 0), linewidth=2)

// Plot horizontal lines for overbought and oversold levels
h_overbought = hline(100, "Overbought (+100)", color=color.new(color.red, 0), linestyle=hline.style_dashed)
h_oversold = hline(-100, "Oversold (-100)", color=color.new(color.green, 0), linestyle=hline.style_dashed)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dotted)

// Fill background between CCI and levels for visual clarity
fill(h_overbought, h_oversold, color=color.new(color.gray, 90))

Key Interpretation: Values above +100 suggest an uptrend, while values below -100 suggest a downtrend. Returns to the 0-line or crossovers can signal reversals.

Practical CCI Trading Strategies

1. Overbought and Oversold Conditions (Trend Reversals)

When CCI moves significantly above +100, it's considered overbought, indicating a strong upward move that might be unsustainable and due for a pullback. Conversely, a move significantly below -100 is oversold, suggesting a strong downward move that might be exhausted.

//@version=5
strategy("CCI Overbought/Oversold Strategy", overlay=true)

// Inputs for CCI
length = input.int(20, title="CCI Length", minval=1)
overboughtLevel = input.int(100, title="Overbought Level")
oversoldLevel = input.int(-100, title="Oversold Level")

// Calculate CCI
cciValue = ta.cci(hlc3, length)

// Define conditions for entries and exits
longCondition = ta.crossunder(cciValue, oversoldLevel) // CCI goes oversold
longExitCondition = ta.crossover(cciValue, oversoldLevel) // CCI exits oversold (potential buy)

shortCondition = ta.crossover(cciValue, overboughtLevel) // CCI goes overbought
shortExitCondition = ta.crossunder(cciValue, overboughtLevel) // CCI exits overbought (potential sell)

// Strategy entries/exits (entry upon exiting extreme zones)
if (longExitCondition)
    strategy.entry("Long", strategy.long)

if (shortExitCondition)
    strategy.entry("Short", strategy.short)

// Optional: Plot CCI in a separate pane for visualization
// plot(cciValue, "CCI", color.blue)
// hline(overboughtLevel, "Overbought", color.red)
// hline(oversoldLevel, "Oversold", color.green)
// hline(0, "Zero Line", color.gray)

2. CCI Zero Line Crossover (Trend Identification)

The zero line can be used to identify new trends or a continuation of the current trend.

//@version=5
strategy("CCI Zero Line Crossover Strategy", overlay=true)

// Inputs for CCI
length = input.int(20, title="CCI Length", minval=1)
zeroLine = 0

// Calculate CCI
cciValue = ta.cci(hlc3, length)

// Define conditions for entries
longSignal = ta.crossover(cciValue, zeroLine)
shortSignal = ta.crossunder(cciValue, zeroLine)

// Strategy entries/exits
if (longSignal)
    strategy.entry("Long", strategy.long)

if (shortSignal)
    strategy.entry("Short", strategy.short)

// Optional: Plot CCI in a separate pane
// plot(cciValue, "CCI", color.blue)
// hline(zeroLine, "Zero Line", color.gray)

3. CCI Divergence Strategy

Divergence between price and CCI can signal potential trend reversals. This occurs when price makes a new high/low, but CCI fails to confirm it, creating an opposite extreme.

//@version=5
indicator("CCI Divergence Scanner", overlay=true)

// Inputs for CCI
length = input.int(20, title="CCI Length", minval=1)
overboughtLevel = input.int(100, title="Overbought Level")
oversoldLevel = input.int(-100, title="Oversold Level")

// Calculate CCI
cciValue = ta.cci(hlc3, length)

// Plot CCI in a separate pane
plot(cciValue, "CCI", color.blue)
hline(overboughtLevel, "Overbought (+100)", color.red)
hline(oversoldLevel, "Oversold (-100)", color.green)
hline(0, "Zero Line", color.gray)

// Simple divergence detection (conceptual, robust detection requires advanced pivot logic)
// This is a simplified example and might need refinement for actual trading.

// Bullish Divergence (Price lower low, CCI higher low)
bullishDivergence = close[2] > close[1] and close[1] > close and cciValue[2] < cciValue[1] and cciValue[1] < cciValue

// Bearish Divergence (Price higher high, CCI lower high)
bearishDivergence = close[2] < close[1] and close[1] < close and cciValue[2] > cciValue[1] and cciValue[1] > cciValue

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 CCI Divergence", "Potential bullish reversal based on CCI divergence.")
alertcondition(bearishDivergence, "Bearish CCI Divergence", "Potential bearish reversal based on CCI divergence.")

Optimizing CCI Performance

To get the most from the Commodity Channel Index in Pine Script:

Trend vs. Overbought/Oversold: Remember that CCI can be used both to identify overbought/oversold conditions *and* to confirm the strength of a trend (when it stays consistently above +100 or below -100).

Common CCI Pitfalls

Conclusion

The Commodity Channel Index (CCI) is a highly versatile and valuable momentum oscillator in Pine Script for TradingView. Its ability to measure how far price has deviated from its average allows traders to identify overbought/oversold conditions, gauge trend strength, and spot potential reversals through divergence. By understanding its calculation, thoughtfully tuning its parameters, and integrating it strategically with other technical analysis tools, you can leverage the CCI to gain deeper insights into market dynamics and enhance your trading decisions.