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 fn update(&mut self, candle: Candle) -> Option<f64> {
45 self.has_emitted = true;
46 Some(candle.avg_price())
47 }
48
49 fn reset(&mut self) {
50 self.has_emitted = false;
51 }
52
53 fn warmup_period(&self) -> usize {
54 1
55 }
56
57 fn is_ready(&self) -> bool {
58 self.has_emitted
59 }
60
61 fn name(&self) -> &'static str {
62 "AVGPRICE"
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use approx::assert_relative_eq;
70
71 #[test]
72 fn averages_the_four_prices() {
73 let candle = Candle::new(10.0, 14.0, 6.0, 12.0, 1.0, 0).unwrap();
75 let mut ap = AvgPrice::new();
76 assert!(!ap.is_ready());
77 assert_relative_eq!(ap.update(candle).unwrap(), 10.5, epsilon = 1e-12);
78 assert!(ap.is_ready());
79 }
80
81 #[test]
82 fn accessors_and_reset() {
83 let mut ap = AvgPrice::new();
84 assert_eq!(ap.name(), "AVGPRICE");
85 assert_eq!(ap.warmup_period(), 1);
86 let candle = Candle::new(10.0, 14.0, 6.0, 12.0, 1.0, 0).unwrap();
87 let _ = ap.update(candle);
88 assert!(ap.is_ready());
89 ap.reset();
90 assert!(!ap.is_ready());
91 }
92}