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:
- Typical Price (TP): `(High + Low + Close) / 3`
- Simple Moving Average of Typical Price (SMATP): `SMA(TP, length)`
- 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`.
- 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))
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.
- Buy Signal: CCI moves below -100 and then crosses back above -100. This suggests bearish momentum is fading.
- Sell Signal: CCI moves above +100 and then crosses back below +100. This suggests bullish momentum is fading.
//@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.
- Bullish Trend: CCI crosses above the zero line. This suggests momentum is shifting to the upside.
- Bearish Trend: CCI crosses below the zero line. This suggests momentum is shifting to the downside.
//@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.
- Bullish Divergence: Price makes a lower low, but CCI makes a higher low. This indicates weakening bearish momentum and a potential upward reversal.
- Bearish Divergence: Price makes a higher high, but CCI makes a lower high. This indicates weakening bullish momentum and a potential downward reversal.
//@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:
- Parameter Tuning: The `length` parameter is crucial. While 20 is a common setting, shorter lengths (e.g., 9-14) make CCI more sensitive, generating more signals but potentially more noise. Longer lengths (e.g., 30-50) provide smoother signals but with more lag. Experiment to find optimal settings for your specific asset and timeframe.
- Adjust Extreme Levels: For very volatile assets or shorter timeframes, you might consider adjusting the overbought/oversold levels beyond +100/-100 (e.g., +200/-200) to filter for only extreme moves.
- Combine with Trend Filters: CCI can be prone to whipsaws in choppy markets. Use a trend filter (like a moving average or ADX) to confirm a clear trend before relying solely on CCI signals.
- Multi-Timeframe Analysis: Confirm CCI signals on a higher timeframe before acting on signals from a lower timeframe for added reliability.
- Confluence with Price Action: Always look for CCI signals to be confirmed by price action, such as candlestick patterns, breaks of support/resistance, or chart patterns.
Common CCI Pitfalls
- False Signals in Ranging Markets: Like most oscillators, CCI can generate numerous false overbought/oversold signals when the market is consolidating sideways.
- Lag: While CCI is designed to be responsive, it is still a lagging indicator. Signals might appear after a portion of the price move has already occurred.
- Divergence Can Be Early: Divergence is powerful but can signal a potential reversal too early, and the trend might continue for some time after the divergence appears.
- Not a Standalone Indicator: CCI should always be used as part of a broader trading system, combined with other indicators and price action analysis for confirmation.
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.