TTM Squeeze — Momentum Drop
TTM Squeeze pairs a Bollinger-inside-Keltner compression detector with a linear-regression momentum histogram — so you see both the coil and the direction of the release on a single panel. Red dots on the zero line mark squeeze ON, the histogram color tells you which way energy is leaning, and when the dot flips off you have a high-information moment to act on.
## What it does
- Detects volatility compression (Bollinger Bands contracting inside Keltner Channels) with classic TTM defaults.
- Plots squeeze state as colored dots on the zero line: red = ON (coil), gray = neutral, green = wide / firing.
- Renders TTM-style linear-regression momentum as a 4-color histogram (rising-above / falling-above / falling-below / rising-below zero).
- Fires "Squeeze Fired Bullish" and "Squeeze Fired Bearish" alerts the bar the squeeze releases.
- Also fires momentum zero-cross alerts for early rotation reads.
## Recommended settings
- BB / KC length: 20
- BB std dev: 2.0
- KC range multiplier: 1.5 (TR-based, classic TTM)
- Momentum linreg length: 20
- Source: close
- Faster intraday variant: length 14, KC mult 1.5
- Slower swing variant: length 30, BB stdev 2.0
## Ideal timeframe
Designed for 5m–1D charts. Most useful on liquid index futures, large-cap equities, and majors during regular hours where the squeeze actually resolves into a real expansion move.
## How to use
Wait for a cluster of red dots — that is the coil. Do not pre-position. The moment the dot turns off (gray or green), let the histogram color cast the deciding vote: aqua/green above zero = take long setups, red/yellow below zero = take short setups. Yellow above or green below means the move is decelerating and you should be quicker to take partials. Treat squeezes that fire against the higher-timeframe trend as fade candidates rather than continuation trades.
## Pine Script v5 code
```pinescript
//@version=5
// ─────────────────────────────────────────────
// │ MarketFragments.com | DNA & Market │
// │ info@marketfragments.com │
// │ www.marketfragments.com │
// ─────────────────────────────────────────────
// Time →
// │
// █ █ █│ █
// █ █ █ │ █ █
// █ █ █ │ █ █ █ ╭─╮
// █ █ █ │ █ █ █ █ ╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮
// █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ █ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ █ ╰─╮ ╭─╯
// █ █ █ │ █ ╰─────╯
// ──────┴──────────────────────────────────────────────────────────────
// T1 T2 T3 T4 T5 T6
//
// TTM Squeeze (open-source rebuild)
// Combines a Bollinger / Keltner compression detector with a TTM-style
// linear-regression momentum histogram. Red dots on the zero line mark
// squeeze ON (BB inside KC = volatility coiling). When the dot turns
// green/gray the squeeze has fired — the histogram color and slope
// tell you which way the energy is releasing.
// Free for non-commercial use. (c) MarketFragments.com
indicator("MF TTM Squeeze", shorttitle="MF TTM Sqz", overlay=false, format=format.price, precision=4)
length = input.int(20, "BB / KC Length", minval=2)
bbStdDev = input.float(2.0, "BB Std Dev", minval=0.1, step=0.1)
kcMultiplier = input.float(1.5, "KC Range Multiplier", minval=0.1, step=0.1)
momentumLength = input.int(20, "Momentum LinReg Length", minval=2)
src = input.source(close, "Source")
// --- Bollinger Bands
basis = ta.sma(src, length)
dev = bbStdDev * ta.stdev(src, length)
upperBB = basis + dev
lowerBB = basis - dev
// --- Keltner Channels (TR-based, classic TTM definition)
kcMid = ta.sma(src, length)
kcRange = ta.sma(ta.tr(true), length)
upperKC = kcMid + kcRange * kcMultiplier
lowerKC = kcMid - kcRange * kcMultiplier
// --- Squeeze state
squeezeOn = lowerBB > lowerKC and upperBB < upperKC
squeezeOff = lowerBB < lowerKC and upperBB > upperKC
noSqueeze = not squeezeOn and not squeezeOff
// --- TTM momentum: linreg of (price - midpoint of recent range/SMA)
hh = ta.highest(high, length)
ll = ta.lowest(low, length)
avgPrice = (math.avg(hh, ll) + ta.sma(close, length)) / 2
delta = close - avgPrice
momentum = ta.linreg(delta, momentumLength, 0)
// --- Momentum histogram with TTM 4-state coloring
momPrev = nz(momentum[1])
momColor = momentum > 0 ? (momentum > momPrev ? color.new(color.aqua, 0) : color.new(color.green, 30)) :
(momentum < momPrev ? color.new(color.red, 0) : color.new(color.yellow, 30))
plot(momentum, "Momentum", style=plot.style_columns, color=momColor)
// --- Squeeze dots on zero line
dotColor = squeezeOn ? color.red : noSqueeze ? color.gray : color.green
plot(0, "Squeeze", style=plot.style_circles, color=dotColor, linewidth=4)
// --- Zero line
hline(0, "Zero", color=color.new(color.gray, 30), linestyle=hline.style_dashed)
// --- Alerts
justFired = squeezeOn[1] and not squeezeOn
alertcondition(justFired and momentum > 0, "TTM Squeeze Fired Bullish", "TTM Squeeze fired — bullish momentum")
alertcondition(justFired and momentum < 0, "TTM Squeeze Fired Bearish", "TTM Squeeze fired — bearish momentum")
alertcondition(ta.crossover(momentum, 0), "TTM Momentum Cross Up", "TTM momentum crossed above zero")
alertcondition(ta.crossunder(momentum, 0), "TTM Momentum Cross Down", "TTM momentum crossed below zero")
```
Drop your tweaks, screenshots, and questions below — that's how the library gets better.

