pub struct StandardError { /* private fields */ }Expand description
Standard Error of the regression line fit over the last period inputs.
Over the trailing window indexed x = 0, 1, …, period − 1 the OLS line
y = a + b·x is fitted, then:
slope = (n·Σxy − Σx·Σy) / (n·Σxx − (Σx)²)
SS_total = Σy² − n·ȳ² // total sum of squares
RSS = SS_total − slope² · S_xx // residual sum of squares
StdErr = √( RSS / (n − 2) ) // n − 2 residual d.o.f.where S_xx = (n·Σxx − (Σx)²) / n is the centred sum of squares of the
design.
This is the textbook standard error of estimate of OLS: it measures
the typical distance between the observed prices and the fitted line,
using the residual degrees of freedom n − 2. It is the spread that
drives crate::BollingerBands-style bands around a regression instead of
around an SMA — when the price hugs its trend, StdErr is small.
Each update is O(period): the Σx and Σxx terms depend only on
period and are precomputed once, but the residuals are summed directly
over the window rather than reconstructed from rolling sums.
That is a deliberate trade. The residual sum of squares can be written as
Σ(y − ȳ)² − slope²·S_xx, which slides in constant time, and this indicator
did exactly that. But the two terms converge as the fit improves, so the
subtraction cancels precisely when the answer is smallest: on a line
carrying a wobble of 1e-4 around a price of 100 the constant-time form was
6.2e-08 out, and at a wobble of 1e-8 it was off by 215% — for the case the
indicator is most likely to be asked about, a market hugging its trend.
Summing the residuals costs one further pass over a window the indicator
already holds, and is what the sibling crate::StandardErrorBands and
crate::LinRegChannel have always done.
§Example
use wickra_core::{Indicator, StandardError};
let mut indicator = StandardError::new(14).unwrap();
let mut last = None;
for i in 0..40 {
last = indicator.update(100.0 + f64::from(i) + (f64::from(i) * 0.5).sin());
}
assert!(last.is_some());Implementations§
Trait Implementations§
Source§impl Clone for StandardError
impl Clone for StandardError
Source§impl Debug for StandardError
impl Debug for StandardError
Source§impl Indicator for StandardError
impl Indicator for StandardError
Source§fn update(&mut self, value: f64) -> Option<f64>
fn update(&mut self, value: 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.Source§fn is_ready(&self) -> bool
fn is_ready(&self) -> bool
Source§fn name(&self) -> &'static str
fn name(&self) -> &'static str
Source§fn batch_nan_into(&mut self, inputs: &[Self::Input], out: &mut [f64])
fn batch_nan_into(&mut self, inputs: &[Self::Input], out: &mut [f64])
Source§fn batch_fast_into(&mut self, inputs: &[Self::Input], out: &mut [f64])
fn batch_fast_into(&mut self, inputs: &[Self::Input], out: &mut [f64])
batch_nan_into, but
an indicator with a vectorised kernel may reassociate its arithmetic to
run it in SIMD lanes. Each value then agrees with the exact batch to within
the tolerance the indicator documents (a few units in the last place), not
bit for bit; warmup positions, NaN placement and the output length are
identical. The kernels are deterministic: the same input produces the same
bits on every platform, with or without SIMD hardware. Read moreAuto Trait Implementations§
impl Freeze for StandardError
impl RefUnwindSafe for StandardError
impl Send for StandardError
impl Sync for StandardError
impl Unpin for StandardError
impl UnsafeUnpin for StandardError
impl UnwindSafe for StandardError
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