ux_indicators/indicators/
max.rs

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