ux_indicators/indicators/
max.rs1#![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#[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]
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}