Bollinger Band Squeeze Meter
The Bollinger Band Squeeze Meter displays the current width of Bollinger Bands as a percentile of their recent historical range. Bollinger Bands consist of an upper and lower band positioned at two standard deviations away from a simple moving average [1]. The bands contract during low volatility and expand during volatile periods. By measuring bandwidth percentile, the distance between bands expressed as a percentage of recent extremes, traders can identify whether current volatility is depressed relative to recent history [1]. The meter reads 0 to 100, where lower readings indicate tighter bands (low volatility) and higher readings indicate wider bands (high volatility).
Traders monitor squeeze conditions to contextualize price consolidation, though the indicator cannot predict direction or the timing of resolution. The tool proves most useful when combined with momentum and trend analysis rather than deployed as a standalone signal.
//@version=6
indicator("Bollinger Band Squeeze Meter", shorttitle="BBSM", overlay=false)
// Inputs
bbLength = input(20, "Bollinger Period", minval=1)
bbDeviations = input(2.0, "Standard Deviations", minval=0.1)
lookbackPeriods = input(50, "Bandwidth Lookback", minval=2)
sourcePrice = input(close, "Source")
// Bollinger Bands
basis = ta.sma(sourcePrice, bbLength)
stddev = ta.stdev(sourcePrice, bbLength)
upperBand = basis + (bbDeviations * stddev)
lowerBand = basis - (bbDeviations * stddev)
// Current bandwidth
currentBandwidth = upperBand - lowerBand
// Highest and lowest bandwidth over lookback period
highestBandwidth = ta.highest(currentBandwidth, lookbackPeriods)
lowestBandwidth = ta.lowest(currentBandwidth, lookbackPeriods)
// Bandwidth percentile: 0 = squeeze floor, 100 = expansion ceiling
bandwidthRange = highestBandwidth - lowestBandwidth
bandwidthPercentile = bandwidthRange > 0 ?
((currentBandwidth - lowestBandwidth) / bandwidthRange) * 100 : 50
// Plot
plot(bandwidthPercentile, color=color.new(color.blue, 0), linewidth=2,
title="Bandwidth Percentile")
hline(50, "Midpoint", linestyle=hline.style_dotted, color=color.gray, linewidth=1)
hline(0, "Squeeze Floor", linestyle=hline.style_dashed, color=color.orange, linewidth=1)
hline(100, "Expansion Ceiling", linestyle=hline.style_dashed, color=color.orange, linewidth=1)
How the code works
The indicator first establishes Bollinger Bands using a 20-period simple moving average and 2 standard deviations (both user-adjustable). It measures the bandwidth: the raw vertical distance between the upper and lower bands on each bar.
Next, it scans backward over a 50-bar window (adjustable) to record the highest and lowest bandwidth values encountered. This establishes a recent historical range. The current bandwidth is then expressed as a percentile of this range: a value of 0 means today's bands are as tight as they have been in the past 50 bars; a value of 100 means they are as wide.
The code guards against division by zero: if the historical bandwidth range is flat (no variation), the percentile defaults to 50. Three horizontal reference lines are plotted: midpoint at 50, and orange dashed lines at 0 and 100 marking the extremes of the lookback window.
Reading it on a chart
A sustained reading near 0 to 20 indicates Bollinger Bands are historically tight. Price scatter around the moving average is suppressed relative to the recent past. Traders often monitor for such squeezes, as low-volatility consolidations sometimes precede rapid moves; however, persistence in low readings does not guarantee a breakout occurs. Some markets enter prolonged low-volatility regimes that resolve slowly or sideways.
A reading near 80 to 100 indicates bands are unusually wide. Price is far from the centerline and volatility is elevated. This commonly occurs during trending moves (when price accelerates away from the average) and can continue for multiple bars without reversal.
Readings near the 50 midpoint suggest bandwidth is at its median level for the recent period, indicating neither historically extreme squeeze nor expansion.
The meter does not forecast direction. A squeeze can resolve upward or downward. It is most useful as a context or filter, for instance, to note that price is in a low-volatility regime, rather than as a primary signal. Pairing the meter with directional tools (moving average slope, momentum oscillators, volume) strengthens a trading hypothesis.
Different timeframes benefit from different lookback periods: intraday charts often work with 15 to 25 bars; daily charts with 50 to 100 bars; weekly charts with 100 to 200 bars.
Limitations
The Bollinger Band Squeeze Meter measures volatility amplitude, not direction or the magnitude of impending moves. A low bandwidth percentile does not guarantee a breakout; markets frequently persist in low-volatility regimes without decisive action. Conversely, a high reading does not signal a reversal; bands remain wide as trending moves accelerate.
Bandwidth is computed as an absolute price distance, not normalized by price level. A 2-point bandwidth on a $200 stock and a 60-point bandwidth on a $5,000 stock represent vastly different proportional volatilities, but this indicator ranks them solely by width. Traders comparing readings across multiple securities or large price-range shifts should adjust expectations accordingly.
The default Bollinger Band parameters (20-period SMA and 2 standard deviations) reflect market convention, not universal optimality [1]. Different asset classes, timeframes, and market regimes may demand different settings. Users should backtest and validate parameters on their own data.
Bollinger Bands assume price returns are approximately normally distributed [1]. Markets prone to gaps, limit moves, or infrequent but extreme events, tail risks, can appear calm in bandwidth terms moments before those shocks occur. The indicator captures historical volatility, not forward-looking tail risk.
Finally, Bollinger Bands rest on a moving average, a lagging construct. The squeeze meter inherently reflects recent-past conditions with built-in lag. It functions best as a secondary filter or context layer alongside concurrent price-action signals, not as a primary entry or exit trigger.
Key definitions
Bollinger Bands: An upper and lower band, each positioned two standard deviations from a simple moving average, used to visualize volatility and price deviation from trend.
Bandwidth: The vertical distance between the upper and lower Bollinger Band on a given bar, measured in price units.
Volatility: The statistical measure of price dispersion, typically computed as the standard deviation of returns over a lookback period.
Squeeze: A market condition in which Bollinger Bands are contracted, indicating low volatility relative to a recent baseline.
Percentile: A statistical rank expressing a value's position within a distribution; the 75th percentile exceeds 75 per cent of all observations.
Standard Deviation: A measure of dispersion around the mean, indicating how far prices typically deviate from the average over a given period.
References
- Bollinger, J., "Bollinger on Bollinger Bands", McGraw-Hill (2001).
- Wikipedia, "Bollinger Bands", en.wikipedia.org. [Online]. Available: https://en.wikipedia.org/wiki/Bollinger_Bands
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-06. Educational research on historical data, not financial advice.
Keep reading
Donchian Channel with Breakout Age Counter
Free open-source Pine Script indicator: Donchian channel with breakout age counter. Full code and a plain-English walkthrough.
Multi-Timeframe Moving Average Alignment Panel
Free open-source Pine Script indicator: multi-timeframe moving average alignment panel. Full code and a plain-English walkthrough.
Premium and Discount Zones
Free open-source Pine Script indicator: premium and discount zones from a rolling range midpoint. Full code and a plain-English walkthrough.