pub struct Sma { /* private fields */ }Expand description
Simple Moving Average over a fixed window.
Maintains a rolling sum so each update is O(1). Output equals
sum(last period prices) / period once the window is full; None before.
On long-running streams a single-subtract incremental sum can accumulate
rounding error (catastrophic cancellation when values of very different
magnitudes are alternately added and removed). To keep drift bounded, the
running sum is reseeded from the live window every 16 · period updates —
O(1) amortised cost (O(period) work amortised over O(period) updates),
zero observable behaviour change on inputs that did not drift to begin
with, and a strict cap on accumulated rounding for streams that did.
§Example
use wickra_core::{Indicator, Sma};
let mut indicator = Sma::new(3).unwrap();
let mut last = None;
for i in 0..80 {
last = indicator.update(100.0 + f64::from(i));
}
assert!(last.is_some());Implementations§
Trait Implementations§
Source§impl Indicator for Sma
impl Indicator for Sma
Source§fn batch_nan_into(&mut self, inputs: &[f64], out: &mut [f64])
fn batch_nan_into(&mut self, inputs: &[f64], out: &mut [f64])
For a fresh, all-finite slice this inlines update’s rolling sum and
drift-reseed, writing the mean as a bare f64 (warmup → NaN) straight
into out. Same add/subtract order, same reseed cadence, same
sum / period division — 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.
Source§fn batch_fast_into(&mut self, inputs: &[f64], out: &mut [f64])
fn batch_fast_into(&mut self, inputs: &[f64], out: &mut [f64])
SIMD kernel: rolling sums as a prefix scan of x[i] - x[i - period],
re-anchored on an exact window sum every 16 · period values like the
exact path’s reseed, each sum scaled by 1 / period. Agrees with the
exact batch to within a few units in the last place (a multiply by the
reciprocal replaces the division, and the running sum is reassociated);
warmup NaNs and length are identical. Afterwards the window holds the
last period inputs and its sum is recomputed exactly, so streaming
continues from a freshly reseeded state.
Source§fn update(&mut self, input: f64) -> Option<f64>
fn update(&mut self, input: f64) -> Option<f64>
None if there is no value for this input. Read moreSource§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 Sma
impl RefUnwindSafe for Sma
impl Send for Sma
impl Sync for Sma
impl Unpin for Sma
impl UnsafeUnpin for Sma
impl UnwindSafe for Sma
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> BatchNanExt for T
impl<T> BatchNanExt for T
Source§fn batch_nan(&mut self, inputs: &[f64]) -> Vec<f64>
fn batch_nan(&mut self, inputs: &[f64]) -> Vec<f64>
f64 per input, warmup positions filled with NaN, bit-for-bit equal
to replaying update.Source§fn batch_fast(&mut self, inputs: &[f64]) -> Vec<f64>
fn batch_fast(&mut self, inputs: &[f64]) -> Vec<f64>
Indicator::batch_fast_into) into a fresh
vector: within the indicator’s documented tolerance of
batch_nan, deterministic across platforms.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