2026-02-27 07:48:12 -08:00
# CHOP: Choppiness Index
2026-03-11 20:21:52 -07:00
> *Choppiness index quantifies how range-bound a market is — high values mean sideways, low values mean trending.*
2026-02-27 07:48:12 -08:00
| Property | Value |
| ---------------- | -------------------------------- |
| **Category** | Dynamic |
| **Inputs** | OHLCV bar (TBar) |
| **Parameters** | `period` (default 14) |
| **Outputs** | Single series (CHOP) |
| **Output range** | Varies (see docs) |
| **Warmup** | `period` bars |
2026-03-11 15:35:33 -07:00
| **PineScript** | [chop.pine ](chop.pine ) |
2026-02-27 07:48:12 -08:00
- The Choppiness Index is a non-directional regime indicator that measures whether the market is trending or trading sideways.
2026-03-13 13:46:52 -07:00
- **Similar:** [ADX ](../adx/Adx.md ), [VHF ](../vhf/Vhf.md ) | **Complementary:** BBands for range boundaries | **Trading note:** Choppiness Index; high values = choppy/ranging, low values = trending. Range 0– 100.
2026-02-27 07:48:12 -08:00
- Validated against TA-Lib, Skender, and Tulip reference implementations where available.
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
The Choppiness Index is a non-directional regime indicator that measures whether the market is trending or trading sideways. It compares total price movement (sum of True Range) to net price movement (high-low channel width) using a logarithmic ratio, producing a bounded value where high readings indicate choppy/consolidating conditions and low readings indicate trending conditions. CHOP does not indicate direction — only whether directional strategies are likely to succeed. The logarithmic scaling normalizes the output to approximately 0-100 regardless of price level or volatility magnitude.
2026-02-05 19:42:49 -08:00
## Historical Context
2026-02-20 21:40:32 -08:00
Australian commodity trader E.W. Dreiss created the Choppiness Index to help traders avoid whipsaw losses by identifying market conditions unsuitable for trend-following strategies. The core insight is geometric: in a perfect trend, total bar-by-bar movement (sum of True Range) roughly equals the net distance traveled (channel width). In a choppy market, total movement greatly exceeds net progress — the market thrashes back and forth, accumulating True Range while the net channel stays narrow. The ratio between these two quantities, log-scaled to normalize across instruments and timeframes, produces a clean regime classifier. The conventional thresholds (38.2 and 61.8) are deliberately chosen as Fibonacci levels, though their efficacy is empirical rather than mathematical.
2026-02-05 19:42:49 -08:00
## Architecture & Physics
2026-02-20 21:40:32 -08:00
### 1. True Range Accumulation
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
$$TR_t = \max(H_t - L_t,\; |H_t - C_{t-1}|,\; |L_t - C_{t-1}|)$$
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
A rolling sum maintains $\sum_{i=1}^{N} TR_i$ over the lookback window.
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
### 2. Price Channel Width
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
The net price movement over the same window:
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
$$\text{Channel} = \max(H_{t-N+1:t}) - \min(L_{t-N+1:t})$$
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
### 3. Choppiness Index
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
$$\text{CHOP} = 100 \times \frac{\log_{10}\!\left(\dfrac{\sum TR_N}{\text{Channel}}\right)}{\log_{10}(N)}$$
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
The denominator $\log_{10}(N)$ normalizes the output so that the theoretical maximum approaches 100 (when $\sum TR = N \times \text{Channel}$, which occurs when every bar traverses the full channel).
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
### 4. Complexity
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
- **Time:** $O(N)$ per bar for min/max scanning of high/low buffers; rolling sum is $O(1)$
- **Space:** $O(N)$ — three ring buffers (TR, highs, lows)
- **Warmup:** $N$ bars
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
## Mathematical Foundation
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
### Parameters
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
| Symbol | Parameter | Default | Constraint |
|--------|-----------|---------|------------|
| $N$ | period | 14 | $N \geq 2$ |
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
### Interpretation
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
| CHOP Value | Market Regime | Strategy Implication |
|------------|---------------|---------------------|
| > 61.8 | High choppiness | Avoid trend-following; favor range strategies |
| 38.2 - 61.8 | Ambiguous | Mixed conditions; reduced position sizing |
| < 38.2 | Low choppiness | Market trending; favor momentum/breakout strategies |
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
### Geometric Intuition
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
- **Perfect trend (straight line):** $\sum TR \approx \text{Channel}$, so $\log_{10}(1) = 0$, CHOP $\to 0$
- **Maximum chop (full traversal every bar):** $\sum TR \approx N \times \text{Channel}$, so $\log_{10}(N) / \log_{10}(N) = 1$, CHOP $\to 100$
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
### Non-Directional Property
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
CHOP is completely direction-agnostic. A strong uptrend and a strong downtrend produce identical low CHOP readings. Direction must be determined by a separate indicator (AMAT, ADX directional components, or simple price comparison).
2026-02-05 19:42:49 -08:00
2026-02-26 22:02:52 -08:00
## Performance Profile
### Operation Count (Streaming Mode)
CHOP needs True Range sum over N bars (running sum from RingBuffer) and ATR-N (highest high minus lowest low over N bars).
**Post-warmup steady state (per bar):**
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
| TR computation (SUB× 3, ABS× 2, MAX× 2) | 7 | 1 | 7 |
| RingBuffer write + oldest sub (TR sum) | 2 | 1 | 2 |
| Deque update × 2 (high/low window extrema) | 4 | 1 | 4 |
| SUB (highest_high − lowest_low = range) | 1 | 1 | 1 |
| DIV (TR_sum / range) | 1 | 15 | 15 |
| LOG10 (normalize to period) | 1 | 20 | 20 |
| DIV (scale by log10(N)) | 1 | 15 | 15 |
| MUL (scale to 100) | 1 | 3 | 3 |
| **Total** | **18** | — | ** ~67 cycles** |
For default $N=14$: ~67 cycles per bar. The LOG10 call is the dominant cost.
### Batch Mode (SIMD Analysis)
| Operation | Vectorizable? | Notes |
| :--- | :---: | :--- |
| TR computation | Yes | VSUBPD + VABSPD + VMAXPD per bar |
| Prefix-sum TR | Partial | Inclusive prefix sum with SIMD subtract-lag |
| Sliding high/low extrema | Partial | Lemire deque or sparse table; ArgMax/ArgMin scan |
| LOG10 + scaling | Yes | SVML vlog10 or Taylor approx; scalar fallback |
With AVX2 and Intel SVML for vectorized log, batch mode achieves ~3× throughput for large datasets.
### Quality Metrics
| Metric | Score | Notes |
| :--- | :---: | :--- |
| **Accuracy** | 9/10 | LOG10 precision sufficient; FMA could be applied to TR computation |
| **Timeliness** | 6/10 | N-bar lookback; instantaneous response to volatility regime changes |
| **Smoothness** | 5/10 | Raw ratio is noisy; often used with EMA smoothing externally |
| **Noise Rejection** | 6/10 | Logarithmic scaling reduces extreme value sensitivity |
2026-02-20 21:40:32 -08:00
## Resources
2026-02-05 19:42:49 -08:00
2026-02-20 21:40:32 -08:00
- Dreiss, E.W. — Choppiness Index (original development)
2026-03-13 13:46:52 -07:00
- PineScript reference: `chop.pine` in indicator directory