Define the squeeze before reading the dots
For the public-formula example below, BB is an SMA of close plus or minus a standard-deviation multiple. KC is an SMA of close plus or minus a multiple of the SMA of true range. Each band has its own length and multiplier. The momentum reference is the average of the rolling high/low midpoint and the SMA of close; the histogram is the linear-regression endpoint of close minus that reference over the KC length.
Compression: BB upper < KC upper AND BB lower > KC lower
Both outside: BB upper > KC upper AND BB lower < KC lower
Mixed: neither of those conditions, including an equal boundary
Release: previous compression AND no compression now, at bar close
Testing only the upper boundary is insufficient when the basis lines differ. In a hypothetical example, BB spans 95 to 101 and KC spans 98 to 102. The upper BB is inside, but the lower BB is outside, so the bands are not contained. Comparing widths alone also misses this offset. A transition into the mixed state ends containment in this example; another script may wait until both bands are outside before it calls that a release.
Above-zero momentum describes a positive regression reading; below-zero describes a negative reading. A positive bar that shrinks indicates weakening positive momentum, not a bearish reading. Neither the histogram nor a release is a price target.
Why two TTM Squeeze scripts can disagree
Match the implementation before comparing signals. The name and a visible length of 20 do not identify the smoothing, multiplier or release rule.
| Version | What is documented | Comparison limit |
|---|---|---|
| thinkorswim TTM_Squeeze | BB/KC relationship, momentum smoothing, and a band-width ratio alert input. | The overview does not establish numerical equivalence to a TradingView script. |
| LazyBear Squeeze Momentum | Public derivative with SMA channel calculations, separate state tests and regression momentum. | The author flags a historical BB multiplier bug. Check the revision instead of assuming every repost is corrected. |
| This page's example | SMA/standard-deviation BB, SMA/mean-true-range KC, independent multipliers, first loss of containment. | An educational implementation with explicit rules, not a replica of a paid study. |
EMA-based channels and channels using Wilder-smoothed ATR can produce different boundaries from the SMA channel here. TradingView documents RMA as its default ATR smoothing. Increasing only the KC multiplier widens this example's channel and can include more bars in the squeeze; it cannot reduce the set of contained bars with all other inputs fixed. More compression readings do not imply better trades.
Sources: thinkorswim TTM_Squeeze, LazyBear's script and revision notes, and TradingView ATR.
A release can pass the entry rule and still fail
Consider this hypothetical long setup, not a reported backtest: price has a prior 20-bar range high of 100. A bar closes at 100.50, containment ends, and momentum is positive and rising. A rule requiring all three observations accepts the signal. The next bar closes at 99.50, back inside the old range. The squeeze calculation was correct, but the expected continuation failed.
- Freeze the range high using bars before the signal; including the signal bar changes the comparison.
- Specify whether entry is at the next bar open or another executable price. Do not assume the signal close is the fill.
- Define a protective stop, position size and exit before testing. A close back below the frozen range high can be a separate invalidation rule; gaps may exceed the planned loss.
- Compare the same rule with and without a volume or trend filter. A filter removes trades but may remove winners too.
Waiting for a closed bar prevents acting on a temporary intrabar release in this example, but adds delay. It does not eliminate false breakouts. News gaps, repeated transitions near a band boundary and transaction costs can all change the outcome.
Pine Script v6: inspect compression and momentum
Paste this indicator into TradingView's Pine Editor, save it and add it to a standard candlestick chart. Inputs start at BB 20/2.0 and KC 20/1.5 as an illustration, not a recommendation. Red dots mean inside, green means both outside, and gray means mixed. The Data Window also provides numeric state values.
//@version=6
indicator("BB/KC squeeze: public-formula example", overlay=false)
bbLength = input.int(20, "BB length", minval=2)
bbMultiplier = input.float(2.0, "BB multiplier", minval=0.1, step=0.1)
kcLength = input.int(20, "KC length", minval=2)
kcMultiplier = input.float(1.5, "KC multiplier", minval=0.1, step=0.1)
useTrueRange = input.bool(true, "Use true range")
bbBasis = ta.sma(close, bbLength)
bbDeviation = bbMultiplier * ta.stdev(close, bbLength)
bbUpper = bbBasis + bbDeviation
bbLower = bbBasis - bbDeviation
kcBasis = ta.sma(close, kcLength)
rangeValue = useTrueRange ? ta.tr(true) : high - low
kcWidth = kcMultiplier * ta.sma(rangeValue, kcLength)
kcUpper = kcBasis + kcWidth
kcLower = kcBasis - kcWidth
ready = not na(bbUpper) and not na(kcUpper)
squeezeOn = ready and bbUpper < kcUpper and bbLower > kcLower
bothOutside = ready and bbUpper > kcUpper and bbLower < kcLower
released = ready and squeezeOn[1] and not squeezeOn and barstate.isconfirmed
rangeMidpoint = (ta.highest(high, kcLength) + ta.lowest(low, kcLength)) / 2
referenceValue = (rangeMidpoint + ta.sma(close, kcLength)) / 2
momentum = ta.linreg(close - referenceValue, kcLength, 0)
momentumColor = momentum >= 0 ? (momentum > momentum[1] ? color.aqua : color.teal) : (momentum < momentum[1] ? color.red : color.orange)
stateColor = squeezeOn ? color.red : bothOutside ? color.lime : color.gray
plot(momentum, "Momentum", color=momentumColor, style=plot.style_histogram, linewidth=2)
plot(ready ? 0 : na, "Squeeze state", color=stateColor, style=plot.style_circles, linewidth=3)
plot(ready ? (squeezeOn ? 1 : bothOutside ? -1 : 0) : na, "State: 1 inside, -1 outside, 0 mixed", display=display.data_window)
plotshape(released, title="Confirmed release", style=shape.triangleup, location=location.bottom, color=color.blue, size=size.tiny, text="Release")
alertcondition(released, "Confirmed squeeze release", "BB/KC containment ended on a closed bar.")Cyan/teal bars are positive momentum rising/not rising; red/orange bars are negative momentum falling/not falling. Dots and histogram update on the live bar. Only the release marker and alert condition wait for bar close. Create an alert using Confirmed squeeze release and Once Per Bar Close; adding code alone does not create an active TradingView alert.
No higher-timeframe data or future bars are requested. This does not make every possible modification non-repainting. See TradingView's repainting documentation. The code is an indicator, not an order-executing strategy.
Turn the formula into a testable rule
Give Pineify's AI Coding Agent the formula, release definition, entry timing and exits you intend to test. Ask for editable inputs and review the generated code in TradingView. Use public formulas or code you have permission to modify; a paid study's name is not enough to reproduce its private algorithm.
Once you have a working strategy, the Strategy Optimizer can compare input combinations. To examine parameter stability, compare nearby BB and KC settings while keeping costs, session, symbol and timeframe fixed. Check trade count, drawdown and performance on a separate period. One profitable parameter peak is not evidence of a stable edge.
Build a squeeze rule with PineifyTTM Squeeze questions
Sources and related reading
Sources checked October 16, 2026.
- thinkorswim: TTM_Squeeze components and input definitions
- LazyBear: public Squeeze Momentum script and revision notes
- TradingView: Keltner Channel formula and settings
- TradingView: true range and ATR smoothing
- TradingView: realtime values, repainting and confirmation
Compare the component formulas in our Bollinger Bands guide and Keltner Channels guide, or return to TradingView indicators.
Educational information, not investment advice. All numeric trade examples are hypothetical. Indicator states and historical tests do not guarantee future results; trading can lose money.