CCI — Commodity Channel Index
תוכן זה אינו זמין עדיין בשפה שלך.
Typical-price deviation from its own average, scaled by mean absolute deviation. Single value, unbounded, ±100 classic thresholds.
Signature
CCI(period, on=<source>)| Argument | Type | Required | Notes |
|---|---|---|---|
period |
int Param or literal | Yes | Lookback. Default 20, bounds 2–200. |
on= |
symbol | No | Source. Defaults to the trade symbol. (CCI needs HLC — pass the symbol, not a single field.) |
Formula
$$ \text{tp}_t = \frac{\text{high}_t + \text{low}_t + \text{close}_t}{3} $$
$$ \text{CCI} = \frac{\text{tp}t - \text{SMA}N(\text{tp})}{0.015 \cdot \text{MAD}}, \qquad \text{MAD} = \frac{1}{N} \sum{i=0}^{N-1} |\text{tp}{t-i} - \text{SMA}_N(\text{tp})| $$
The denominator is floored at a small epsilon, so a perfectly flat window reads a large finite value rather than dividing by zero.
Warmup
period bars. Reads 0 until the window is full.
Reading the value
cci = CCI(20, on=self.trade)
cci.valuecci.crossed_above(-100) # leaving oversoldcci.crossed_below(100) # leaving overboughtExample
class CCIReversion(Strategy): """Buy when CCI leaves oversold, exit at the zero line.""" period = Param(20, min=5, max=50) trade = Symbol() sizing = FixedCapital()
def execute(self): cci = CCI(self.period, on=self.trade) self.stop_loss(3.0)
if cci.crossed_above(-100) and self.trade.is_flat: self.buy(self.trade, reason=f"CCI leaving oversold ({cci.value:.0f})")
if cci.value > 0 and self.trade.is_long: self.sell(self.trade, self.trade.position, reason="CCI back above zero")Notes
- The 0.015 constant calibrates roughly 70–80% of values into the ±100 band — beyond ±100 is the classic “extreme” read.
- CCI is unbounded (unlike
RSI) — extremes can run far past ±200 in strong trends. Mean-reversion entries need a stop. - Because CCI uses typical price (H+L+C)/3, it reacts to intrabar range, not just closes — noisier but earlier than close-only oscillators.