Yes, Bollinger Bands are simple, but small mistakes in data or calculation make them mismatch.
Let break it properly:
So if you are using Bb on less candles data then also this happnes, usally you should use the 20 period by default if anything else, values won’t match.
May be the another reason is standard deviation – if even small variation in how std dev is calculated → visible difference in bands.
If you start with less data, then also this happens so if you are testing this in morning at market starts then it also gives inaccurate values, so you also need to feed some historical data + live candle data (aftermarket start).
Below is the code you can refer:
import math
def calculate_bollinger_bands(candles, period=20):
# Use only closed candles (skip last running candle)
candles = candles[:-1]
if len(candles) < period:
return None
closes = [c["close"] for c in candles]
recent = closes[-period:]
sma = sum(recent) / period
std_dev = math.sqrt(
sum((price - sma) ** 2 for price in recent) / period
)
upper = sma + (2 * std_dev)
lower = sma - (2 * std_dev)
return {
"upper": round(upper, 2),
"middle": round(sma, 2),
"lower": round(lower, 2),
}
candles = [
{"close": 100}, {"close": 101}, {"close": 102}, {"close": 103}, {"close": 104},
{"close": 105}, {"close": 106}, {"close": 107}, {"close": 108}, {"close": 109},
{"close": 110}, {"close": 111}, {"close": 112}, {"close": 113}, {"close": 114},
{"close": 115}, {"close": 116}, {"close": 117}, {"close": 118}, {"close": 119},
{"close": 120} # last candle (running → will be ignored)
]
bb = calculate_bollinger_bands(candles)
print(bb)