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.
## thinkScript code
```thinkscript
# ─────────────────────────────────────────────
# │ 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/yellow 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
declare lower;
input length = 20;
input bbStdDev = 2.0;
input kcMultiplier = 1.5;
input momentumLength = 20;
input src = close;
# --- Bollinger Bands
def basis = Average(src, length);
def dev = bbStdDev * StDev(src, length);
def upperBB = basis + dev;
def lowerBB = basis - dev;
# --- Keltner Channels (TR-based, classic TTM definition)
def kcMid = Average(src, length);
def kcRange = Average(TrueRange(high, close, low), length);
def upperKC = kcMid + kcRange * kcMultiplier;
def lowerKC = kcMid - kcRange * kcMultiplier;
# --- Squeeze state
def squeezeOn = lowerBB > lowerKC and upperBB < upperKC;
def squeezeOff = lowerBB < lowerKC and upperBB > upperKC;
def noSqueeze = !squeezeOn and !squeezeOff;
# --- TTM momentum: linreg of (price - midpoint of recent range/SMA)
def hh = Highest(high, length);
def ll = Lowest(low, length);
def avgPrice = ((hh + ll) / 2 + Average(close, length)) / 2;
def delta = close - avgPrice;
def momentum = Inertia(delta, momentumLength);
# --- Momentum histogram with TTM 4-state coloring
plot Mom = momentum;
Mom.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Mom.SetLineWeight(3);
Mom.AssignValueColor(
if momentum > 0 and momentum > momentum[1] then Color.CYAN
else if momentum > 0 and momentum <= momentum[1] then Color.DARK_GREEN
else if momentum < 0 and momentum < momentum[1] then Color.RED
else Color.YELLOW
);
# --- Squeeze dots on zero line
plot SqDot = if !IsNaN(close) then 0 else Double.NaN;
SqDot.SetPaintingStrategy(PaintingStrategy.POINTS);
SqDot.SetLineWeight(4);
SqDot.AssignValueColor(
if squeezeOn then Color.RED
else if noSqueeze then Color.GRAY
else Color.GREEN
);
SqDot.HideTitle();
# --- Zero line
plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.DARK_GRAY);
ZeroLine.SetStyle(Curve.LONG_DASH);
ZeroLine.HideTitle();
# --- Alerts
def justFired = squeezeOn[1] and !squeezeOn;
Alert(justFired and momentum > 0, "TTM Squeeze fired bullish", Alert.BAR, Sound.Ding);
Alert(justFired and momentum < 0, "TTM Squeeze fired bearish", Alert.BAR, Sound.Ding);
Alert(momentum crosses above 0, "TTM momentum crossed above zero", Alert.BAR, Sound.Bell);
Alert(momentum crosses below 0, "TTM momentum crossed below zero", Alert.BAR, Sound.Bell);
```
Drop your tweaks, screenshots, and questions below — that's how the library gets better.

