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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.stdevis the population version by default, likeStdDevin EasyLanguage andiBandsin 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 minus2 * ta.atr(20).ta.kchas 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.entrywithstop = pivotandlimit = pivot * 1.05.
MultiCharts and TradeStation (EasyLanguage)
- Use
StdDev(population) for the bands.StdDevSis 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.AvgTrueRangeis 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 stoplives 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)
iBandsgives bands on the population deviation, and bandwidth is calculated from the buffers manually.- There is no built-in Keltner:
iMAin EMA mode plus ATR.iATRis 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.