Trading Strategy
CCI Strategy
A momentum oscillator strategy using the Commodity Channel Index to identify cyclical trends and mean reversion opportunities.
Cyclical Momentum Indicator
The Commodity Channel Index (CCI) is a versatile indicator that measures how price deviates from the statistical mean. Originally designed for commodity markets, it works equally well on any financial instrument. CCI identifies cyclical trends, overbought/oversold conditions, and potential trend reversals. Combined with a 200 EMA trend filter, this strategy provides reliable entry signals.
Momentum Type
4h Chart Timeframe
Intermediate Complexity
CCI + EMA + ATR Indicators
Signal Logic
Long (Buy)
CCI crosses above oversold level (-100), price is above 200 EMA.
Short (Sell)
CCI crosses below overbought level (+100), price is below 200 EMA.
Implementation
//@version=6
strategy("CCI Strategy", overlay=true, initial_capital=1000000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
// ==========================================
// 🔹 INPUTS
// ==========================================
// Group: CCI Settings
grp_cci = "CCI Settings"
cci_len = input.int(20, "CCI Period", minval=1, group=grp_cci)
cci_oversold = input.int(-100, "Oversold Level", group=grp_cci)
cci_overbought = input.int(100, "Overbought Level", group=grp_cci)
// Group: Trend Filter
grp_trend = "Trend Filter"
use_trend = input.bool(true, "Use Trend Filter (EMA 200)", group=grp_trend)
ema_len = input.int(200, "Trend EMA Length", minval=1, group=grp_trend)
// Group: Risk Management
grp_risk = "Risk Management"
atr_len = input.int(14, "ATR Length", minval=1, group=grp_risk)
sl_mult = input.float(2.0, "Stop Loss (ATR Multiplier)", step=0.1, group=grp_risk)
tp_ratio = input.float(2.0, "Risk:Reward Ratio", step=0.1, group=grp_risk)
// ==========================================
// 🔹 CALCULATIONS
// ==========================================
// CCI Indicator
cci_val = ta.cci(close, high, low, cci_len)
// Trend EMA
ema_val = ta.ema(close, ema_len)
// ATR for risk management
atr_val = ta.atr(atr_len)
// Trend conditions
trend_up = use_trend ? close > ema_val : true
trend_down = use_trend ? close < ema_val : true
// ==========================================
// 🔹 STRATEGY LOGIC
// ==========================================
// Long Entry: CCI crosses above oversold level (bullish reversal)
long_signal = ta.crossover(cci_val, cci_oversold) and trend_up
// Short Entry: CCI crosses below overbought level (bearish reversal)
short_signal = ta.crossunder(cci_val, cci_overbought) and trend_down
// ==========================================
// 🔹 EXECUTION & RISK MANAGEMENT
// ==========================================
if long_signal
strategy.entry("Long", strategy.long, comment="L | CCI Bull")
if short_signal
strategy.entry("Short", strategy.short, comment="S | CCI Bear")
// Risk management with ATR
if strategy.position_size > 0
stop_level = strategy.position_avg_price - (atr_val * sl_mult)
profit_level = strategy.position_avg_price + (atr_val * sl_mult * tp_ratio)
strategy.exit("Exit Long", "Long", stop=stop_level, limit=profit_level, comment_loss="SL", comment_profit="TP")
if strategy.position_size < 0
stop_level = strategy.position_avg_price + (atr_val * sl_mult)
profit_level = strategy.position_avg_price - (atr_val * sl_mult * tp_ratio)
strategy.exit("Exit Short", "Short", stop=stop_level, limit=profit_level, comment_loss="SL", comment_profit="TP")
// ==========================================
// 🔹 VISUALS
// ==========================================
// Plot Trend EMA
plot(use_trend ? ema_val : na, "Trend EMA", color=color.new(color.orange, 0), linewidth=2)
// Plot CCI Reference Levels
plot(cci_overbought, "Overbought", color=color.new(color.red, 70), linestyle=plot.linestyle_dashed)
plot(cci_oversold, "Oversold", color=color.new(color.green, 70), linestyle=plot.linestyle_dashed)
plot(0, "Zero Line", color=color.new(color.gray, 80), linestyle=plot.linestyle_dashed)
// Plot Signals on price chart
plotshape(long_signal, title="Long Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY", textcolor=color.white)
plotshape(short_signal, title="Short Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL", textcolor=color.white)
// Background color for overbought/oversold zones
overbought_zone = cci_val > cci_overbought
oversold_zone = cci_val < cci_oversold
bgcolor(overbought_zone ? color.new(color.red, 95) : oversold_zone ? color.new(color.green, 95) : na)