Bollinger Bands (BOLL) consist of three lines that measure voltaility and price dynamics over time.
Mathematical Definition
- Middle Band: N-period Simple Moving Average (SMA) of closing prices, typically using N=20.
- Upper Band: Middle Band + K multiplied by the N-period standard deviation, typically K=2.
- Lower Band: Middle Band - M multiplied by the N-period standard deviation, typically M=2.
Python Implementation
Custom Calculation
Using a custom function with pandas allows for flexibility, particularly when aligning with specific regional trading platform standards.
import pandas as pd
def compute_bollinger(data_frame, window=20, upper_factor=2, lower_factor=2):
sorted_frame = data_frame.sort_values('timestamp')
price_col = sorted_frame['closing_price']
moving_avg = price_col.rolling(window=window).mean()
# Using ddof=0 for population standard deviation (dividing by N)
price_volatility = price_col.rolling(window=window).std(ddof=0)
sorted_frame['middle_band'] = moving_avg
sorted_frame['upper_band'] = moving_avg + (upper_factor * price_volatility)
sorted_frame['lower_band'] = moving_avg - (lower_factor * price_volatility)
return sorted_frame
TA-Lib Implementation
The TA-Lib library provides a highly optimized built-in function for Bollinger Bands.
import talib as ta
import pandas as pd
upper_band, middle_band, lower_band = ta.BBANDS(
data_frame['closing_price'],
timeperiod=20,
nbdevup=2,
nbdevdn=2,
matype=0
)
bands_df = pd.DataFrame({
'upper_band': upper_band,
'middle_band': middle_band,
'lower_band': lower_band
})
combined_data = pd.concat([data_frame, bands_df], axis=1)
Standard Deviation Discrepancy
A numerical difference exists between the custom pandas calculation and the TA-Lib output due to how standard deviation is computed.
| Method | Standard Deviation Type | Divisor |
|---|---|---|
Custom (pandas with ddof=0) |
Population | n |
| TA-Lib | Sample | n-1 |
Domestic securities platforms typical display Bollinger Bands based on population standard deviation. To replicate this behavior in pandas, explicitly set ddof=0 in the .std() method; otherwise, pandas defaults to sample standard deviation (ddof=1).