pub struct BollingerBands { /* private fields */ }Expand description
Bollinger Bands with SMA middle band and population standard deviation envelopes.
Standard parameters are period = 20, multiplier = 2.0. Bollinger’s original
publication uses population (not sample) standard deviation, which matches every
reference implementation (TA-Lib, pandas-ta, etc.).
The running sum and sum_sq are reseeded from the live window every
16 · period updates to cap floating-point drift on long streams. This is
amortised O(1), preserves bit-equivalence with the previous behaviour on
inputs that did not drift, and is particularly important for sum_sq,
where catastrophic cancellation between large add/subtract pairs can drive
the computed variance negative (the .max(0.0) clamp below is the
safety-net for the rare cases where the reseed has not happened yet).
§Example
use wickra_core::{Indicator, BollingerBands};
let mut indicator = BollingerBands::new(5, 2.0).unwrap();
let mut last = None;
for i in 0..80 {
last = indicator.update(100.0 + f64::from(i));
}
assert!(last.is_some());Implementations§
Source§impl BollingerBands
impl BollingerBands
Sourcepub fn new(period: usize, multiplier: f64) -> Result<Self>
pub fn new(period: usize, multiplier: f64) -> Result<Self>
Construct a new Bollinger Bands indicator.
§Errors
Returns Error::PeriodZero for period == 0 and
Error::NonPositiveMultiplier for multiplier <= 0.
Sourcepub const fn multiplier(&self) -> f64
pub const fn multiplier(&self) -> f64
Configured multiplier.
Sourcepub fn batch_bands(&mut self, inputs: &[f64]) -> Vec<f64>
pub fn batch_bands(&mut self, inputs: &[f64]) -> Vec<f64>
Vectorized flat batch for bindings: returns n * 4 values laid out as
[upper, middle, lower, stddev] per input row, warmup rows all NaN.
For a fresh, all-finite slice it inlines update’s rolling sum/sum_sq
and drift-reseed, writing the four band values directly instead of an
Option<BollingerOutput> per element. Same add/subtract order, same reseed
cadence, same variance/sqrt math — so it is bit-for-bit equal to
replaying update, including the long-stream drift bound. Any other state,
or a non-finite element, defers to the exact update replay.
This is a separate entry point from the trait batch,
which returns Vec<Option<BollingerOutput>>; only the bindings, which want
a flat f64 buffer, call this.
Trait Implementations§
Source§impl Clone for BollingerBands
impl Clone for BollingerBands
Source§fn clone(&self) -> BollingerBands
fn clone(&self) -> BollingerBands
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for BollingerBands
impl Debug for BollingerBands
Source§impl Indicator for BollingerBands
impl Indicator for BollingerBands
Source§type Output = BollingerOutput
type Output = BollingerOutput
Source§fn update(&mut self, input: f64) -> Option<BollingerOutput>
fn update(&mut self, input: f64) -> Option<BollingerOutput>
None if the indicator is still warming up.Source§fn reset(&mut self)
fn reset(&mut self)
Source§fn warmup_period(&self) -> usize
fn warmup_period(&self) -> usize
None output can be produced.Auto Trait Implementations§
impl Freeze for BollingerBands
impl RefUnwindSafe for BollingerBands
impl Send for BollingerBands
impl Sync for BollingerBands
impl Unpin for BollingerBands
impl UnsafeUnpin for BollingerBands
impl UnwindSafe for BollingerBands
Blanket Implementations§
Source§impl<T> BatchExt for Twhere
T: Indicator,
impl<T> BatchExt for Twhere
T: Indicator,
Source§fn batch(&mut self, inputs: &[Self::Input]) -> Vec<Option<Self::Output>>
fn batch(&mut self, inputs: &[Self::Input]) -> Vec<Option<Self::Output>>
None during warmup) per input.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more