pub struct BetaNeutralSpread { /* private fields */ }Expand description
The beta-neutral spread between two assets — the residual of a rolling
ordinary-least-squares regression of a on b.
Each update takes one (a, b) price pair. Over the trailing window of
period pairs the indicator fits the hedge ratio β (and intercept α) by
OLS and reports the current residual:
β = cov(a, b) / var(b) α = ā − β · b̄
spread = a_now − (α + β · b_now)Subtracting β · b removes a’s exposure to b, so the spread is market-
(beta-)neutral: it is what is left after the common factor is hedged out.
Positive means a is rich relative to its hedge, negative means cheap — the
raw signal a pairs trade fades. Where crate::PairSpreadZScore standardises
this residual into a z-score and crate::Cointegration bundles it with an
ADF test, this indicator returns the residual itself, in price units.
If b is flat over the window (var(b) = 0) there is no defined slope; the
indicator falls back to β = 0, so the spread becomes a_now − ā.
Each update is O(1): four running sums (Σa, Σb, Σb², Σab) are
maintained as the window slides.
§Example
use wickra_core::{BetaNeutralSpread, Indicator};
let mut s = BetaNeutralSpread::new(20).unwrap();
let mut last = None;
for t in 0..40 {
let b = 100.0 + f64::from(t);
// a = 2·b + 5 exactly ⇒ the regression explains a fully ⇒ spread ≈ 0.
last = s.update((2.0 * b + 5.0, b));
}
assert!(last.unwrap().abs() < 1e-6);Implementations§
Trait Implementations§
Source§impl Clone for BetaNeutralSpread
impl Clone for BetaNeutralSpread
Source§fn clone(&self) -> BetaNeutralSpread
fn clone(&self) -> BetaNeutralSpread
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 BetaNeutralSpread
impl Debug for BetaNeutralSpread
Source§impl Indicator for BetaNeutralSpread
impl Indicator for BetaNeutralSpread
Source§type Input = (f64, f64)
type Input = (f64, f64)
f64 for a price, or Candle / Tick).Source§fn update(&mut self, input: (f64, f64)) -> Option<f64>
fn update(&mut self, input: (f64, f64)) -> Option<f64>
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 BetaNeutralSpread
impl RefUnwindSafe for BetaNeutralSpread
impl Send for BetaNeutralSpread
impl Sync for BetaNeutralSpread
impl Unpin for BetaNeutralSpread
impl UnsafeUnpin for BetaNeutralSpread
impl UnwindSafe for BetaNeutralSpread
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