Volatility
Bollinger Bands Signals: Touches, Compression and Breakouts
Distinguish band-touch, compression and breakout rules with a Pine Script example. Check the exact conditions instead of assuming a measured reversal probability.
Bollinger Bands Signal Interpretation
Quick-reference guide to 5 signal types you will see on the chart.
| Signal Type | Indicator Condition | Market Meaning | Interpretation limits |
|---|---|---|---|
| Lower-band rejection example | Low touches/breaches lower band, close returns above it, and close exceeds open | The completed bar recovered relative to its final lower band. | Does not prove a bottom; the band also moves during the bar. |
| Upper-band rejection example | High touches/breaches upper band, close returns below it, and close is below open | The completed bar retreated relative to its final upper band. | Does not prove a top or require a subsequent decline. |
| Compression state | Raw band width is below its moving average and below its value one lookback ago | This example’s exact two-comparison definition. | Not necessarily the lowest width in the window. |
| Breakout following compression | Prior bar satisfied compression; current close finishes outside a band | A one-bar sequence of defined events. | No minimum expansion size or duration is implied. |
| Three closes outside a band | Three consecutive closes beyond the same boundary | An example of persistence rather than a bounce. | Can continue or fail; no reliability score is established. |
Bollinger Bands Pine Script Signal Code
Educational indicator example. Review its exact rules and compare its plots with your intended calculation in TradingView. It does not place orders or establish profitability.
Pine Script v6
//@version=6
indicator("Bollinger Band Condition Examples", overlay=true)
bbLength = input.int(20, "BB Length", minval=1)
bbMult = input.float(2.0, "BB Std Dev", minval=0.1)
src = input.source(close, "Source")
squeezeLookback = input.int(20, "Squeeze Lookback", minval=1, tooltip="Number of bars for squeeze comparison baseline")
// Bollinger Bands calculation
basis = ta.sma(src, bbLength)
dev = bbMult * ta.stdev(src, bbLength)
upper = basis + dev
lower = basis - dev
// Band width
bandWidth = upper - lower
avgBandWidth = ta.sma(bandWidth, squeezeLookback)
// Buy signal: price touches lower band, closes back inside
lowerTouch = low <= lower
lowerBounce = close > lower
buySignal = barstate.isconfirmed and lowerTouch and lowerBounce and close > open
// Sell signal: price touches upper band, closes back inside
upperTouch = high >= upper
upperReject = close < upper
sellSignal = barstate.isconfirmed and upperTouch and upperReject and close < open
// Squeeze detection
isSqueeze = bandWidth < avgBandWidth and bandWidth < bandWidth[squeezeLookback]
squeezeBreakoutUp = barstate.isconfirmed and isSqueeze[1] and close > upper
squeezeBreakoutDown = barstate.isconfirmed and isSqueeze[1] and close < lower
// Band walk detection: 3+ consecutive closes outside a band
walkUp = barstate.isconfirmed and close > upper and close[1] > upper[1] and close[2] > upper[2]
walkDown = barstate.isconfirmed and close < lower and close[1] < lower[1] and close[2] < lower[2]
// Plot Bollinger Bands
plot(basis, "Basis", color=#2962FF, linewidth=2)
p1 = plot(upper, "Upper", color=#FF5252, linewidth=1)
p2 = plot(lower, "Lower", color=#4CAF50, linewidth=1)
fill(p1, p2, color=color.new(color.gray, 92), title="Band Fill")
// Plot buy and sell signals on the price chart
plotshape(buySignal, "Lower-band rejection", shape.triangleup, location.belowbar, color=#4CAF50, size=size.small)
plotshape(sellSignal, "Upper-band rejection", shape.triangledown, location.abovebar, color=#FF5252, size=size.small)
// Squeeze markers
plotshape(squeezeBreakoutUp, "Squeeze Buy", shape.labelup, location.belowbar, color=#00BCD4, size=size.small)
plotshape(squeezeBreakoutDown, "Squeeze Sell", shape.labeldown, location.abovebar, color=#FF9800, size=size.small)
// Band walk labels
plotshape(walkUp, "Band Walk Up", shape.circle, location.abovebar, color=#E040FB, size=size.tiny)
plotshape(walkDown, "Band Walk Down", shape.circle, location.belowbar, color=#E040FB, size=size.tiny)
// Band width subplot
plot(bandWidth, "Band Width", color=#757575, display=display.none)
alertcondition(buySignal, "BB Lower Band Rejection", "Price closed above the lower Bollinger Band after touching it")
alertcondition(sellSignal, "BB Upper Band Rejection", "Price closed below the upper Bollinger Band after touching it")
alertcondition(barstate.isconfirmed and isSqueeze, "BB Squeeze", "Confirmed width below its average and its lookback-ago value")
alertcondition(squeezeBreakoutUp, "BB Squeeze Breakout Up", "Price broke above upper band after a squeeze")
alertcondition(squeezeBreakoutDown, "BB Squeeze Breakout Down", "Price broke below lower band after a squeeze")Example settings for Bollinger Bands
Record the inputs used by the example. These settings are not an optimized trading recommendation.
| Parameter | Default | Description |
|---|---|---|
| BB Length | 20, example | Lookback for the SMA basis and standard deviation. The script uses an SMA rather than every available built-in basis type. |
| BB Std Dev | 2.0, example | Multiplier applied to measured dispersion. It does not establish 95% coverage for future prices. |
| Source | Close | Used for band calculation; touch rules separately compare chart high, low, open and close. |
| Squeeze Lookback | 20, example | Controls the width average and the single past-width comparison. It is not a rolling minimum operator. |
Turn the condition into an explicit rule
Specify the calculation, confirmation time, entry and exit rules before asking Pineify to draft or revise Pine Script. Review the code and simulate realistic costs before evaluating a strategy.
Explore Pine Script codingRelated Resources
FAQ
Bollinger Bands Signals FAQ
Is a band touch an instruction to buy or sell?
No. A band is a calculated boundary and price can continue outside it. The example requires a particular completed candle for its rejection marker, without claiming that this predicts the next move.
What does the compression rule actually test?
It compares raw width with its moving average and one value a lookback ago. To test a rolling minimum, percentile or Keltner-channel squeeze, implement that different definition explicitly. Do not label these interchangeable.
How is %B different from width?
%B expresses the source’s position between lower and upper bands; it can be below zero or above one. Width measures separation. A %B of 0.5 corresponds to the basis, not a confirmed trend re-entry. The example does not emit %B alerts.
Are Bollinger Bands always wider than Keltner Channels?
No. They use different dispersion measures and inputs. Neither relative width nor comparative win rate is fixed across markets.
How should I evaluate combined RSI and band conditions?
Write both conditions and their confirmation times, then compare the complete rule with a baseline using costs and reserved data. Adding an oscillator does not itself establish improved accuracy.
What happens during news or an open bar?
New observations can change the bands, and a wick is compared with the final calculated boundary in this example. Markers wait for close. This is a bar-based condition, not a reconstruction of the exact intrabar order of touches.