Skip to main content

quantwave_core/indicators/
cycle.rs

1talib_1_in_1_out!(HT_DCPERIOD, talib_rs::cycle::ht_dcperiod);
2impl Default for HT_DCPERIOD {
3    fn default() -> Self {
4        Self::new()
5    }
6}
7talib_1_in_2_out!(HT_PHASOR, talib_rs::cycle::ht_phasor);
8impl Default for HT_PHASOR {
9    fn default() -> Self {
10        Self::new()
11    }
12}
13talib_1_in_1_out!(HT_DCPHASE, talib_rs::cycle::ht_dcphase);
14impl Default for HT_DCPHASE {
15    fn default() -> Self {
16        Self::new()
17    }
18}
19talib_1_in_2_out!(HT_SINE, talib_rs::cycle::ht_sine);
20impl Default for HT_SINE {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25talib_1_in_1_out_i32!(HT_TRENDMODE, talib_rs::cycle::ht_trendmode);
26impl Default for HT_TRENDMODE {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35    use crate::traits::Next;
36    use proptest::prelude::*;
37
38    proptest! {
39        #[test]
40        fn test_ht_dcperiod_parity(input in prop::collection::vec(0.1..100.0, 1..100)) {
41            let mut ht = HT_DCPERIOD::new();
42            let streaming_results: Vec<f64> = input.iter().map(|&x| ht.next(x)).collect();
43            let batch_results = talib_rs::cycle::ht_dcperiod(&input).unwrap_or_else(|_| vec![f64::NAN; input.len()]);
44
45            for (s, b) in streaming_results.iter().zip(batch_results.iter()) {
46                if s.is_nan() {
47                    assert!(b.is_nan());
48                } else {
49                    approx::assert_relative_eq!(s, b, epsilon = 1e-6);
50                }
51            }
52        }
53
54        #[test]
55        fn test_ht_phasor_parity(input in prop::collection::vec(0.1..100.0, 1..100)) {
56            let mut ht = HT_PHASOR::new();
57            let streaming_results: Vec<(f64, f64)> = input.iter().map(|&x| ht.next(x)).collect();
58            let (b_inphase, b_quadrature) = talib_rs::cycle::ht_phasor(&input).unwrap_or_else(|_| {
59                (vec![f64::NAN; input.len()], vec![f64::NAN; input.len()])
60            });
61
62            for (i, (s_in, s_quad)) in streaming_results.into_iter().enumerate() {
63                if s_in.is_nan() {
64                    assert!(b_inphase[i].is_nan());
65                } else {
66                    approx::assert_relative_eq!(s_in, b_inphase[i], epsilon = 1e-6);
67                }
68                if s_quad.is_nan() {
69                    assert!(b_quadrature[i].is_nan());
70                } else {
71                    approx::assert_relative_eq!(s_quad, b_quadrature[i], epsilon = 1e-6);
72                }
73            }
74        }
75
76        #[test]
77        fn test_ht_trendmode_parity(input in prop::collection::vec(0.1..100.0, 1..100)) {
78            let mut ht = HT_TRENDMODE::new();
79            let streaming_results: Vec<f64> = input.iter().map(|&x| ht.next(x)).collect();
80            let batch_results = talib_rs::cycle::ht_trendmode(&input).unwrap_or_else(|_| vec![0; input.len()]);
81
82            for (s, b) in streaming_results.iter().zip(batch_results.iter()) {
83                assert_eq!(*s as i32, *b);
84            }
85        }
86    }
87}