Skip to content

contango.stream.indicators.calculations.bollinger_bands

contango.stream.indicators.calculations.bollinger_bands

BollingerBandSnapshot

Bases: NamedTuple

A single snapshot of Bollinger Bands.

Attributes:

Name Type Description
upper float

The upper band for the current price.

middle float

The middle band (pure SMA) for the current price.

lower float

The lower band for the current price.

stdev float

The population standard deviation over the lookback window.

BollingerBands

BollingerBands(pd: days = 20, k: float = 2.0)

Bases: Indicator[BollingerBandSnapshot | None]

Rolling Bollinger Bands with variance updates.

Wraps an SMA and tracks a running sum-of-squares so that standard deviation is recomputed in constant time on every tick. Returns None until the lookback window is full.

Parameters:

Name Type Description Default
pd days

Lookback window in bars (default 20).

20
k float

Band-width multiplier in standard deviations (default 2.0).

2.0
Source code in src\contango\stream\indicators\calculations\bollinger_bands.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def __init__(self, pd: days = 20, k: float = 2.0) -> None:
    """
    Args:
        pd: Lookback window in bars (default 20).
        k: Band-width multiplier in standard deviations (default 2.0).
    """
    self._period = pd
    self._k = k

    self._sum: float = 0.0
    self._sum_sq: float = 0.0
    self._count: int = 0

    self._window: list[float] = [0.0] * pd
    self._head: int = 0

    self._value: BollingerBandSnapshot | None = None

value property

value: BollingerBandSnapshot | None

Returns the latest value for the bollinger bands.

update

update(event: MarketDataEvent) -> BollingerBandSnapshot | None

Takes in a new price and return the current bands, or None while the window is still filling.

Parameters:

Name Type Description Default
event MarketDataEvent

The underlying event to update the bollinger bands indicator with.

required

Returns:

Type Description
BollingerBandSnapshot | None

A BollingerBandSnapshot(upper, middle, lower), or None until

BollingerBandSnapshot | None

period prices have been seen.

Source code in src\contango\stream\indicators\calculations\bollinger_bands.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def update(self, event: MarketDataEvent) -> BollingerBandSnapshot | None:
    """
    Takes in a new price and return the current bands, or None while the
    window is still filling.

    Args:
        event: The underlying event to update the bollinger bands indicator with.

    Returns:
        A BollingerBandSnapshot(upper, middle, lower), or None until
        `period` prices have been seen.
    """
    if self._count == self._period:
        oldest = self._window[self._head]
        self._sum -= oldest
        self._sum_sq -= oldest * oldest

    self._window[self._head] = event.close
    self._head = (self._head + 1) % self._period
    self._count = min(self._count + 1, self._period)

    self._sum += event.close
    self._sum_sq += event.close * event.close

    if self._count < self._period:
        return None

    n = self._period
    middle = self._sum / n
    variance = (self._sum_sq - self._sum * self._sum / n) / n
    stdev = variance ** 0.5
    band = self._k * stdev

    self._value = BollingerBandSnapshot(
        upper=middle + band,
        middle=middle,
        lower=middle - band,
        stdev=stdev,
    )
    return self._value