Bollinger Band Squeeze Meter
A squeeze meter measures how tight Bollinger Bands have contracted relative to recent history. When bands narrow sharply, implied volatility drops and prices often consolidate, occasionally breaking out sharply afterward. This indicator expresses current bandwidth as a percentile rank from 0 (tightest squeeze on record) to 100 (widest expansion), helping traders identify regime shifts without visual estimation.
Traders monitoring mean-reversion strategies or breakout setups often watch for extreme squeeze conditions; the percentile format removes interpretation ambiguity and works across any instrument or timeframe.
//@version=6
indicator("Bollinger Band Squeeze Meter", shorty="BB Squeeze", overlay=false, max_bars_back=500)
// Inputs
bbLength = input.int(20, "Bollinger Bands Period", minval=1)
bbMult = input.float(2.0, "Bollinger Bands Std Dev Multiplier", minval=0.1)
percentileLen = input.int(252, "Percentile Lookback Bars", minval=10)
squeezeThreshold = input.int(30, "Squeeze Alert Threshold (%)", minval=1, maxval=50)
// Calculate Bollinger Bands
basis = ta.sma(close, bbLength)
deviation = bbMult * ta.stdev(close, bbLength)
upperBand = basis + deviation
lowerBand = basis - deviation
// Bandwidth = width of the band envelope
bandwidth = upperBand - lowerBand
// Historical min and max bandwidth over lookback period
minBandwidth = ta.lowest(bandwidth, percentileLen)
maxBandwidth = ta.highest(bandwidth, percentileLen)
// Bandwidth percentile: 0 = tightest squeeze, 100 = widest expansion
bwRange = maxBandwidth - minBandwidth
bwPercentile = bwRange == 0 ? 50 : (bandwidth - minBandwidth) / bwRange * 100
// Plots
plot(bwPercentile, "Squeeze Percentile", color=color.new(color.blue, 0), linewidth=2)
hline(50, "Median", color=color.gray, linestyle=hline.style_dashed, editable=false)
hline(squeezeThreshold, "Squeeze Threshold", color=color.orange, linestyle=hline.style_dotted)
hline(0, "Min (Most Squeezed)", color=color.new(color.red, 50), linestyle=hline.style_dotted, editable=false)
hline(100, "Max (Most Expanded)", color=color.new(color.green, 50), linestyle=hline.style_dotted, editable=false)
// Background shading for high-squeeze zone
bgcolor(bwPercentile < squeezeThreshold ? color.new(color.orange, 85) : na, title="High Squeeze Zone")
How the code works
The indicator first computes standard Bollinger Bands by taking a simple moving average (basis) and adding/subtracting a multiple of the standard deviation of closing prices. The bandwidth is the difference between the upper and lower bands, measured in price units.
To convert bandwidth into a percentile, the code tracks the lowest and highest bandwidth values seen over the lookback period (defaulting to 252 bars, roughly one year on a daily chart). The percentile formula then maps the current bandwidth linearly from 0 (matching the historical minimum) to 100 (matching the historical maximum). When current bandwidth equals the lowest value ever seen in the lookback window, the percentile reads 0 (the band squeeze is as tight as it has been); when it reaches the highest value, the percentile reads 100 (expansion is maximal).
The horizontal reference lines mark the 50th percentile (median), the squeeze threshold (default 30th, adjustable), and the extremes. The orange shading highlights periods when the percentile falls below the threshold, signaling elevated squeeze conditions.
Reading it on a chart
A squeeze meter reading of 0-30 percentile indicates the bands are unusually contracted; traders watching for volatility expansion or breakouts often monitor this zone. Readings above 70 indicate bands are wider than average, consistent with a trend or elevated volatility regime. The 50th percentile line marks the center of the historical range, useful for confirming mean reversion.
The key tells traders how squeezed the market is right now relative to what they have seen before, without forcing them to mentally compare band widths across months of price history. On daily charts, a plunge from 50 to 10 percentile signals a sharp contraction; a climb from 30 to 80 suggests volatility has expanded. Neither movement predicts a breakout direction, but both signal a regime change worth noting.
The threshold input (default 30) is tunable; setting it lower (10-20) creates a stricter squeeze alert, higher (40-50) relaxes it for choppier instruments.
Limitations
The indicator is purely descriptive; it shows how tight bands are right now but says nothing about when they will break or in which direction. Many assets oscillate in and out of squeeze states throughout a session without pronounced breakouts. Percentile rank depends critically on the lookback period; a 252-bar window may be too short on monthly charts or too long on 1-minute charts, requiring manual adjustment per timeframe.
Bandwidth percentile also lags regime shifts: if volatility has sustained a structural increase (a shock, regime change, or earnings event), the lookback window may reset the baseline, making a new "high" percentile read as normal instead of exceptional. The Bollinger Bands period (default 20) and standard deviation multiplier (default 2.0) are not tuned to any specific asset class or volatility regime; users trading low-volatility currency pairs or high-volatility crypto will find the defaults approximate and may need to recalibrate.
Finally, the indicator assumes historical percentiles are predictive of future structure. In highly non-stationary markets or following major economic releases, the relationship breaks down.
Key definitions
Bollinger Bands: A volatility envelope consisting of a middle moving average and upper/lower bands set at a fixed number of standard deviations away, tracking the range of recent price movement.
Bandwidth: The distance between the upper and lower Bollinger Bands, expressed in price units; contracts during low-volatility periods (squeeze) and expands during high volatility.
Squeeze: A period of abnormally low volatility in which Bollinger Bands narrow sharply, often preceding a large directional move.
Percentile rank: The position of a value within a historical distribution, expressed as a percentage from 0 (minimum) to 100 (maximum).
Implied volatility: The degree of price movement investors expect over a given period; reflected in the width of Bollinger Bands, narrower bands signal lower expected volatility.
Standard deviation: A statistical measure of how widely prices deviate from their average; used in Bollinger Bands to scale the distance of the upper and lower bands.
References
[1] Bollinger, J., Bollinger on Bollinger Bands, McGraw-Hill (2001).
[2] Investopedia, "Bollinger Bands: Definition, How to Use Them, and Indicators", Investopedia. Https://www.investopedia.com/terms/b/bollingerbands.asp
[3] TradingView, Pine Script Reference Manual v6, TradingView Inc. Https://www.tradingview.com/pine-script-docs/
[4] CME Group, "Volatility Derivatives and Trading", CME Group Education. Https://www.cmegroup.com/education.html
Educational research on historical data only. Not investment advice, not a signal, and never a performance promise. Past results do not predict future performance. Every reference is link-verified before publication and every paper is re-audited weekly against the library's editorial standard.
Last reviewed by the PropLedger research pipeline: 2026-09-21. Educational research on historical data, not financial advice.
Keep reading
Prior Day High, Low, and Settlement
Free open-source Pine Script indicator: prior day high, low, and settlement levels. Full code and a plain-English walkthrough.
Seasonality Heat Strip: Month-of-Year Average Returns
Free open-source Pine Script indicator: seasonality heat strip: month-of-year average returns. Full code and a plain-English walkthrough.
Spread Tracker: Futures Pair
Free open-source Pine Script indicator: spread tracker between two related futures contracts. Full code and a plain-English walkthrough.