Bollinger %B — where the price sits inside its own bollinger
channel, as a fraction of the channel's width:
percentB = (price − lower) / (upper − lower)
1 is a price on the upper band, 0 on the lower, 0.5 on the centre;
above 1 or below 0 is a price outside its bands. Appends one column,
default 'percentB'.
Not ×100. StockCharts and TradingView both draw %B as a decimal with
0 and 1 as the reference lines, and the whole reading is "is it above
1 / below 0", which the decimal form states directly. The % in the name
is the indicator's, not a unit. (This is the opposite choice from
bollingerBandwidth's ×100, and for the same reason: match the
chart a caller is comparing against, per study.)
One column, read twice — deliberately
The price in the numerator and the price the bands are built from are the
samecolumn. That is the definition (%B places a series inside its
own bands) and it is what makes the flat-window case a genuine 0/0
rather than something over zero. A caller who wants one series placed
inside another's bands has bollinger plus arithmetic; an option
for it here would be a second indicator wearing this one's name.
The flat window is undefined, and here that IS a 0/0
When σ = 0 the denominator 2·stdDev·σ is zero — and so is the
numerator, because a flat window's price is its own mean. A genuine
0/0: the price could be said to sit anywhere in a channel of no width,
so it sits nowhere. undefined.
This is the opposite answer from bollingerBandwidth's 0 on
the same window, and the pair is the clearest illustration of the rule the
package applies: ask whether the numerator is forced to zero
independently of the denominator. BandWidth's is (it is 2·stdDev·σ
itself); %B's is only zero because the window is flat, which is the same
fact as the denominator being zero. bollinger itself draws the
degenerate band there (upper = lower = middle, [PND-BBFLAT]) — a band of
no width is a real thing to draw, but the price's position in it is not
a real thing to report.
Edges
Warm-up is period − 1 rows, and — as with
bollingerBandwidth — it does not compose with the source's when
run over another study's output. Length-preserving.
Scale- AND shift-INVARIANT: numerator and denominator are both
differences of prices in the same units, so a common multiplier cancels
in the ratio and a common offset cancels in the numerator. Unlike
bollingerBandwidth, which is only the first of the two — pinned
by property tests on both studies, because the difference between them
is exactly the mistake a reader would make.
Unbounded. There is no clamp: a price far outside its bands reads
well above 1 or below 0, which is the signal.
A gap costs exactly its own bar. The window statistics skip a
missing cell (see bollingerBandwidth, which therefore loses
nothing), but the numerator reads the bar's own price, so the gap
bar has no position and the next one does. Measured and pinned in
study-missing-cells.test.ts.
On every bar where bollinger emits bands with width, percentB
equals (price − bbLower)/(bbUpper − bbLower); pinned by a test against
the shipped study. The flat window is the one exception: the bands are
drawn there (degenerate) and %B is undefined.
Bollinger %B — where the price sits inside its own bollinger channel, as a fraction of the channel's width:
1is a price on the upper band,0on the lower,0.5on the centre; above1or below0is a price outside its bands. Appends one column, default'percentB'.Not ×100. StockCharts and TradingView both draw %B as a decimal with
0and1as the reference lines, and the whole reading is "is it above 1 / below 0", which the decimal form states directly. The%in the name is the indicator's, not a unit. (This is the opposite choice from bollingerBandwidth's ×100, and for the same reason: match the chart a caller is comparing against, per study.)One
column, read twice — deliberatelyThe price in the numerator and the price the bands are built from are the same
column. That is the definition (%B places a series inside its own bands) and it is what makes the flat-window case a genuine0/0rather than something over zero. A caller who wants one series placed inside another's bands has bollinger plus arithmetic; an option for it here would be a second indicator wearing this one's name.The flat window is
undefined, and here that IS a 0/0When
σ = 0the denominator2·stdDev·σis zero — and so is the numerator, because a flat window's price is its own mean. A genuine0/0: the price could be said to sit anywhere in a channel of no width, so it sits nowhere.undefined.This is the opposite answer from bollingerBandwidth's
0on the same window, and the pair is the clearest illustration of the rule the package applies: ask whether the numerator is forced to zero independently of the denominator. BandWidth's is (it is2·stdDev·σitself); %B's is only zero because the window is flat, which is the same fact as the denominator being zero. bollinger itself draws the degenerate band there (upper = lower = middle, [PND-BBFLAT]) — a band of no width is a real thing to draw, but the price's position in it is not a real thing to report.Edges
period − 1rows, and — as with bollingerBandwidth — it does not compose with the source's when run over another study's output. Length-preserving.1or below0, which is the signal.study-missing-cells.test.ts.bollingeremits bands with width,percentBequals(price − bbLower)/(bbUpper − bbLower); pinned by a test against the shipped study. The flat window is the one exception: the bands are drawn there (degenerate) and %B isundefined.