quantaxis_rs/indicators/
minimum.rs1use std::f64::INFINITY;
2use std::fmt;
3
4use crate::errors::*;
5use crate::{Low, Next, Reset};
6
7#[derive(Debug, Clone)]
26pub struct Minimum {
27 n: usize,
28 vec: Vec<f64>,
29 min_index: usize,
30 cur_index: usize,
31}
32
33impl Minimum {
34 pub fn new(n: u32) -> Result<Self> {
35 let n = n as usize;
36
37 if n <= 0 {
38 return Err(Error::from_kind(ErrorKind::InvalidParameter));
39 }
40
41 let indicator = Self {
42 n: n,
43 vec: vec![INFINITY; n],
44 min_index: 0,
45 cur_index: 0,
46 };
47
48 Ok(indicator)
49 }
50
51 fn find_min_index(&self) -> usize {
52 let mut min = ::std::f64::INFINITY;
53 let mut index: usize = 0;
54
55 for (i, &val) in self.vec.iter().enumerate() {
56 if val < min {
57 min = val;
58 index = i;
59 }
60 }
61
62 index
63 }
64}
65
66impl Next<f64> for Minimum {
67 type Output = f64;
68
69 fn next(&mut self, input: f64) -> Self::Output {
70 self.cur_index = (self.cur_index + 1) % (self.n as usize);
71 self.vec[self.cur_index] = input;
72
73 if input < self.vec[self.min_index] {
74 self.min_index = self.cur_index;
75 } else if self.min_index == self.cur_index {
76 self.min_index = self.find_min_index();
77 }
78
79 self.vec[self.min_index]
80 }
81}
82
83impl<'a, T: Low> Next<&'a T> for Minimum {
84 type Output = f64;
85
86 fn next(&mut self, input: &'a T) -> Self::Output {
87 self.next(input.low())
88 }
89}
90
91impl Reset for Minimum {
92 fn reset(&mut self) {
93 for i in 0..self.n {
94 self.vec[i] = INFINITY;
95 }
96 }
97}
98
99impl Default for Minimum {
100 fn default() -> Self {
101 Self::new(14).unwrap()
102 }
103}
104
105impl fmt::Display for Minimum {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 write!(f, "MIN({})", self.n)
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114 use crate::test_helper::*;
115 macro_rules! test_indicator {
116 ($i:tt) => {
117 #[test]
118 fn test_indicator() {
119 let bar = Bar::new();
120
121 let mut indicator = $i::default();
123
124 let first_output = indicator.next(12.3);
126
127 indicator.next(&bar);
129
130 indicator.reset();
132 assert_eq!(indicator.next(12.3), first_output);
133
134 format!("{}", indicator);
136 }
137 };
138 }
139 test_indicator!(Minimum);
140
141 #[test]
142 fn test_new() {
143 assert!(Minimum::new(0).is_err());
144 assert!(Minimum::new(1).is_ok());
145 }
146
147 #[test]
148 fn test_next() {
149 let mut min = Minimum::new(3).unwrap();
150
151 assert_eq!(min.next(4.0), 4.0);
152 assert_eq!(min.next(1.2), 1.2);
153 assert_eq!(min.next(5.0), 1.2);
154 assert_eq!(min.next(3.0), 1.2);
155 assert_eq!(min.next(4.0), 3.0);
156 assert_eq!(min.next(6.0), 3.0);
157 assert_eq!(min.next(7.0), 4.0);
158 assert_eq!(min.next(8.0), 6.0);
159 assert_eq!(min.next(-9.0), -9.0);
160 assert_eq!(min.next(0.0), -9.0);
161 }
162
163 #[test]
164 fn test_next_with_bars() {
165 fn bar(low: f64) -> Bar {
166 Bar::new().low(low)
167 }
168
169 let mut min = Minimum::new(3).unwrap();
170
171 assert_eq!(min.next(&bar(4.0)), 4.0);
172 assert_eq!(min.next(&bar(4.0)), 4.0);
173 assert_eq!(min.next(&bar(1.2)), 1.2);
174 assert_eq!(min.next(&bar(5.0)), 1.2);
175 }
176
177 #[test]
178 fn test_reset() {
179 let mut min = Minimum::new(10).unwrap();
180
181 assert_eq!(min.next(5.0), 5.0);
182 assert_eq!(min.next(7.0), 5.0);
183
184 min.reset();
185 assert_eq!(min.next(8.0), 8.0);
186 }
187
188 #[test]
189 fn test_default() {
190 Minimum::default();
191 }
192
193 #[test]
194 fn test_display() {
195 let indicator = Minimum::new(10).unwrap();
196 assert_eq!(format!("{}", indicator), "MIN(10)");
197 }
198}