quantaxis_rs/indicators/
llv.rs1use std::f64::INFINITY;
2use std::fmt;
3
4use crate::{Low, Next, Reset, Update};
5use crate::errors::*;
6
7#[derive(Debug, Clone)]
27pub struct LLV {
28 n: usize,
29 vec: Vec<f64>,
30 min_index: usize,
31 cur_index: usize,
32 pub cached: Vec<f64>
33}
34
35impl LLV {
36 pub fn new(n: u32) -> Result<Self> {
37 let n = n as usize;
38
39 if n <= 0 {
40 return Err(Error::from_kind(ErrorKind::InvalidParameter));
41 }
42
43 let indicator = Self {
44 n: n,
45 vec: vec![INFINITY; n],
46 min_index: 0,
47 cur_index: 0,
48 cached: vec![INFINITY; n],
49 };
50
51 Ok(indicator)
52 }
53 pub fn new_init(n: u32, vec: Vec<f64>) -> Result<Self> {
54 let n = n as usize;
55
56 if n <= 0 {
57 return Err(Error::from_kind(ErrorKind::InvalidParameter));
58 }
59
60 let mut indicator = Self {
61 n: n,
62 vec: vec![INFINITY; n],
63 min_index: 0,
64 cur_index: 0,
65 cached: vec![INFINITY; n],
66 };
67 for data in vec{
68 indicator.next(data as f64);
69 }
70 Ok(indicator)
71 }
72
73 fn find_min_index(&self) -> usize {
74 let mut min = ::std::f64::INFINITY;
75 let mut index: usize = 0;
76
77 for (i, &val) in self.vec.iter().enumerate() {
78 if val < min {
79 min = val;
80 index = i;
81 }
82 }
83
84 index
85 }
86}
87
88impl Next<f64> for LLV {
89 type Output = f64;
90
91 fn next(&mut self, input: f64) -> Self::Output {
92 self.cur_index = (self.cur_index + 1) % (self.n as usize);
93 self.vec[self.cur_index] = input;
94
95 if input < self.vec[self.min_index] {
96 self.min_index = self.cur_index;
97 } else if self.min_index == self.cur_index {
98 self.min_index = self.find_min_index();
99 }
100 self.cached.push(self.vec[self.min_index]);
101 self.cached.remove(0);
102 self.vec[self.min_index]
103 }
104}
105
106
107impl Update<f64> for LLV {
108 type Output = f64;
109
110 fn update(&mut self, input: f64) -> Self::Output {
111 self.vec[self.cur_index] = input;
112
113 if input < self.vec[self.min_index] {
114 self.min_index = self.cur_index;
115 } else if self.min_index == self.cur_index {
116 self.min_index = self.find_min_index();
117 }
118 self.cached.remove(self.n - 1);
119 self.cached.push(self.vec[self.min_index]);
120
121 self.vec[self.min_index]
122 }
123}
124
125impl<'a, T: Low> Next<&'a T> for LLV {
126 type Output = f64;
127
128 fn next(&mut self, input: &'a T) -> Self::Output {
129 self.next(input.low())
130 }
131}
132
133impl Reset for LLV {
134 fn reset(&mut self) {
135 for i in 0..self.n {
136 self.vec[i] = INFINITY;
137 }
138 }
139}
140
141impl Default for LLV {
142 fn default() -> Self {
143 Self::new(14).unwrap()
144 }
145}
146
147impl fmt::Display for LLV {
148 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
149 write!(f, "MIN({})", self.n)
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use crate::test_helper::*;
156
157 use super::*;
158
159 macro_rules! test_indicator {
160 ($i:tt) => {
161 #[test]
162 fn test_indicator() {
163 let bar = Bar::new();
164
165 let mut indicator = $i::default();
167
168 let first_output = indicator.next(12.3);
170
171 indicator.next(&bar);
173
174 indicator.reset();
176 assert_eq!(indicator.next(12.3), first_output);
177
178 format!("{}", indicator);
180 }
181 };
182 }
183 test_indicator!(LLV);
184
185 #[test]
186 fn test_new() {
187 assert!(LLV::new(0).is_err());
188 assert!(LLV::new(1).is_ok());
189 }
190
191 #[test]
192 fn test_next() {
193 let mut min = LLV::new(3).unwrap();
194
195 assert_eq!(min.next(4.0), 4.0);
196 assert_eq!(min.next(1.2), 1.2);
197 assert_eq!(min.next(5.0), 1.2);
198 assert_eq!(min.next(3.0), 1.2);
199 assert_eq!(min.next(4.0), 3.0);
200 assert_eq!(min.next(6.0), 3.0);
201 assert_eq!(min.next(7.0), 4.0);
202 assert_eq!(min.next(8.0), 6.0);
203 assert_eq!(min.next(-9.0), -9.0);
204 assert_eq!(min.next(0.0), -9.0);
205 }
206
207 #[test]
208 fn test_update() {
209 let mut min = LLV::new(3).unwrap();
210
211 assert_eq!(min.next(4.0), 4.0);
212 assert_eq!(min.next(1.2), 1.2);
213 assert_eq!(min.next(5.0), 1.2);
214 assert_eq!(min.next(3.0), 1.2);
215 assert_eq!(min.next(2.0), 2.0);
216 assert_eq!(min.update(2.5), 2.5);
217 assert_eq!(min.next(2.2), 2.2);
218 }
219
220
221 #[test]
222 fn test_next_with_bars() {
223 fn bar(low: f64) -> Bar {
224 Bar::new().low(low)
225 }
226
227 let mut LLV_Indicator = LLV::new(3).unwrap();
228 println!("{:#?}", LLV_Indicator);
229 assert_eq!(LLV_Indicator.next(&bar(4.0)), 4.0);
230 assert_eq!(LLV_Indicator.next(&bar(4.0)), 4.0);
231 println!("{:#?}", LLV_Indicator);
232 assert_eq!(LLV_Indicator.next(&bar(1.2)), 1.2);
233 assert_eq!(LLV_Indicator.next(&bar(5.0)), 1.2);
234 println!("{:#?}", LLV_Indicator);
235 }
236
237 #[test]
238 fn test_reset() {
239 let mut min = LLV::new(10).unwrap();
240
241 assert_eq!(min.next(5.0), 5.0);
242 assert_eq!(min.next(7.0), 5.0);
243
244 min.reset();
245 assert_eq!(min.next(8.0), 8.0);
246 }
247
248 #[test]
249 fn test_newx() {
250 let mut LLV_Indicator = LLV::new_init(2, vec![3.0,4.0,3.0]).unwrap();
251 println!("{:#?}", LLV_Indicator);
252 assert_eq!(LLV_Indicator.next(5.0), 3.0);
253 println!("{:#?}", LLV_Indicator);
254 assert_eq!(LLV_Indicator.next(7.0), 5.0);
255 println!("{:#?}", LLV_Indicator);
256 LLV_Indicator.reset();
257 assert_eq!(LLV_Indicator.next(8.0), 8.0);
258 }
259
260 #[test]
261 fn test_new_notenough() {
262 let mut LLV_Indicator = LLV::new_init(4, vec![4.0,6.0,3.0]).unwrap();
263 println!("{:#?}", LLV_Indicator);
264 assert_eq!(LLV_Indicator.next(5.0), 3.0);
265 println!("{:#?}", LLV_Indicator);
266 assert_eq!(LLV_Indicator.next(2.0), 2.0);
267 println!("{:#?}", LLV_Indicator);
268 LLV_Indicator.reset();
269 assert_eq!(LLV_Indicator.next(8.0), 8.0);
270 }
271 #[test]
272 fn test_default() {
273 LLV::default();
274 }
275
276 #[test]
277 fn test_display() {
278 let indicator = LLV::new(10).unwrap();
279 println!("{}", indicator);
280 assert_eq!(format!("{}", indicator), "MIN(10)");
281 }
282}