Bollinger Bands (BB)

Haiyue
10min

I. What is the Bollinger Bands Indicator

Bollinger Bands (BB) is a technical analysis indicator invented by American financial analyst John Bollinger in the early 1980s and officially published in 1983. In 2011, Bollinger trademarked the indicator.

Bollinger Bands belongs to the Volatility / Bands overlay indicator category and is plotted directly on the price chart. It consists of three lines:

  • Middle Band: Simple Moving Average (SMA) of the closing price
  • Upper Band: Middle Band + K times the standard deviation
  • Lower Band: Middle Band - K times the standard deviation

The default parameters are period n=20n = 20, standard deviation multiplier K=2K = 2, and the data source is the closing price.

The core idea behind Bollinger Bands is that price fluctuations are cyclical, and most of the time prices move within the range of “mean +/- 2 standard deviations.” When volatility increases, the bandwidth expands; when volatility decreases, the bandwidth contracts. This “breathing” rhythm provides traders with extremely valuable market state information.

Tip

According to statistical principles, under the normal distribution assumption, approximately 95.4% of data falls within the mean +/- 2 standard deviations. Therefore, the upper and lower bands of Bollinger Bands can be viewed as the “reasonable fluctuation range” of the price.


II. Mathematical Principles and Calculation

2.1 Core Formulas

Let the closing price series be C1,C2,,CtC_1, C_2, \ldots, C_t, the period be nn, and the standard deviation multiplier be KK.

Middle Band:

Middlet=SMA(C,n)=1ni=0n1Cti\text{Middle}_t = \text{SMA}(C, n) = \frac{1}{n} \sum_{i=0}^{n-1} C_{t-i}

Standard Deviation:

σt=1ni=0n1(CtiMiddlet)2\sigma_t = \sqrt{\frac{1}{n} \sum_{i=0}^{n-1} (C_{t-i} - \text{Middle}_t)^2}
Note

Here the population standard deviation (dividing by nn) is used, not the sample standard deviation (dividing by n1n-1). This follows John Bollinger’s original definition.

Upper Band:

Uppert=Middlet+K×σt\text{Upper}_t = \text{Middle}_t + K \times \sigma_t

Lower Band:

Lowert=MiddletK×σt\text{Lower}_t = \text{Middle}_t - K \times \sigma_t

2.2 Derived Indicators

Bandwidth:

BandWidtht=UppertLowertMiddlet×100\text{BandWidth}_t = \frac{\text{Upper}_t - \text{Lower}_t}{\text{Middle}_t} \times 100

Bandwidth quantifies the current volatility level. Extremely low bandwidth values typically foreshadow an upcoming large price movement (the “squeeze” signal).

%B Indicator:

%Bt=CtLowertUppertLowert\%B_t = \frac{C_t - \text{Lower}_t}{\text{Upper}_t - \text{Lower}_t}

%B\%B represents the relative position of the price within the Bollinger Bands: %B=1\%B = 1 means at the upper band, %B=0\%B = 0 means at the lower band, and %B=0.5\%B = 0.5 means at the middle band.

2.3 Calculation Steps

  1. Take the most recent nn closing prices
  2. Calculate the simple moving average of these nn closing prices — this is the middle band
  3. Calculate the population standard deviation of these nn closing prices
  4. Upper Band = Middle Band + K×K \times Standard Deviation
  5. Lower Band = Middle Band - K×K \times Standard Deviation

III. Python Implementation

import numpy as np
import pandas as pd

def bollinger_bands(close: pd.Series, period: int = 20, std_dev: float = 2.0) -> pd.DataFrame:
    """
    Calculate Bollinger Bands (BB).

    Parameters:
        close  : closing price series
        period : moving average period, default 20
        std_dev: standard deviation multiplier, default 2.0

    Returns:
        DataFrame with columns: middle, upper, lower, bandwidth, percent_b
    """
    # Middle band: simple moving average
    middle = close.rolling(window=period).mean()

    # Population standard deviation (ddof=0)
    std = close.rolling(window=period).std(ddof=0)

    # Upper and lower bands
    upper = middle + std_dev * std
    lower = middle - std_dev * std

    # Bandwidth
    bandwidth = (upper - lower) / middle * 100

    # %B
    percent_b = (close - lower) / (upper - lower)

    return pd.DataFrame({
        'middle': middle,
        'upper': upper,
        'lower': lower,
        'bandwidth': bandwidth,
        'percent_b': percent_b
    })


# ============ Usage Example ============
if __name__ == '__main__':
    np.random.seed(42)
    n_days = 100

    # Generate simulated OHLCV data
    base_price = 100 + np.cumsum(np.random.randn(n_days) * 0.5)
    df = pd.DataFrame({
        'open':   base_price + np.random.randn(n_days) * 0.3,
        'high':   base_price + np.abs(np.random.randn(n_days) * 0.8),
        'low':    base_price - np.abs(np.random.randn(n_days) * 0.8),
        'close':  base_price,
        'volume': np.random.randint(1000, 10000, n_days)
    })

    # Calculate Bollinger Bands
    bb = bollinger_bands(df['close'], period=20, std_dev=2.0)
    result = pd.concat([df, bb], axis=1)

    print("=== Bollinger Bands Results (last 10 rows) ===")
    print(result[['close', 'middle', 'upper', 'lower', 'bandwidth', 'percent_b']].tail(10).to_string())

    # Generate trading signals
    result['signal'] = np.where(result['close'] < result['lower'], 'Oversold',
                       np.where(result['close'] > result['upper'], 'Overbought', 'Neutral'))
    print("\n=== Signal Statistics ===")
    print(result['signal'].value_counts())

IV. Problems the Indicator Solves

4.1 Volatility Measurement

The bandwidth of Bollinger Bands directly reflects the current volatility level of the market. When bandwidth contracts to a historical low (i.e., the “Bollinger Band squeeze”), it often foreshadows an upcoming large price movement.

4.2 Overbought / Oversold Detection

  • Price touches or breaks above the upper band: Possibly overbought, with short-term pullback risk
  • Price touches or breaks below the lower band: Possibly oversold, with short-term rebound potential
Warning

Price touching the upper Bollinger Band does not automatically mean a sell signal. In a strong trend, the price can “walk the band,” persistently staying near the upper band. The same applies in reverse. Therefore, do not simply use Bollinger Bands as a contrarian trading tool.

4.3 Typical Trading Strategies

  1. Bollinger Band Squeeze Strategy: Enter in the direction of the breakout when bandwidth expands after contracting to a recent minimum
  2. Mean Reversion Strategy: In range-bound markets, go short when the price touches the upper band and go long when it touches the lower band, with the middle band as the profit target
  3. Double Bollinger Band Strategy: Use both 1x and 2x standard deviation bands simultaneously, dividing the price space into three zones (trend zone, buffer zone, reversal zone)
  4. W-Bottom and M-Top Patterns: A pattern recognition method specifically recommended by John Bollinger — a W-bottom near the lower band is a buy signal, and an M-top near the upper band is a sell signal

4.4 Combining with Other Indicators

  • Combine with RSI to confirm overbought/oversold signals
  • Combine with volume indicators to confirm breakout validity
  • Combine with Keltner Channels to detect the “squeeze” signal

V. Advantages, Disadvantages, and Use Cases

Advantages

AdvantageDescription
Adaptive volatilityBandwidth automatically adjusts with market volatility — no need to manually switch parameters
Intuitive and easy to understandThe relationship between price and the upper/lower bands is immediately clear
VersatileCan be used for both trend identification and mean reversion trading
Solid statistical foundationBased on standard deviation theory with clear probabilistic meaning

Disadvantages

DisadvantageDescription
LaggingBased on SMA and historical standard deviation — inherently a lagging indicator
Normal distribution assumptionFinancial market return distributions typically have “fat tails,” so actual breakout frequency exceeds theoretical values
False signals in trending marketsIn strong trends, price may persistently “walk the band,” causing mean reversion strategies to incur repeated stop-losses
Not reliable aloneNeeds to be combined with other indicators or pattern analysis for confirmation

Use Cases

  • Best suited for: Mean reversion trading in range-bound markets; identifying breakouts after volatility compression
  • Moderately suited for: Trend following in combination with trend indicators
  • Not suited for: Contrarian trading alone in strongly trending markets

Comparison with Similar Indicators

IndicatorVolatility MeasurementCharacteristics
Bollinger BandsStandard deviationSensitive to extreme values; more dramatic bandwidth changes
Keltner ChannelsATRSmoother; less sensitive to extreme values
EnvelopesFixed percentageDoes not adjust with volatility; simplest but least flexible
Tip

Parameter tuning tips: For daily charts, the default parameters (20, 2) are generally sufficient. For more sensitive signals, shorten the period (e.g., 10); to reduce noise, increase the standard deviation multiplier (e.g., 2.5). Bollinger himself suggests that for each doubling of the period, increase the multiplier by 0.1 (e.g., use a 2.1 multiplier for a 50-period setting).