ux_indicators/indicators/
min.rs

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