wickra_core/indicators/
avg_price.rs1use crate::ohlcv::Candle;
4use crate::traits::Indicator;
5
6#[derive(Debug, Clone, Default)]
29pub struct AvgPrice {
30 has_emitted: bool,
31}
32
33impl AvgPrice {
34 pub const fn new() -> Self {
36 Self { has_emitted: false }
37 }
38}
39
40impl Indicator for AvgPrice {
41 type Input = Candle;
42 type Output = f64;
43
44 #[inline]
45 fn update(&mut self, candle: Candle) -> Option<f64> {
46 self.has_emitted = true;
47 Some(candle.avg_price())
48 }
49
50 fn reset(&mut self) {
51 self.has_emitted = false;
52 }
53
54 #[inline]
55 fn warmup_period(&self) -> usize {
56 1
57 }
58
59 #[inline]
60 fn is_ready(&self) -> bool {
61 self.has_emitted
62 }
63
64 #[inline]
65 fn name(&self) -> &'static str {
66 "AVGPRICE"
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use approx::assert_relative_eq;
74
75 #[test]
76 fn averages_the_four_prices() {
77 let candle = Candle::new(10.0, 14.0, 6.0, 12.0, 1.0, 0).unwrap();
79 let mut ap = AvgPrice::new();
80 assert!(!ap.is_ready());
81 assert_relative_eq!(ap.update(candle).unwrap(), 10.5, epsilon = 1e-12);
82 assert!(ap.is_ready());
83 }
84
85 #[test]
86 fn accessors_and_reset() {
87 let mut ap = AvgPrice::new();
88 assert_eq!(ap.name(), "AVGPRICE");
89 assert_eq!(ap.warmup_period(), 1);
90 let candle = Candle::new(10.0, 14.0, 6.0, 12.0, 1.0, 0).unwrap();
91 let _ = ap.update(candle);
92 assert!(ap.is_ready());
93 ap.reset();
94 assert!(!ap.is_ready());
95 }
96}