Bollinger Bands
Bollinger Bands explained: how the bands, %B and Bandwidth are calculated, and what they describe — and what they do not. Educational content.
What is it?
Created by John Bollinger in the 1980s, Bollinger Bands consist of a middle band (typically a 20-period SMA) and two outer bands plotted at ±2 standard deviations from the middle band. Because standard deviation is a measure of volatility, the bands widen when price is volatile and contract when it is quiet. Approximately 95% of price action falls within the bands under normal distribution assumptions — though crypto markets frequently violate this. The 'Bollinger Squeeze' (bands narrowing to a multi-month low) describes a period of unusually low volatility. It does not say when volatility will rise or in which direction price will move.
How it is calculated
- Middle band: the simple moving average (SMA) of the last 20 closing prices.
- Upper band: the middle band plus 2 × the standard deviation of the same 20 prices.
- Lower band: the middle band minus 2 × that standard deviation.
Both the length (20) and the multiplier (2) are settings. 20 and 2 are the values John Bollinger suggested as a starting point.
Two derived measures: %B and Bandwidth
- %B = (price − lower band) ÷ (upper band − lower band). A value of 1 means price is at the upper band, 0 means it is at the lower band, and 0.5 means it is at the middle band. Above 1 or below 0 means price closed outside the bands.
- Bandwidth = (upper band − lower band) ÷ middle band. It shows how wide the bands are relative to price. The "squeeze" in the free template below is a Bandwidth reading close to its 125-bar low.
What the bands describe — and what they do not
- They describe how far price is from its recent average, measured in units of recent volatility.
- They do not describe direction, a future price, or whether a move will continue. A close outside the bands is a statistical observation, not a forecast.
Related indicators
- Keltner Channels — an EMA middle line with bands based on ATR.
- ATR — volatility measured in price units.
- RSI — momentum on a 0–100 scale.
Common pitfalls
- Touching the band is not an indication by itself. In a trending market, price can walk the upper band for dozens of candles. A band touch on its own says nothing about the trend.
- The 2-standard-deviation setting means roughly 5% of closes will be outside the bands by definition — these are not rare events.
- Bollinger Bands use a simple moving average as the middle band. An EMA-based middle band, as in the Keltner Channel, reacts faster to recent prices.
- A squeeze describes low volatility. It does not tell you whether a larger move will follow, or in which direction.
- Bands calculated on closing prices miss intraday wicks. A wick that pierces the band but closes inside it is not a confirmed band touch.
Indicator Rider — Bollinger Ball
The Bollinger Ball bounces between the upper and lower bands — cyan at the top, orange at the bottom — with squash-and-stretch physics on impact.
Free code template
Paste directly into TradingView Pine Editor → Add to chart.
/indicator("Bollinger Bands — DAI Template", overlay=true)
// ── Inputs ──────────────────────────────────────────────────────────────────
bbLen = input.int(20, "BB Length", minval=1)
bbMult = input.float(2.0, "Multiplier", minval=0.1, step=0.1)
src = input.source(close, "Source")
// ── Calculation ─────────────────────────────────────────────────────────────
[mid, upper, lower] = ta.bb(src, bbLen, bbMult)
bandwidth = (upper - lower) / mid * 100
// ── Plots ───────────────────────────────────────────────────────────────────
pUpper = plot(upper, "Upper Band", color=color.new(#8b5cf6, 20), linewidth=1)
pLower = plot(lower, "Lower Band", color=color.new(#8b5cf6, 20), linewidth=1)
pMid = plot(mid, "Middle SMA", color=color.new(#94a3b8, 40), linewidth=1)
fill(pUpper, pLower, color.new(#8b5cf6, 92))
// ── Squeeze Detection ────────────────────────────────────────────────────────
bwLow = ta.lowest(bandwidth, 125) // 125-bar low of bandwidth
squeeze = bandwidth <= bwLow * 1.05 // within 5% of 125-bar low
bgcolor(squeeze ? color.new(#fbbf24, 90) : na, title="Squeeze Alert")
// ── Band Touch readings ───────────────────────────────────────────────────────
touchUpper = close >= upper
touchLower = close <= lower
plotshape(touchUpper, "Upper Touch", shape.circle, location.abovebar, #ef4444, size=size.tiny)
plotshape(touchLower, "Lower Touch", shape.circle, location.belowbar, #22c55e, size=size.tiny)
alertcondition(squeeze, "BB Squeeze", "Bollinger Bands in squeeze")
alertcondition(touchUpper, "Upper Band Touch","Price closed at or above upper Bollinger Band")
alertcondition(touchLower, "Lower Band Touch","Price closed at or below lower Bollinger Band")Educational content. Not investment advice.