ux_indicators/indicators/
sd.rs1#![allow(dead_code)]
2
3use std::fmt;
4
5use crate::errors::*;
6use crate::{Close, Next, Reset};
7
8use crate::{Factory};
9use crate::indicators::SimpleMovingAverage;
10
11pub struct SdFactory {
12}
13
14impl SdFactory {
15 pub fn new() -> Self {
16 Self{}
17 }
18}
19
20impl Factory for SdFactory {
21 fn create() -> Box<dyn Next<f64, Output = Box<[f64]>>> {
22 Box::new(SimpleMovingAverage::default())
23 }
24}
25
26#[derive(Debug, Clone)]
61pub struct StandardDeviation {
62 n: u32,
63 index: usize,
64 count: u32,
65 m: f64,
66 m2: f64,
67 vec: Vec<f64>,
68}
69
70impl StandardDeviation {
71 pub fn new(n: u32) -> Result<Self> {
72 match n {
73 0 => Err(Error::from_kind(ErrorKind::InvalidParameter)),
74 _ => {
75 let std = StandardDeviation {
76 n,
77 index: 0,
78 count: 0,
79 m: 0.0,
80 m2: 0.0,
81 vec: vec![0.0; n as usize],
82 };
83 Ok(std)
84 }
85 }
86 }
87
88 pub(super) fn mean(&self) -> f64 {
89 self.m
90 }
91}
92
93impl Next<f64> for StandardDeviation {
94 type Output = f64;
95
96 fn next(&mut self, input: f64) -> Self::Output {
97 self.index = (self.index + 1) % (self.n as usize);
98
99 let old_val = self.vec[self.index];
100 self.vec[self.index] = input;
101
102 if self.count < self.n {
103 self.count += 1;
104 let delta = input - self.m;
105 self.m += delta / self.count as f64;
106 let delta2 = input - self.m;
107 self.m2 += delta * delta2;
108 } else {
109 let delta = input - old_val;
110 let old_m = self.m;
111 self.m += delta / self.n as f64;
112 let delta2 = input - self.m + old_val - old_m;
113 self.m2 += delta * delta2;
114 }
115
116 (self.m2 / self.count as f64).sqrt()
117 }
118}
119
120impl<'a, T: Close> Next<&'a T> for StandardDeviation {
121 type Output = f64;
122
123 fn next(&mut self, input: &'a T) -> Self::Output {
124 self.next(input.close())
125 }
126}
127
128impl Reset for StandardDeviation {
129 fn reset(&mut self) {
130 self.index = 0;
131 self.count = 0;
132 self.m = 0.0;
133 self.m2 = 0.0;
134 for i in 0..(self.n as usize) {
135 self.vec[i] = 0.0;
136 }
137 }
138}
139
140impl Default for StandardDeviation {
141 fn default() -> Self {
142 Self::new(9).unwrap()
143 }
144}
145
146impl fmt::Display for StandardDeviation {
147 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148 write!(f, "SD({})", self.n)
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155 use crate::test_helper::*;
156
157 #[test]
160 fn test_new() {
161 assert!(StandardDeviation::new(0).is_err());
162 assert!(StandardDeviation::new(1).is_ok());
163 }
164
165 #[test]
166 fn test_next() {
167 let mut sd = StandardDeviation::new(4).unwrap();
168 assert_eq!(sd.next(10.0), 0.0);
169 assert_eq!(sd.next(20.0), 5.0);
170 assert_eq!(round(sd.next(30.0)), 8.165);
171 assert_eq!(round(sd.next(20.0)), 7.071);
172 assert_eq!(round(sd.next(10.0)), 7.071);
173 assert_eq!(round(sd.next(100.0)), 35.355);
174 }
175
176 #[test]
177 fn test_next_with_bars() {
178 fn bar(close: f64) -> Bar {
179 Bar::new().close(close)
180 }
181
182 let mut sd = StandardDeviation::new(4).unwrap();
183 assert_eq!(sd.next(&bar(10.0)), 0.0);
184 assert_eq!(sd.next(&bar(20.0)), 5.0);
185 assert_eq!(round(sd.next(&bar(30.0))), 8.165);
186 assert_eq!(round(sd.next(&bar(20.0))), 7.071);
187 assert_eq!(round(sd.next(&bar(10.0))), 7.071);
188 assert_eq!(round(sd.next(&bar(100.0))), 35.355);
189 }
190
191 #[test]
192 fn test_next_same_values() {
193 let mut sd = StandardDeviation::new(3).unwrap();
194 assert_eq!(sd.next(4.2), 0.0);
195 assert_eq!(sd.next(4.2), 0.0);
196 assert_eq!(sd.next(4.2), 0.0);
197 assert_eq!(sd.next(4.2), 0.0);
198 }
199
200 #[test]
201 fn test_reset() {
202 let mut sd = StandardDeviation::new(4).unwrap();
203 assert_eq!(sd.next(10.0), 0.0);
204 assert_eq!(sd.next(20.0), 5.0);
205 assert_eq!(round(sd.next(30.0)), 8.165);
206
207 sd.reset();
208 assert_eq!(sd.next(20.0), 0.0);
209 }
210
211 #[test]
212 fn test_default() {
213 StandardDeviation::default();
214 }
215
216 #[test]
217 fn test_display() {
218 let sd = StandardDeviation::new(5).unwrap();
219 assert_eq!(format!("{}", sd), "SD(5)");
220 }
221}