Choppiness Index — Volatility Drop
The Choppiness Index tells you *when* the market is trending versus chopping sideways — not which direction. Use it as a regime filter to switch between trend-following and mean-reversion tactics.
## What it does
- Measures how directional price has been over a lookback window using the ratio of summed True Range to the total high-low range.
- Scales the result to a clean 0–100 oscillator via a log normalization.
- High readings (≥ 61.8) flag choppy, range-bound conditions; low readings (≤ 38.2) flag strong trends.
- Color-codes the line (yellow = chop, aqua = trend, gray = neutral) and tints the background by regime.
- Fires alerts the bar the market crosses into a trend or chop regime.
## Recommended settings
- Length: 14
- Chop threshold: 61.8
- Trend threshold: 38.2
- Mid reference: 50
## Ideal timeframe
Works on any timeframe; most reliable as a regime filter on 15m–4h and daily charts.
## How to use
Treat the Choppiness Index as a gate, not a trigger. When the line is low (≤ 38.2) and falling, price is trending — favor breakout and pullback entries and let trend tools lead. When the line is high (≥ 61.8), the market is coiling sideways — fade the edges of the range and distrust breakouts until the index rolls back down. The Fibonacci-derived 61.8 / 38.2 bands are the classic thresholds; the aqua/yellow coloring and background tint make the active regime obvious at a glance.
## Pine Script v5 code
```
//@version=5
// ─────────────────────────────────────────────
// │ MarketFragments.com | DNA & Market │
// │ info@marketfragments.com │
// │ www.marketfragments.com │
// ─────────────────────────────────────────────
// Time →
// │
// █ █ █│ █
// █ █ █ │ █ █
// █ █ █ │ █ █ █ ╭─╮
// █ █ █ │ █ █ █ █ ╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ █ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ ╰─────╯
// ──────┴──────────────────────────────────────────────────────────────
// T1 T2 T3 T4 T5 T6
//
// Choppiness Index — volatility / trend-vs-range regime oscillator
// Measures whether price is trending or chopping over a lookback window.
// Free for non-commercial use. Attribution to MarketFragments.com appreciated.
indicator("MarketFragments Choppiness Index", shorttitle="MF CHOP", overlay=false)
length = input.int(14, "Length", minval=2)
chopThreshold = input.float(61.8, "Chop Threshold")
trendThreshold = input.float(38.2, "Trend Threshold")
tr1 = ta.tr(true)
trSum = math.sum(tr1, length)
hh = ta.highest(high, length)
ll = ta.lowest(low, length)
rng = hh - ll
ci = rng > 0 ? 100 * math.log(trSum / rng) / math.log(length) : na
ciColor = ci >= chopThreshold ? color.yellow : ci <= trendThreshold ? color.aqua : color.gray
plot(ci, "Choppiness Index", color=ciColor, linewidth=2)
hline(chopThreshold, "Chop", color=color.orange)
hline(trendThreshold, "Trend", color=color.green)
hline(50, "Mid", color=color.gray, linestyle=hline.style_dashed)
bgcolor(ci >= chopThreshold ? color.new(color.yellow, 90) : ci <= trendThreshold ? color.new(color.aqua, 90) : na)
var label tag = na
if barstate.islast
label.delete(tag)
regime = ci >= chopThreshold ? "CHOPPY" : ci <= trendThreshold ? "TRENDING" : "NEUTRAL"
tag := label.new(bar_index, ci, "CHOP " + str.tostring(ci, "#.#") + " | " + regime,
style=label.style_label_left, color=color.new(ciColor, 20), textcolor=color.black)
alertcondition(ta.crossunder(ci, trendThreshold), "Trend regime", "Choppiness: entering TREND regime")
alertcondition(ta.crossover(ci, chopThreshold), "Chop regime", "Choppiness: entering CHOP regime")
```
Drop your tweaks, screenshots, and questions below — that's how the library gets better.

