Skip to main content

quantwave_core/indicators/
hilbert_transform.rs

1use crate::utils::RingBuffer as VecDeque;
2
3/// Hilbert Transform 7-tap FIR Filter
4///
5/// Based on John Ehlers' "Rocket Science for Traders".
6/// This filter provides a 90-degree phase shift for the input signal.
7#[derive(Debug, Clone)]
8pub struct HilbertFIR {
9    window: VecDeque<f64>,
10}
11
12impl HilbertFIR {
13    pub fn new() -> Self {
14        Self {
15            window: VecDeque::from(vec![0.0; 7]),
16        }
17    }
18
19    pub fn next(&mut self, input: f64, period: f64) -> f64 {
20        self.window.pop_back();
21        self.window.push_front(input);
22
23        // FIR coefficients for 90-degree phase shift
24        (0.0962 * self.window[0] + 0.5769 * self.window[2]
25            - 0.5769 * self.window[4]
26            - 0.0962 * self.window[6])
27            * (0.075 * period + 0.54)
28    }
29}
30
31impl Default for HilbertFIR {
32    fn default() -> Self {
33        Self::new()
34    }
35}
36
37/// A simpler 4-tap WMA often used in Ehlers' smoothing
38#[derive(Debug, Clone)]
39pub struct EhlersWma4 {
40    window: VecDeque<f64>,
41}
42
43impl EhlersWma4 {
44    pub fn new() -> Self {
45        Self {
46            window: VecDeque::from(vec![0.0; 4]),
47        }
48    }
49
50    pub fn next(&mut self, input: f64) -> f64 {
51        self.window.pop_back();
52        self.window.push_front(input);
53
54        (4.0 * self.window[0] + 3.0 * self.window[1] + 2.0 * self.window[2] + self.window[3]) / 10.0
55    }
56}
57
58impl Default for EhlersWma4 {
59    fn default() -> Self {
60        Self::new()
61    }
62}