Skip to main content

finance_query/backtesting/refs/
power.rs

1use crate::backtesting::strategy::StrategyContext;
2use crate::indicators::Indicator;
3
4use super::IndicatorRef;
5
6/// Bull Power reference.
7#[derive(Debug, Clone)]
8pub struct BullPowerRef {
9    pub period: usize,
10    key: String,
11}
12
13/// Create a Bull Power reference.
14#[inline]
15pub fn bull_power(period: usize) -> BullPowerRef {
16    BullPowerRef {
17        period,
18        key: format!("bull_power_{period}"),
19    }
20}
21
22impl IndicatorRef for BullPowerRef {
23    fn key(&self) -> &str {
24        &self.key
25    }
26
27    fn required_indicators(&self) -> Vec<(String, Indicator)> {
28        vec![(self.key.clone(), Indicator::BullBearPower(self.period))]
29    }
30
31    fn value(&self, ctx: &StrategyContext) -> Option<f64> {
32        ctx.indicator(self.key())
33    }
34
35    fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
36        ctx.indicator_prev(self.key())
37    }
38}
39
40/// Bear Power reference.
41#[derive(Debug, Clone)]
42pub struct BearPowerRef {
43    pub period: usize,
44    key: String,
45}
46
47/// Create a Bear Power reference.
48#[inline]
49pub fn bear_power(period: usize) -> BearPowerRef {
50    BearPowerRef {
51        period,
52        key: format!("bear_power_{period}"),
53    }
54}
55
56impl IndicatorRef for BearPowerRef {
57    fn key(&self) -> &str {
58        &self.key
59    }
60
61    fn required_indicators(&self) -> Vec<(String, Indicator)> {
62        vec![(self.key.clone(), Indicator::BullBearPower(self.period))]
63    }
64
65    fn value(&self, ctx: &StrategyContext) -> Option<f64> {
66        ctx.indicator(self.key())
67    }
68
69    fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
70        ctx.indicator_prev(self.key())
71    }
72}
73
74/// Elder Ray Bull Power reference.
75#[derive(Debug, Clone)]
76pub struct ElderBullPowerRef {
77    pub period: usize,
78    key: String,
79}
80
81/// Create an Elder Ray Bull Power reference.
82#[inline]
83pub fn elder_bull_power(period: usize) -> ElderBullPowerRef {
84    ElderBullPowerRef {
85        period,
86        key: format!("elder_bull_{period}"),
87    }
88}
89
90impl IndicatorRef for ElderBullPowerRef {
91    fn key(&self) -> &str {
92        &self.key
93    }
94
95    fn required_indicators(&self) -> Vec<(String, Indicator)> {
96        vec![(self.key.clone(), Indicator::ElderRay(self.period))]
97    }
98
99    fn value(&self, ctx: &StrategyContext) -> Option<f64> {
100        ctx.indicator(self.key())
101    }
102
103    fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
104        ctx.indicator_prev(self.key())
105    }
106}
107
108/// Elder Ray Bear Power reference.
109#[derive(Debug, Clone)]
110pub struct ElderBearPowerRef {
111    pub period: usize,
112    key: String,
113}
114
115/// Create an Elder Ray Bear Power reference.
116#[inline]
117pub fn elder_bear_power(period: usize) -> ElderBearPowerRef {
118    ElderBearPowerRef {
119        period,
120        key: format!("elder_bear_{period}"),
121    }
122}
123
124impl IndicatorRef for ElderBearPowerRef {
125    fn key(&self) -> &str {
126        &self.key
127    }
128
129    fn required_indicators(&self) -> Vec<(String, Indicator)> {
130        vec![(self.key.clone(), Indicator::ElderRay(self.period))]
131    }
132
133    fn value(&self, ctx: &StrategyContext) -> Option<f64> {
134        ctx.indicator(self.key())
135    }
136
137    fn prev_value(&self, ctx: &StrategyContext) -> Option<f64> {
138        ctx.indicator_prev(self.key())
139    }
140}
141
142#[cfg(test)]
143mod tests {
144    use super::*;
145
146    #[test]
147    fn test_power_keys() {
148        assert_eq!(bull_power(13).key(), "bull_power_13");
149        assert_eq!(bear_power(13).key(), "bear_power_13");
150        assert_eq!(elder_bull_power(13).key(), "elder_bull_13");
151        assert_eq!(elder_bear_power(13).key(), "elder_bear_13");
152    }
153}