pub struct KalmanHedgeRatio { /* private fields */ }Expand description
Dynamic hedge ratio between two series, estimated online with a Kalman filter.
Each update takes one (a, b) price pair and treats the linear relation
aₜ = αₜ + βₜ·bₜ + noise as a state-space model whose hidden state
[βₜ, αₜ] follows a random walk. The filter updates the state from every
observation, so the hedge ratio adapts continuously instead of being a
flat OLS slope over a fixed window:
state xₜ = [βₜ, αₜ], drifts as a random walk with covariance Vw·I
observe aₜ = [bₜ, 1]·xₜ + εₜ, Var(εₜ) = observation_var
Vw = delta / (1 − delta)delta controls how fast the hedge ratio is allowed to move: a larger
delta tracks regime changes faster but is noisier; a smaller delta is
smoother but slower. observation_var is the measurement-noise variance.
The reported spread (the filter’s forecast error) is the mean-reverting
signal a pairs trade fades — the Kalman analogue of the
crate::Cointegration residual, but with a hedge ratio that breathes.
The filter emits an estimate from the first update (warmup of one bar);
early estimates are diffuse and settle as observations accumulate. Each
update is O(1) over the fixed 2×2 covariance.
§Example
use wickra_core::{Indicator, KalmanHedgeRatio};
let mut k = KalmanHedgeRatio::new(1e-2, 1e-3).unwrap();
let mut last = None;
for t in 0..400 {
// `b` sweeps a wide range so the slope and intercept are identifiable.
let b = 100.0 + (f64::from(t) * 0.5).sin() * 95.0;
last = k.update((2.0 * b + 5.0, b)); // a = 2·b + 5
}
let out = last.unwrap();
assert!((out.hedge_ratio - 2.0).abs() < 0.05);
assert!(out.spread.abs() < 0.05);Implementations§
Source§impl KalmanHedgeRatio
impl KalmanHedgeRatio
Sourcepub fn new(delta: f64, observation_var: f64) -> Result<Self>
pub fn new(delta: f64, observation_var: f64) -> Result<Self>
Construct a new Kalman hedge-ratio filter.
delta is the state-drift ratio in (0, 1); observation_var is the
measurement-noise variance (> 0).
§Errors
Returns Error::InvalidParameter if delta is not in (0, 1) or if
observation_var is not strictly positive (both must also be finite).
Sourcepub const fn observation_var(&self) -> f64
pub const fn observation_var(&self) -> f64
Configured measurement-noise variance.
Trait Implementations§
Source§impl Clone for KalmanHedgeRatio
impl Clone for KalmanHedgeRatio
Source§fn clone(&self) -> KalmanHedgeRatio
fn clone(&self) -> KalmanHedgeRatio
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 KalmanHedgeRatio
impl Debug for KalmanHedgeRatio
Source§impl Indicator for KalmanHedgeRatio
impl Indicator for KalmanHedgeRatio
Source§type Input = (f64, f64)
type Input = (f64, f64)
f64 for a price, or Candle / Tick).Source§type Output = KalmanHedgeRatioOutput
type Output = KalmanHedgeRatioOutput
Source§fn update(&mut self, input: (f64, f64)) -> Option<KalmanHedgeRatioOutput>
fn update(&mut self, input: (f64, f64)) -> Option<KalmanHedgeRatioOutput>
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 KalmanHedgeRatio
impl RefUnwindSafe for KalmanHedgeRatio
impl Send for KalmanHedgeRatio
impl Sync for KalmanHedgeRatio
impl Unpin for KalmanHedgeRatio
impl UnsafeUnpin for KalmanHedgeRatio
impl UnwindSafe for KalmanHedgeRatio
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