Pine Script Bollinger Bands

Master these dynamic volatility envelopes in TradingView's Pine Script for identifying overbought/oversold conditions, potential trend reversals, and market volatility shifts.

Last Updated on: Expertise: Intermediate

What are Bollinger Bands?

Bollinger Bands (BB) are a widely popular and versatile technical analysis indicator developed by John Bollinger. They consist of three lines:

  1. A Middle Band: Typically a 20-period Simple Moving Average (SMA) of the price.
  2. An Upper Band: Plotted a certain number of standard deviations (typically 2) above the Middle Band.
  3. A Lower Band: Plotted the same number of standard deviations below the Middle Band.

The key feature of Bollinger Bands is their dynamic nature: they expand during periods of high market volatility and contract during periods of low volatility. This adaptability makes them valuable for identifying overbought/oversold conditions relative to the moving average, potential trend reversals, and impending price breakouts following periods of consolidation.

In Pine Script, Bollinger Bands are a fundamental tool for traders seeking to understand price volatility and leverage mean-reversion or breakout strategies.

Components and Calculation

The calculation of Bollinger Bands involves a Simple Moving Average (SMA) and Standard Deviation (StdDev) of price:

  1. Middle Band: A Simple Moving Average of the `close` price over a specified `length` (e.g., 20 periods).
    `Middle Band = SMA(close, length)`
  2. Standard Deviation: Calculate the standard deviation of the `close` price over the same `length`. Standard deviation measures how dispersed the data points are from their average.
    `StdDev = ta.stdev(close, length)`
  3. Upper Band: Add a multiple of the standard deviation to the Middle Band. The `multiplier` is typically 2.
    `Upper Band = Middle Band + (StdDev * multiplier)`
  4. Lower Band: Subtract the same multiple of the standard deviation from the Middle Band.
    `Lower Band = Middle Band - (StdDev * multiplier)`

Approximately 95% of price action is expected to occur within the Upper and Lower Bands when using a 2-standard deviation setting.

Basic Bollinger Bands Implementation in Pine Script

Pine Script v5 provides a convenient built-in function `ta.bb()` for calculating Bollinger Bands.

//@version=5
indicator("My Bollinger Bands", overlay=true) // overlay=true to plot directly on the price chart

// Inputs for Bollinger Bands parameters
length = input.int(20, title="BB Length", minval=1)
stdDevMultiplier = input.float(2.0, title="StdDev Multiplier", minval=0.1, step=0.1)

// Calculate Bollinger Bands using the built-in function
// ta.bb returns the Middle, Upper, and Lower bands
[middleBand, upperBand, lowerBand] = ta.bb(close, length, stdDevMultiplier)

// Plot the Middle Band
plot(middleBand, title="Middle Band", color=color.blue, linewidth=2)

// Plot the Upper and Lower Bands
plot(upperBand, title="Upper Band", color=color.red, linewidth=1)
plot(lowerBand, title="Lower Band", color=color.green, linewidth=1)

// Fill the area between the bands for visual appeal
fill(upperBand, lowerBand, color=color.new(color.blue, 90), title="BB Background")

Dynamic Channels: Unlike fixed channels, Bollinger Bands adapt to current volatility, providing a more context-aware view of price extremes.

Practical Bollinger Bands Trading Strategies

1. Bollinger Band Squeeze (Volatility Contraction)

A "squeeze" occurs when the bands contract significantly, indicating a period of low volatility and consolidation. This often precedes a period of high volatility and a strong price breakout.

//@version=5
strategy("Bollinger Band Squeeze Breakout", overlay=true)

length = input.int(20, title="BB Length", minval=1)
stdDevMultiplier = input.float(2.0, title="StdDev Multiplier", minval=0.1, step=0.1)

[middleBand, upperBand, lowerBand] = ta.bb(close, length, stdDevMultiplier)

plot(middleBand, "Middle Band", color.blue)
plot(upperBand, "Upper Band", color.red)
plot(lowerBand, "Lower Band", color.green)
fill(upperBand, lowerBand, color.new(color.blue, 90))

// Calculate band width relative to middle band for squeeze detection
bandWidth = (upperBand - lowerBand) / middleBand * 100

// Detect a squeeze (e.g., current width is historically low)
// We'll use a simple threshold or look for the lowest width over a longer period
squeezeThreshold = input.float(5.0, title="Squeeze Percentage Threshold", minval=0.1, step=0.1) // Adjust based on asset
isSqueezing = bandWidth < squeezeThreshold

// Entry after squeeze break
longBreakout = isSqueezing[1] and close > upperBand and close[1] <= upperBand[1]
shortBreakout = isSqueezing[1] and close < lowerBand and close[1] >= lowerBand[1]

if (longBreakout)
    strategy.entry("Long Breakout", strategy.long)

if (shortBreakout)
    strategy.entry("Short Breakout", strategy.short)

// Example exit: close on touch of opposite band or after a set number of bars
strategy.exit("Long Exit", from_entry="Long Breakout", stop=lowerBand, limit=middleBand + (upperBand - middleBand) * 0.5) // Exit at middle band or stop loss
strategy.exit("Short Exit", from_entry="Short Breakout", stop=upperBand, limit=middleBand - (middleBand - lowerBand) * 0.5)

2. Band Walks (Trend Following)

In strong trends, price can "walk" along the Upper or Lower Band without touching the Middle Band for extended periods. This indicates strong directional momentum.

//@version=5
strategy("Bollinger Band Walk Strategy", overlay=true)

length = input.int(20, title="BB Length", minval=1)
stdDevMultiplier = input.float(2.0, title="StdDev Multiplier", minval=0.1, step=0.1)

[middleBand, upperBand, lowerBand] = ta.bb(close, length, stdDevMultiplier)

plot(middleBand, "Middle Band", color.blue)
plot(upperBand, "Upper Band", color.red)
plot(lowerBand, "Lower Band", color.green)
fill(upperBand, lowerBand, color.new(color.blue, 90))

// Conditions for a bullish walk (simple example)
isBullishWalk = close > middleBand and close > close[1] and close[1] > middleBand[1] and middleBand > middleBand[1] and close >= upperBand
// Conditions for a bearish walk
isBearishWalk = close < middleBand and close < close[1] and close[1] < middleBand[1] and middleBand < middleBand[1] and close <= lowerBand

if (isBullishWalk)
    strategy.entry("Riding Bull", strategy.long)

if (isBearishWalk)
    strategy.entry("Riding Bear", strategy.short)

// Exit when price breaks the walk or hits middle band
strategy.close("Riding Bull", when=close < middleBand or close[1] < middleBand[1])
strategy.close("Riding Bear", when=close > middleBand or close[1] > middleBand[1])

3. Mean Reversion (Band Bounces)

In sideways or consolidating markets, price often reverts to the Middle Band after touching one of the outer bands. This strategy attempts to capitalize on these "bounces."

//@version=5
strategy("Bollinger Band Mean Reversion", overlay=true)

length = input.int(20, title="BB Length", minval=1)
stdDevMultiplier = input.float(2.0, title="StdDev Multiplier", minval=0.1, step=0.1)

[middleBand, upperBand, lowerBand] = ta.bb(close, length, stdDevMultiplier)

plot(middleBand, "Middle Band", color.blue)
plot(upperBand, "Upper Band", color.red)
plot(lowerBand, "Lower Band", color.green)
fill(upperBand, lowerBand, color.new(color.blue, 90))

// Identify if the market is ranging (e.g., band width is not too wide and not too narrow)
// This is a simplification; a dedicated choppiness index might be better
isRanging = (upperBand - lowerBand) / middleBand * 100 > 1.0 and (upperBand - lowerBand) / middleBand * 100 < 5.0

// Buy when close touches lower band and closes back inside, confirming mean reversion
longReversion = isRanging and close > lowerBand and close[1] <= lowerBand[1]

// Sell when close touches upper band and closes back inside
shortReversion = isRanging and close < upperBand and close[1] >= upperBand[1]

if (longReversion)
    strategy.entry("Buy Reversion", strategy.long)

if (shortReversion)
    strategy.entry("Sell Reversion", strategy.short)

// Exit at Middle Band (target) or if price goes against you
strategy.close("Buy Reversion", when=close > middleBand or close < lowerBand)
strategy.close("Sell Reversion", when=close < middleBand or close > upperBand)

Optimizing Bollinger Bands Performance

To get the most from Bollinger Bands in Pine Script:

Not Just About Price Outside Bands: Price touching or slightly exceeding the bands is not always a direct buy/sell signal. It indicates relative overextension. The subsequent price action (reverting or continuing to ride the band) is what provides the signal.

Common Bollinger Bands Pitfalls

Conclusion

Bollinger Bands are an exceptionally powerful and dynamic technical analysis tool in Pine Script for TradingView. By creating a visual representation of price volatility around a central moving average, they provide traders with invaluable insights into relative overbought/oversold conditions, potential trend reversals, and shifts in market volatility. Whether you are looking to capitalize on volatility squeezes, ride strong trends, or execute mean-reversion strategies, understanding and effectively applying Bollinger Bands, ideally in conjunction with other indicators and robust risk management, can significantly enhance your trading decisions and overall performance.