quantaxis_rs/indicators/
average_true_range.rs1use std::fmt;
2
3use crate::errors::*;
4use crate::indicators::{MovingAverage, TrueRange};
5use crate::{Close, High, Low, Next, Reset, Update};
6use std::f64::INFINITY;
7
8#[derive(Debug, Clone)]
29pub struct AverageTrueRange {
30 true_range: TrueRange,
31 ma: MovingAverage,
32 length: usize,
33 pub cached: Vec<f64>
34}
35
36impl AverageTrueRange {
37 pub fn new(length: u32) -> Result<Self> {
38 let indicator = Self {
39 true_range: TrueRange::new(),
40 ma: MovingAverage::new(length)?,
41 length: length as usize,
42 cached: vec![-INFINITY; length as usize]
43 };
44 Ok(indicator)
45 }
46}
47
48impl Next<f64> for AverageTrueRange {
49 type Output = f64;
50
51 fn next(&mut self, input: f64) -> Self::Output {
52 let res = self.ma.next(self.true_range.next(input));
53 self.cached.push(res);
54 self.cached.remove(0);
55 res
56 }
57}
58impl Update<f64> for AverageTrueRange {
59 type Output = f64;
60
61 fn update(&mut self, input: f64) -> Self::Output {
62 let res = self.ma.update(self.true_range.update(input));
63 let x = self.cached.last_mut().unwrap();
64 *x = res;
65 res
66 }
67}
68
69impl<'a, T: High + Low + Close> Next<&'a T> for AverageTrueRange {
70 type Output = f64;
71
72 fn next(&mut self, input: &'a T) -> Self::Output {
73 let res = self.ma.next(self.true_range.next(input));
74 self.cached.push(res);
75 self.cached.remove(0);
76 res
77 }
78}
79
80impl<'a, T: High + Low + Close> Update<&'a T> for AverageTrueRange {
81 type Output = f64;
82
83 fn update(&mut self, input: &'a T) -> Self::Output {
84 let res = self.ma.update(self.true_range.update(input));
85 let x = self.cached.last_mut().unwrap();
86 *x = res;
87 res
88 }
89}
90
91impl Reset for AverageTrueRange {
92 fn reset(&mut self) {
93 self.true_range.reset();
94 self.ma.reset();
95 }
96}
97
98impl Default for AverageTrueRange {
99 fn default() -> Self {
100 Self::new(14).unwrap()
101 }
102}
103
104impl fmt::Display for AverageTrueRange {
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106 write!(f, "ATR({})", self.ma.n)
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use crate::test_helper::*;
114 macro_rules! test_indicator {
115 ($i:tt) => {
116 #[test]
117 fn test_indicator() {
118 let bar = Bar::new();
119
120 let mut indicator = $i::default();
122
123 let first_output = indicator.next(12.3);
125
126 indicator.next(&bar);
128
129 indicator.reset();
131 assert_eq!(indicator.next(12.3), first_output);
132
133 format!("{}", indicator);
135 }
136 };
137 }
138 test_indicator!(AverageTrueRange);
139
140 #[test]
141 fn test_new() {
142 assert!(AverageTrueRange::new(0).is_err());
143 assert!(AverageTrueRange::new(1).is_ok());
144 }
145 #[test]
146 fn test_next() {
147 let mut atr = AverageTrueRange::new(3).unwrap();
148
149 let bar1 = Bar::new().high(10).low(7.5).close(9);
150 let bar2 = Bar::new().high(11).low(9).close(9.5);
151 let bar3 = Bar::new().high(9).low(5).close(8);
152
153 assert_eq!(atr.next(&bar1), 0f64);
154 assert_eq!(atr.next(&bar2), 0f64);
155 assert_eq!(atr.next(&bar3), 3f64);
156 }
157
158 #[test]
159 fn test_reset() {
160 let mut atr = AverageTrueRange::new(9).unwrap();
161
162 let bar1 = Bar::new().high(10).low(7.5).close(9);
163 let bar2 = Bar::new().high(11).low(9).close(9.5);
164
165 atr.next(&bar1);
166 atr.next(&bar2);
167
168 atr.reset();
169 let bar3 = Bar::new().high(60).low(15).close(51);
170 assert_eq!(atr.next(&bar3), 0.0);
171 }
172
173 #[test]
174 fn test_default() {
175 AverageTrueRange::default();
176 }
177
178 #[test]
179 fn test_display() {
180 let indicator = AverageTrueRange::new(8).unwrap();
181 assert_eq!(format!("{}", indicator), "ATR(8)");
182 }
183}