pub struct EvenBetterSinewave { /* private fields */ }Expand description
Ehlers’ Even Better Sinewave (EBSW) — a self-normalising cycle oscillator
that swings cleanly in [−1, +1] regardless of price amplitude.
From John Ehlers’ Cycle Analytics for Traders (2013, ch. 12):
alpha1 = (1 − sin(2π/hp_period)) / cos(2π/hp_period)
HP_t = 0.5·(1 + alpha1)·(price_t − price_{t−1}) + alpha1·HP_{t−1} (one-pole highpass)
Filt = SuperSmoother(HP, ssf_length)
Wave = (Filt_t + Filt_{t−1} + Filt_{t−2}) / 3
Pwr = (Filt_t² + Filt_{t−1}² + Filt_{t−2}²) / 3
EBSW = Wave / sqrt(Pwr)The price is first highpass-filtered to remove the trend, then SuperSmoothed to
remove noise, leaving the dominant cycle. Dividing a 3-bar average of that
cycle by its RMS power normalises the amplitude, so the output reads like a
clean sine wave bounded in [−1, +1] whatever the instrument. Unlike the
classic SineWave (which derives in-phase/quadrature
components from the Hilbert transform and can whip in trends), the EBSW stays
well-behaved and is read directly: crossing up through 0/−0.9 is a buy
cue, crossing down through 0/+0.9 a sell cue.
The first value lands once three SuperSmoothed samples exist
(warmup_period == 3). Each update is O(1).
§Example
use wickra_core::{Indicator, EvenBetterSinewave};
let mut indicator = EvenBetterSinewave::new(40, 10).unwrap();
let mut last = None;
for i in 0..120 {
last = indicator.update(100.0 + (f64::from(i) * 0.3).sin() * 5.0);
}
assert!(last.is_some());Implementations§
Source§impl EvenBetterSinewave
impl EvenBetterSinewave
Trait Implementations§
Source§impl Clone for EvenBetterSinewave
impl Clone for EvenBetterSinewave
Source§fn clone(&self) -> EvenBetterSinewave
fn clone(&self) -> EvenBetterSinewave
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 EvenBetterSinewave
impl Debug for EvenBetterSinewave
Source§impl Indicator for EvenBetterSinewave
impl Indicator for EvenBetterSinewave
Source§fn update(&mut self, price: f64) -> Option<f64>
fn update(&mut self, price: 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 EvenBetterSinewave
impl RefUnwindSafe for EvenBetterSinewave
impl Send for EvenBetterSinewave
impl Sync for EvenBetterSinewave
impl Unpin for EvenBetterSinewave
impl UnsafeUnpin for EvenBetterSinewave
impl UnwindSafe for EvenBetterSinewave
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§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