BollingerPercentB — Bollinger %B
תוכן זה אינו זמין עדיין בשפה שלך.
Where the close sits inside the Bollinger bands: 0 at the lower band, 1 at the upper, 0.5 at the mean, outside [0, 1] beyond the bands. The band position as a portable number — comparable across instruments in a way raw band distance is not.
Signature
BollingerPercentB(period, multiplier, on=<source>)| Argument | Type | Required | Notes |
|---|---|---|---|
period |
int Param or literal | Yes | Bollinger window. Default 20, bounds 2–400. |
multiplier |
float Param or literal | Yes | Band width in standard deviations. Default 2.0, bounds 0.1–10.0. |
on= |
symbol, OHLCV field, or indicator | No | Source. Defaults to the trade symbol’s close. |
Formula
$$ %B = \frac{C - \text{lower}}{\text{upper} - \text{lower}} $$
Warmup
period bars; 0.5 (the mean) until then, and 0.5 when the bands collapse on a flat window.
Reading the value
pb.valuepb < 0pb.crossed_above(0.5)Example
class PercentBReversion(Strategy): """Buy a close below the lower band, exit at the mean.""" trade = Symbol() sizing = FixedCapital()
def execute(self): pb = BollingerPercentB(20, 2.0, on=self.trade) if pb.value < 0 and self.trade.is_flat: self.buy(self.trade, reason=f"%B {pb.value:.2f}") if pb.value > 0.5 and self.trade.is_long: self.sell(self.trade, self.trade.position, reason="At the mean")Notes
- John Bollinger’s %B. Equivalent to a rescaled
ZScore:%B = z/(2m) + 0.5. - Proven by an assert-via-trade run on SPY daily (matched a strategy-side reference to 1e-3 on every bar; zero alarm trades).
- Flat-window sentinel is 0.5 — the neutral middle, not a band touch.