Debated1 min read
◆ The PatternHow far price has strayed from its typical level, measured in units of its usual wandering
The Commodity Channel Index — created by Donald Lambert (1980).
CCI = (Typical Price − SMA(TP)) / (0.015 × Mean Deviation)
The 0.015 constant scales the indicator so that roughly 70–80% of values fall between −100 and +100 (Lambert’s intent).
Interpretation:
• CCI > +100 → unusually strong (possible overbought)
• CCI < −100 → unusually weak (possible oversold)
• Zero-line crossovers indicate trend direction changes
• CCI > +100 → unusually strong (possible overbought)
• CCI < −100 → unusually weak (possible oversold)
• Zero-line crossovers indicate trend direction changes
Worked example
Day 15: the typical prices of days 11–15 are 103.67, 102.33, 99.67, 100.67 and 103.33. Their mean is 101.93 and their mean absolute deviation 1.41, so CCI = (103.33 − 101.93) / (0.015 × 1.41) = 66. Two days earlier, at the low, it read −141, below Lambert’s −100 line. The 0.015 was chosen so that most readings land between −100 and +100.
The example data: 15 days, used in every indicator here
| Day | High | Low | Close | Volume |
|---|---|---|---|---|
| 1 | 101 | 99 | 100 | 50,000 |
| 2 | 103 | 100 | 102 | 62,000 |
| 3 | 103 | 100 | 101 | 48,000 |
| 4 | 105 | 101 | 104 | 70,000 |
| 5 | 108 | 104 | 107 | 85,000 |
| 6 | 108 | 105 | 106 | 60,000 |
| 7 | 110 | 106 | 109 | 90,000 |
| 8 | 110 | 107 | 108 | 72,000 |
| 9 | 108 | 104 | 105 | 80,000 |
| 10 | 105 | 102 | 103 | 66,000 |
| 11 | 105 | 102 | 104 | 55,000 |
| 12 | 104 | 101 | 102 | 75,000 |
| 13 | 102 | 98 | 99 | 95,000 |
| 14 | 102 | 99 | 101 | 64,000 |
| 15 | 105 | 101 | 104 | 71,000 |
Where it misleads
- It has no bound: readings of ±200 or ±300 happen in strong moves, and fading them means fading a trend.
- The mean deviation shrinks in quiet periods, so a modest move after a calm stretch gives an extreme reading.
- Lambert built it to catch cycles in commodities; where there is no regular cycle the ±100 lines have no special meaning.
In code
tp = (df['high'] + df['low'] + df['close']) / 3 ma = tp.rolling(5).mean() md = tp.rolling(5).apply(lambda x: np.abs(x - x.mean()).mean(), raw=True) df['cci5'] = (tp - ma) / (0.015 * md)
Assumes import numpy as np, import pandas as pd, and a DataFrame df with columns high, low, close and volume — the 15 days above.
Sources
- D. R. Lambert, “Commodity Channel Index: Tools for Trading Cyclic Trends”, Commodities magazine, 1980
- Technical Analysis from A to Z (2nd ed.), S. B. Achelis, McGraw-Hill, 2000
- C.-H. Park & S. H. Irwin, “What Do We Know About the Profitability of Technical Analysis?”, Journal of Economic Surveys 21(4), 2007 — a review of the evidence across studies
Last reviewed October 2026 · How this site checks its content · Report a mistake
Pattern bridge: CCI measures deviation from the mean in units of mean absolute deviation — a z-score variant. In ML, batch normalization does the same: center and scale.
Linked from 1