Skip to content
ViprasolWE SOLVE INFINITYGet started
Back to Blog

TTM Squeeze vs Volatility Breakout Indicators: How They Differ

What the TTM Squeeze indicator measures, how its Bollinger-inside-Keltner test works, and how it differs from range and ATR breakout tools, with Pine code.

Viprasol Tech Team
11 min read
Updated 2026

TTM Squeeze vs Volatility Breakout Indicators: How They Differ

TLDR

The TTM Squeeze is a volatility indicator that flags when Bollinger Bands have contracted inside Keltner Channels, meaning recent price dispersion is unusually small relative to average range, and pairs that flag with a momentum histogram that suggests which way the eventual expansion may go. Volatility breakout indicators such as the opening range breakout, Donchian channels and ATR-multiple bands instead wait for price to actually leave a defined range and signal on the break itself. The squeeze answers "is a move being set up"; the breakout tools answer "has the move started". They are complementary rather than competing, and the most common mistake is treating the squeeze's momentum color as an entry signal in its own right. This article explains the construction, compares the two families in a table, works an example in numbers and provides an original Pine Script v6 squeeze with a confirmed fire signal.

What the TTM Squeeze measures

The indicator was developed by John Carter and popularized through his company Simpler Trading; a version ships with the thinkorswim platform under the name TTM_Squeeze. The idea is a comparison between two volatility envelopes drawn around the same moving average:

  • Bollinger Bands: a 20-period simple moving average plus and minus 2.0 standard deviations of close. Standard deviation reacts quickly to a change in dispersion.
  • Keltner Channels: the same 20-period average plus and minus 1.5 times the average true range. ATR is a smoother measure of typical bar range.

Most of the time the Bollinger Bands sit outside the Keltner Channels, because two standard deviations of close is usually wider than 1.5 average ranges. When the market goes quiet, the standard deviation collapses faster than the ATR does, and the Bollinger Bands slip inside the Keltner Channels. That condition is the "squeeze". In the original display a red dot on the zero line means the squeeze is on; a green dot means the bands have expanded back outside, which the indicator treats as the squeeze "firing".

The second component is a momentum histogram. It is a linear regression of the distance between close and a reference level, where the reference is the average of the 20-period Donchian midpoint and the 20-period SMA. The histogram's sign says whether price is above or below that reference; its color encodes whether it is growing or shrinking. The standard trading rule associated with the indicator is to wait for the first green dot after a run of red dots and to take the trade in the direction of the histogram at that moment.

Two things are worth noticing. The squeeze itself has no direction; it is a statement about dispersion. All the directional information comes from the histogram, which is a lagging momentum measure like any other. And the fire condition is not a price breakout; the bands can expand outside the Keltner Channels while price is still inside yesterday's range.

What volatility breakout indicators measure

A volatility breakout indicator defines a range and signals when price exits it. The range can be built from time, from a lookback, or from a volatility multiple:

  • Opening range breakout: the high and low of the first N minutes of the session. The ORB strategy article covers it in depth, with code.
  • Donchian channels: the highest high and lowest low of the last N bars. A close above the upper channel is the signal. Our Donchian breakout article works through the turtle-style version.
  • ATR bands: the previous close plus or minus a multiple of ATR, so the breakout threshold scales with recent volatility.
  • Bollinger Band breakouts: a close outside the band, sometimes combined with a band-width filter so the signal only counts after a contraction.

In every case the signal happens after price has moved. That costs you the first part of the move but gives you a definite entry price, a natural stop (the other side of the range) and a rule that a backtest can evaluate without ambiguity.

Side by side

PropertyTTM SqueezeRange or ATR breakout indicators
Core questionIs volatility compressed relative to its own average?Has price left a defined range?
DirectionNone from the squeeze; inferred from a momentum histogramGiven by the side of the range that broke
TimingCan be early: the squeeze can persist for many bars and fire before price movesLate by construction: price has already moved by at least the range width
Entry priceUndefined; the fire bar's close is the usual proxyDefined: the range boundary plus slippage
Stop placementNo natural level; traders use ATR or the recent swingNatural: the opposite side or midpoint of the range
False signalsFires in the wrong direction when the histogram lags a reversal; fires without follow-through in slow driftsBreaks that reverse back into the range; worst on narrow ranges and around news
ParametersLength, BB multiplier, KC multiplier (20 / 2.0 / 1.5 are typical)Range length or lookback, ATR multiple, minimum range filter
Natural roleSetup filter: trade other signals only when a squeeze has recently firedTrigger: define the entry, stop and first target
Repainting riskLow on confirmed bars; the histogram color flickers intrabarLow on confirmed bars; intrabar breaks that close back inside are the main trap

Worked example: squeeze on, squeeze off, then a breakout

Consider a 30 minute chart of an equity index future. The 20-period SMA is 18,000. Over a quiet afternoon the 20-period standard deviation of close falls to 9.0 points while the 20-period ATR is 14.0 points.

  • Bollinger upper = 18,000 + 2.0 x 9.0 = 18,018.0; lower = 17,982.0
  • Keltner upper = 18,000 + 1.5 x 14.0 = 18,021.0; lower = 17,979.0

The Bollinger Bands (17,982 to 18,018) sit inside the Keltner Channels (17,979 to 18,021): the squeeze is on. Suppose it stays on for seven bars, during which the histogram is slightly positive and growing.

On the eighth bar the market moves. The bar closes at 18,026, and the new standard deviation is 12.0 while ATR has barely moved to 14.4.

  • Bollinger upper = 18,000 + 24.0 = 18,024.0 (the SMA will have shifted slightly; we hold it at 18,000 for clarity)
  • Keltner upper = 18,000 + 21.6 = 18,021.6

The upper Bollinger Band is now outside the upper Keltner Channel, so the squeeze fires. The histogram is positive, so the textbook rule says long at the close, 18,026.

Now compare with a breakout tool on the same bars. The 20-bar Donchian high before this bar was 18,019. The bar closed at 18,026, above the channel, so the Donchian breakout also signals long at 18,026 on this occasion, with the natural stop at the channel midpoint, (18,019 + 17,980) / 2 = 17,999.5, for a risk of 26.5 points per contract. The squeeze offers no equivalent stop; a trader would have to add one, for example 1.5 x ATR = 21.6 points below the entry at 18,004.4.

The two tools agreed on this bar, but they will not always. Had the eighth bar closed at 18,017, the Bollinger expansion could still have fired the squeeze while price remained inside the Donchian channel; the squeeze trader would be long on a histogram reading and the breakout trader would still be flat. Which outcome is better depends on the instrument's follow-through statistics, and that is something to measure, not assume. Note that every number above is constructed to show the arithmetic and is not a backtest result.

Original Pine Script v6: squeeze with a confirmed fire signal

The script below implements the Bollinger-inside-Keltner test, the momentum histogram and a "fire" event that only triggers on a confirmed bar, so an alert will not fire on a bar that later closes back inside. It is deliberately compact.

//@version=6
indicator("Squeeze (BB inside KC) with momentum", overlay = false)

len = input.int(20, "Length", minval = 2) bbMult = input.float(2.0, "Bollinger multiplier", step = 0.1, minval = 0.1) kcMult = input.float(1.5, "Keltner ATR multiplier", step = 0.1, minval = 0.1)

basis = ta.sma(close, len) dev = bbMult * ta.stdev(close, len) bbUp = basis + dev bbDn = basis - dev rangeMa = ta.sma(ta.tr(true), len) kcUp = basis + kcMult * rangeMa kcDn = basis - kcMult * rangeMa

squeezeOn = bbDn > kcDn and bbUp < kcUp fired = not squeezeOn and squeezeOn[1] and barstate.isconfirmed

hh = ta.highest(high, len) ll = ta.lowest(low, len) midRef = ((hh + ll) / 2 + basis) / 2 mom = ta.linreg(close - midRef, len, 0)

rising = mom > mom[1] momColor = mom > 0 ? (rising ? color.lime : color.green) : (rising ? color.maroon : color.red)

plot(mom, "Momentum", color = momColor, style = plot.style_columns) plot(0, "Squeeze state", color = squeezeOn ? color.red : color.gray, style = plot.style_circles, linewidth = 2) plotshape(fired and mom > 0, "Fired up", shape.triangleup, location.bottom, color.green, size = size.small) plotshape(fired and mom < 0, "Fired down", shape.triangledown, location.top, color.red, size = size.small)

alertcondition(fired and mom > 0, "Squeeze fired up", "Bollinger Bands expanded outside Keltner, momentum positive") alertcondition(fired and mom < 0, "Squeeze fired down", "Bollinger Bands expanded outside Keltner, momentum negative")

Design notes:

  • The Keltner Channel here uses a simple average of true range. Some implementations use an exponential average or an EMA basis; the squeeze condition is similar but the exact fire bar can differ by a bar or two. If you are matching a chart from another platform, check which smoothing it uses.
  • fired is a one-bar event rather than a state, and it requires barstate.isconfirmed. Without that guard the triangle appears and disappears within the live bar as the standard deviation moves, which is the intrabar flicker described in the non-repainting indicators article.
  • The histogram color logic distinguishes rising from falling momentum on each side of zero. Many traders only trade a fire whose histogram is both positive and rising (or negative and falling), which cuts the signal count roughly in half.
  • To combine with a breakout tool, keep this on a lower pane and gate your range breakout signal on a condition such as "squeeze fired within the last 5 bars". That turns the squeeze into a filter and lets the breakout define price, stop and target.

Common mistakes with the squeeze

  1. Trading the histogram color alone. The histogram is a lagging momentum measure. Without the squeeze condition it is just another oscillator, and a slow one.
  2. Entering during the squeeze. A long run of red dots feels like a coiled spring, but squeezes can persist for dozens of bars and resolve in either direction. Positioning before the fire is a guess.
  3. Ignoring the time of day. On intraday charts a squeeze that forms over lunch and fires at the New York close has little chance of follow-through. Combine with session logic.
  4. No stop plan. Because the indicator supplies no level, traders improvise, and improvised stops tend to be either too tight (stopped by noise) or absent. Decide the stop rule before the fire.
  5. Treating every fire the same. A fire after a 3-bar squeeze and a fire after a 30-bar squeeze are different events. Logging squeeze duration alongside outcome is a cheap way to learn whether that matters on your market.

FAQ

Is the TTM Squeeze indicator free on TradingView?

The TTM Squeeze name belongs to Simpler Trading and the official version is distributed through their channels and platforms such as thinkorswim. The underlying logic, Bollinger Bands inside Keltner Channels plus a regression momentum histogram, is well known and there are many community implementations on TradingView under names such as "Squeeze Momentum". The code in this article is an original implementation of that logic.

What are the standard TTM Squeeze settings?

The commonly used values are a length of 20, a Bollinger multiplier of 2.0 and a Keltner multiplier of 1.5. Some traders run a tighter Keltner multiplier, which makes squeezes rarer and shorter. As with any parameter, test the neighborhood rather than a single value.

Is the squeeze a leading indicator?

The squeeze condition is leading in the sense that it identifies compression before the expansion. The direction call is not leading; it comes from momentum, which lags. Expect the squeeze to tell you when to pay attention, and something else to tell you which way.

Does the TTM Squeeze work on forex and crypto?

The volatility logic is instrument-agnostic. What differs is session structure: forex has three overlapping sessions and crypto trades continuously, so squeezes that form in dead hours are more common and less reliable than on an exchange-traded product with a defined open. Add a session filter when testing on those markets.

Squeeze or opening range breakout for day trading?

They are built for different jobs. The ORB defines a specific window and gives you an entry and stop; the squeeze finds compression at any time of day but leaves the entry mechanics to you. Many intraday traders use the squeeze as a filter on top of a breakout rule rather than choosing between them.

Where Viprasol fits

Viprasol builds breakout and volatility tooling for TradingView and MetaTrader: squeeze detectors with session filters and duration logging, range breakout indicators with ATR-scaled filters, and combined systems where the squeeze gates the breakout. We deliver readable Pine Script v6 or MQL5 source, alerts formatted for webhook automation, and a strategy version so you can test the rule set before trading it. If you want a squeeze or breakout tool built to your specification, our Pine Script development service is the starting point; the backtesting service covers the measurement work. Pricing is on the pricing page and you can describe your rules through the contact form.

Risk disclaimer: trading futures, forex, CFDs and crypto involves substantial risk of loss. This article is educational and is not investment advice; the examples are illustrative and do not indicate future performance.

ttm squeeze indicatorttm squeezevolatility breakoutbollinger bands keltner channelsqueeze indicatorpine script v6breakout trading

External Resources

Share this article:

About the Author

V

Viprasol Tech Team

Custom Software Development Specialists

The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 1000+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement.

MT4/MT5 EA DevelopmentAI Agent SystemsSaaS DevelopmentAlgorithmic Trading

Ready to Automate Your Trading?

Discuss a custom Expert Advisor with defined strategy rules, risk controls and a testing plan.

Free consultation • No commitment • Response within 24 hours

Viprasol · Trading Software

Need a custom EA or trading bot built?

We build MT4/MT5 Expert Advisors around your strategy, broker and risk requirements. Each project has an agreed scope, testing plan and individual quote.