mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-19 11:08:05 +00:00
141 lines
5.7 KiB
Markdown
141 lines
5.7 KiB
Markdown
# CCI - Commodity Channel Index
|
||
|
||
> *CCI measures how far price deviates from its statistical mean, scaled by mean absolute deviation — a z-score with character.*
|
||
|
||
| Property | Value |
|
||
| ---------------- | -------------------------------- |
|
||
| **Category** | Momentum |
|
||
| **Inputs** | OHLCV bar (TBar) |
|
||
| **Parameters** | `period` (default 20) |
|
||
| **Outputs** | Single series (CCI) |
|
||
| **Output range** | Varies (see docs) |
|
||
| **Warmup** | `period` bars |
|
||
| **PineScript** | [cci.pine](cci.pine) |
|
||
|
||
- The Commodity Channel Index (CCI) is a versatile momentum-based oscillator developed by Donald Lambert in 1980.
|
||
- **Similar:** [RSI](../rsi/Rsi.md), [Stoch](../../oscillators/stoch/Stoch.md) | **Complementary:** ADX for trend filter | **Trading note:** Commodity Channel Index; measures deviation from statistical mean. ±100 = overbought/oversold.
|
||
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
|
||
|
||
## Overview
|
||
|
||
The Commodity Channel Index (CCI) is a versatile momentum-based oscillator developed by Donald Lambert in 1980. Originally designed for commodity trading, it measures the deviation of price from its statistical mean, normalized by mean absolute deviation.
|
||
|
||
## Formula
|
||
|
||
```
|
||
TP = (High + Low + Close) / 3
|
||
SMA = Simple Moving Average of TP over period
|
||
Mean Deviation = SUM(|TP - SMA|) / period
|
||
CCI = (TP - SMA) / (0.015 × Mean Deviation)
|
||
```
|
||
|
||
## Key Characteristics
|
||
|
||
| Property | Value |
|
||
|----------|-------|
|
||
| Default Period | 20 |
|
||
| Lambert Constant | 0.015 |
|
||
| Returns | Unbounded oscillator (typically -300 to +300) |
|
||
| Warmup Period | Equal to period |
|
||
| Input Data | OHLC bars (uses Typical Price) |
|
||
|
||
## Signal Interpretation
|
||
|
||
### Primary Levels
|
||
- **Above +100**: Strong uptrend, potentially overbought
|
||
- **Below -100**: Strong downtrend, potentially oversold
|
||
- **Zero Line**: Centerline crossover indicates trend change
|
||
|
||
### Trading Strategies
|
||
1. **Trend Identification**: Values consistently above/below zero indicate trend direction
|
||
2. **Overbought/Oversold**: Extreme readings (+200/-200) suggest reversal potential
|
||
3. **Divergence**: Price making new high/low while CCI fails to confirm
|
||
4. **Zero-Line Cross**: Bullish when crossing above, bearish when crossing below
|
||
|
||
## Lambert Constant (0.015)
|
||
|
||
The 0.015 constant was chosen by Lambert to ensure that approximately 70-80% of CCI values fall between +100 and -100 under normal market conditions. This provides a statistical framework where:
|
||
- Values outside ±100 indicate significant price movement
|
||
- Extended readings suggest strong trends
|
||
- Extreme values (±200 or beyond) are relatively rare
|
||
|
||
## Usage
|
||
|
||
### Basic Construction
|
||
```csharp
|
||
// Create CCI with default 20-period
|
||
var cci = new Cci();
|
||
|
||
// Create CCI with custom period
|
||
var cci = new Cci(14);
|
||
```
|
||
|
||
### Streaming Updates
|
||
```csharp
|
||
foreach (var bar in realTimeData)
|
||
{
|
||
TValue result = cci.Update(bar);
|
||
double cciValue = result.Value;
|
||
|
||
if (cciValue > 100)
|
||
Console.WriteLine("Overbought territory");
|
||
else if (cciValue < -100)
|
||
Console.WriteLine("Oversold territory");
|
||
}
|
||
```
|
||
|
||
### Batch Processing
|
||
```csharp
|
||
TSeries results = Cci.Batch(barSeries, period: 20);
|
||
```
|
||
|
||
## Comparison with Other Oscillators
|
||
|
||
| Indicator | Bounds | Best For |
|
||
|-----------|--------|----------|
|
||
| CCI | Unbounded | Trend strength, divergence |
|
||
| RSI | 0-100 | Overbought/oversold levels |
|
||
| Stochastic | 0-100 | Price position within range |
|
||
|
||
## Historical Context
|
||
|
||
- Developed by Donald Lambert (1980)
|
||
- Originally published in *Commodities* magazine
|
||
- Early application for identifying cyclical trends in commodities
|
||
- Now widely used across all asset classes
|
||
|
||
## References
|
||
|
||
- Lambert, D.R. (1980). "Commodity Channel Index: Tool for Trading Cyclic Trends"
|
||
- [TradingView CCI Documentation](https://www.tradingview.com/support/solutions/43000502001/)
|
||
- [Investopedia CCI Guide](https://www.investopedia.com/terms/c/commoditychannelindex.asp)
|
||
|
||
## Performance Profile
|
||
|
||
### Operation Count (Streaming Mode)
|
||
|
||
Each `Update()` call on CCI(N) performs a full O(N) mean-deviation scan over the ring buffer. There is no closed-form running-sum decomposition for mean absolute deviation — the absolute values prevent the cancellation that makes SMA or variance incremental. The RingBuffer manages the sliding window; computing MAD requires visiting every element.
|
||
|
||
| Operation | Count | Cost (cycles) | Subtotal |
|
||
| :--- | :---: | :---: | :---: |
|
||
| Ring buffer push | 1 | 3 | ~3 |
|
||
| Running sum update (TP add/subtract) | 2 | 1 | ~2 |
|
||
| SMA divide | 1 | 8 | ~8 |
|
||
| MAD scan: N subtractions + N ABS | 2N | 2 | ~2N·2 |
|
||
| MAD divide | 1 | 8 | ~8 |
|
||
| Final scale + divide (0.015×MAD) | 2 | 3 | ~6 |
|
||
| **Total** | **2N + 7** | — | **~(4N + 27) cycles** |
|
||
|
||
O(N) streaming cost per bar. For the default N = 20: ~107 cycles. No incremental shortcut exists for MAD; SIMD vectorization of the scan loop is the primary optimization lever.
|
||
|
||
### Batch Mode (SIMD Analysis)
|
||
|
||
| Operation | Vectorizable? | Notes |
|
||
| :--- | :---: | :--- |
|
||
| Typical price (H+L+C)/3 | Yes | 3-wide FMA, AVX2 vectorizable |
|
||
| Rolling SMA via prefix sums | Yes | `VADDPD` on register array |
|
||
| MAD inner loop (ABS + accumulate) | Yes | `VABSPD` + `VADDPD`, width-8 per AVX2 lane |
|
||
| Final CCI scale | Yes | scalar multiply after reduction |
|
||
| State dependency across bars (SMA) | Partial | prefix sum removes dependency; MAD is fully independent per bar |
|
||
|
||
AVX2 processes 4 doubles per instruction. For the inner MAD loop of N=20, that is 5 SIMD passes vs 20 scalar iterations — roughly 3× throughput gain. The outer bar loop remains SIMD-friendly since each bar's TP is independent once the window positions are known. |