← All ideas
#018Regime filterSwing

Bollinger squeeze: band width at its 125-bar low

The squeeze as Bollinger defines it: band width at its lowest in 125 bars. Bollinger did not name the breakout direction, so we formalize the entry and exit. Variants: bands inside Keltner and the weekly TTM Squeeze.

The Algorithmic Advantage · John Bollinger · Watch video

Markets

Stocks, Indices, Futures, Forex, Crypto

Timeframe

D1, W1

Data

OHLC, Volume

Rules

Partly formalised

Difficulty

Easy

Status

Untested

Some rules were added by us and are marked in the text.

TradingView ports directly
EasyLanguage has pitfalls
MetaTrader 5 has pitfalls

Idea in brief

Bollinger Bands are built on the standard deviation of closes, so they narrow quickly when the market goes quiet. A squeeze is the moment when the bands have become very narrow. It is usually spotted by eye. John Bollinger has a precise definition: bandwidth, the distance between the bands divided by the middle line, has dropped to its lowest level in 125 periods. Bollinger calls this rule inviolable and says their team trades the squeeze often.

A squeeze describes a state, not a trade. Bollinger did not say which direction to enter or where to exit. In this card, those rules are formalized by us and marked. Variant B: the classic approach that Bollinger mentions directly (Bollinger Bands entirely inside the Keltner channel). Variant C: the weekly TTM Squeeze for leading stocks from the Financial Wisdom video, where the breakout rules are already named.

Why it might work

Bollinger explains the durability of the bands by the fact that they rest on a first principle of the market, volatility. Volatility itself changes: quiet periods give way to expansion. A band width low over half a year of daily bars marks the point where the lull has reached the edge of its recent history, and expansion becomes more likely.

Comparing with the Keltner channel adds a second measure. Keltner is built on ATR, that is, the typical bar range, and it changes more slowly. When the Bollinger Bands move inside Keltner, the dispersion of closes has contracted more than the normal range of bars. The Financial Wisdom author describes this as energy building up: in the author's view, the stronger the rise before the consolidation, the more powerful the move out of it.

None of the authors showed that volatility expansion after a squeeze produces profit in a particular direction. The direction has to be set by a separate rule.

Rules

Squeeze (author)

Mid   = SMA(Close, 20)
SD    = StdDev(Close, 20)                // population standard deviation
Upper = Mid + 2 * SD
Lower = Mid - 2 * SD
// Finetiq: length 20 and multiplier 2. Bollinger's own band parameters were not clearly named in the interview

BandWidth = (Upper - Lower) / Mid                     // author
Squeeze   = BandWidth <= Lowest(BandWidth, 125)       // author: 125-period low
// Finetiq: the current bar is included in the 125-bar window

Entry and exit after a squeeze (Finetiq)

// Bollinger did not name the direction or the breakout trigger. Everything in this block is our formalization
Armed = Squeeze on at least one of the last 10 bars          // Finetiq

IF Armed AND Close > Upper THEN BUY AT NEXT BAR OPEN          // Finetiq: close beyond the band
IF Armed AND Close < Lower THEN SELL SHORT AT NEXT BAR OPEN

Long:  StopLoss = Lower on the signal bar                      // Finetiq: the opposite band
       IF Close < Mid THEN EXIT AT NEXT BAR OPEN               // Finetiq: return to the average
Short: StopLoss = Upper on the signal bar
       IF Close > Mid THEN EXIT AT NEXT BAR OPEN

// after an exit, a new entry only after a new squeeze          // Finetiq

Variant B. Bands inside Keltner (Bollinger)

KC_Mid = EMA(Close, 20)                // author: EMA 20 or 21
KC_Up  = KC_Mid + 2 * ATR(20)          // author: 2 ATR; Finetiq: ATR period 20, Wilder smoothing
KC_Low = KC_Mid - 2 * ATR(20)

InsideKC = Upper < KC_Up AND Lower > KC_Low       // author: both Bollinger Bands inside Keltner

// author: then "look for a volatility breakout", the trigger is not named
Fired = InsideKC[1] AND NOT InsideKC               // Finetiq: the first bar out of the compression
Armed = Fired on at least one of the last 5 bars   // Finetiq
// entry, stop and exit as in the main version

Variant C. Weekly TTM Squeeze (Financial Wisdom)

// weekly bars, stocks from the screen (see below)
// BB and Keltner as in variant B, Keltner multiplier 1.5 (stricter, less than 5% of the time) or 2.0 (author)
// Finetiq: lengths 20; the author uses a ready-made TradingView indicator where they can be changed

SqueezeWeeks = number of InsideKC weeks over the last 8 weeks
Setup = SqueezeWeeks >= 3                          // author: "several red dots"; Finetiq: 3 of 8
Pivot = Highest(High, 8)[1]                        // author: high of the consolidation (for a cup with handle, the high of the handle)
                                                   // Finetiq: 8 weeks

IF Setup
    BUY STOP at Pivot LIMIT Pivot * 1.05           // author: no more than 5% beyond the pivot
// author: the breakout must be confirmed by volume
IF Volume of the breakout week < 1.5 * Average(Volume, 10)[1]   // Finetiq: 1.5× threshold
    EXIT AT NEXT BAR OPEN

StopLoss = Low of the breakout week or the nearest swing low   // author
// author: with a wide stop (Robinhood example, 11%), reduce the position size
IF Close < SMA(Close, 10) THEN EXIT AT NEXT BAR OPEN     // Finetiq: the author did not name an exit

// Stock selection (author): a separate rule across the whole universe
// market cap from $2 billion, sorted by return over a year, top 30,
// or stocks from the trend template with RS of 90+. The signal above is calculated on each stock separately

Parameters

Parameter Value Source
Bollinger Bands SMA 20, 2 standard deviations Finetiq
Bandwidth (Upper − Lower) / Mid author
Low window 125 bars author
Squeeze stays "active" 10 bars Finetiq
Trigger close beyond the band Finetiq
Stop opposite band on the signal bar Finetiq
Exit close on the other side of the average Finetiq
Keltner EMA 20-21, 2 ATR author
ATR period 20, Wilder smoothing Finetiq
Variant C: Keltner multiplier 1.5 or 2.0 author
Variant C: timeframe week author
Variant C: setup 3 squeeze weeks out of 8 Finetiq
Variant C: pivot 8-week high Finetiq
Variant C: maximum entry pivot + 5% author
Variant C: volume 1.5× the 10-week average Finetiq
Variant C: stop low of the breakout week or swing low author
Variant C: exit close below the 10-week SMA Finetiq
Variant C: screening from $2 billion, top 30 over a year author

What to test

  1. Does the squeeze predict expansion. Calculate the average ATR(10) and the absolute price change over 10 bars after a squeeze and after random days. If volatility does not rise noticeably more after a squeeze, breakout rules on top of it have nothing to stand on.
  2. The squeeze as a breakout filter. The same trade on a close beyond the band: only after a squeeze versus any close beyond the band. This is a direct test of whether Bollinger's definition adds anything to a band breakout.
  3. Parameter neighborhood using Bollinger's method. Bollinger personally tests neighboring values (for a 20 average this is 16-24) and discards the system if the results are not similar. Run a low window of 100, 110, 125, 140, 150 and a band length of 16-24.
  4. Direction trigger. A close beyond the band versus stop orders beyond the high and low of the squeeze period and versus entering only with the trend (price above SMA 50 for buys). This is the weakest part of the card, and the author does not have it.
  5. Two definitions of compression. How often the 125-period bandwidth low and bands inside Keltner coincide with multipliers of 1.5 and 2.0. Test the Financial Wisdom claim about 5% of the time on your markets.
  6. Daily versus weekly, stocks versus futures. A squeeze behaves differently in quiet markets (bonds, currencies) and in stocks. Look at the result for each asset class separately.
  7. False breakouts. The share of trades closed by the stop within the first 5 bars. If it is high, try entering on a second close beyond the band.

Platform notes

TradingView (Pine Script)

  • ta.stdev is the population version by default, like StdDev in EasyLanguage and iBands in MT5. Band width will match across the three platforms.
  • Bandwidth and its low are easier to calculate yourself: bw = (upper - lower) / basis, squeeze = bw <= ta.lowest(bw, 125).
  • Build the Keltner channel for variant B yourself: ta.ema(close, 20) plus or minus 2 * ta.atr(20). ta.kc has its own implementation, and the compression frequency with it may differ from the source.
  • Weekly variant C needs enough history to warm up the averages (20 weeks) plus the 8-week squeeze window. If you test the 125-period low from the main version on weekly bars, you need another 125 weeks, about 2.5 years. History depth depends on the subscription plan. Stop-limit at the pivot: strategy.entry with stop = pivot and limit = pivot * 1.05.

MultiCharts and TradeStation (EasyLanguage)

  • Use StdDev (population) for the bands. StdDevS is the sample version: the bands will be wider, and the width lows will shift.
  • Lowest(BW, 125) includes the current bar, as in the rules. Store the width in a variable, otherwise the function will recalculate the bands at every step of the window.
  • AvgTrueRange is a simple average of TR. A Keltner channel built on it is narrower or wider than one on Wilder ATR, and compression in variant B will occur at a different frequency. To match Pine, calculate Wilder ATR manually.
  • Buy next bar at Pivot stop lives for one bar. On a weekly chart, send the order every week and emulate the 5% limit with a check of the open.

MetaTrader 5 (MQL5)

  • iBands gives bands on the population deviation, and bandwidth is calculated from the buffers manually.
  • There is no built-in Keltner: iMA in EMA mode plus ATR. iATR is a simple average of TR, so Wilder is needed to match Pine.
  • At some brokers, short Sunday bars on D1 add extra closes to the 20 and 125 windows. Band width and its low get distorted by this.
  • The weekly variant on stock CFDs runs into the broker's history and volume: CFDs have only tick volume, so breakout confirmation based on it is approximate.

Where the idea can break

  • Bollinger gave a definition of the squeeze, not a system. The direction, stop and exit are ours. If the result is poor, this may be a weakness of our formalization rather than of the squeeze.
  • The band parameters were not clearly audible in the transcript. We took the standard 20 and 2, Bollinger may have used others.
  • A lull can last a long time. In quiet trends, band width declines gradually, and squeezes come in series without a subsequent expansion.
  • The Financial Wisdom examples were picked in hindsight, all of them winners, with no statistics. The weekly variant relies on screening for the top 30 stocks and RS of 90+, which Pine and MT5 do not have.
  • Keltner implementations differ between platforms. The compression frequency and the set of trades in variant B may not match even on the same data.

Sources

Author's claims

These figures and statements are the author's. We have not verified them.

  • Bollinger: the approach "both Bollinger Bands inside the Keltner channels, then a volatility breakout" has existed for 20-25 years and still works. Bollinger gives no numeric results.
  • According to Bollinger, on US stocks about 90% of the data lies inside the ±2 standard deviation bands, not 95% as it would under a normal distribution.
  • The Financial Wisdom author: a squeeze with a 1.5 ATR Keltner channel occurs less than 5% of the time.
  • Financial Wisdom examples picked in hindsight: Robinhood (pivot $51.30, stop $45.50, risk 11%, then +121% in 71 days), Nvidia in 2023 (risk 6.5%, then +200% in less than a year), AppLovin (breakout at $44 with a 14% stop, +100%, then from the $95 pivot another +450% in 8 months).

Related ideas

Updated: 2026-09-10