Bollinger Bands
Bollinger Bands (20-period, 2-sigma default). Returns upper / mid / lower band arrays. Edge-first on an upstream close series. Wired to more than one Price Factor, it fans out to per-ticker by_symbol results.
What (One-liner)
Volatility envelope around a moving average (20-day SMA ± 2σ) — feeds breakout and mean-reversion signals.
Inputs
period(number, optional) — lookback, default 20.std_dev(number, optional) — band width in sigmas, default 2.
Outputs
upper—mid + std_dev × sigma.mid— middle band (moving average).lower—mid - std_dev × sigma.by_symbol— per-ticker map when fed by multiple Price Factors.
How to use
- Connect an upstream
price_factor. - Optionally override
periodandstd_dev. - Read
upper/mid/lowerfor envelope-relative signals.
Core formulas
mid = close.rolling(period).mean()
std = close.rolling(period).std(ddof=0)
upper = mid + std_dev × std
lower = mid - std_dev × stdAssumptions & applicability
Assumptions: Bollinger 20 / 2σ defaults + ddof=0 (population std) + pandas-ta equivalent.
Applicability: mean-reversion signals, breakout identification, volatility envelope; equities, FX, crypto, commodities at daily / weekly frequency.
Out of scope: n < period, trending markets (bands hug price).
Known limitations
- Assumes roughly normal dispersion; fat tails break band coverage.
- Band touches are not signals on their own.
- 20 / 2σ defaults are convention; ddof choice affects band width; pandas-ta dispatch dependency.
References
Bollinger (2001), Bollinger on Bollinger Bands; Murphy (1999), textbook explanation.
Golden Test
tests/golden/fixtures/tier1/compute_bollinger/ — tolerance 1e-10 absolute, pandas-ta + manual SMA + rolling std cross-check, last verified 2026-05-25, status passing.
Changelog
- 1.0.0 (2026-05-25) — Activated as canonical Layer-1 transform; merged governance fields from the superseded Layer-0
compute_bollingercard.

