ux_indicators/indicators/
atr.rs1#![allow(dead_code)]
2
3use std::fmt;
4
5use crate::errors::*;
6use crate::indicators::{ExponentialMovingAverage, TrueRange};
7use crate::{Close, High, Low, Next, Reset};
8
9use crate::{Factory};
10use crate::indicators::SimpleMovingAverage;
11
12pub struct AtrFactory {
13}
14
15impl AtrFactory {
16 pub fn new() -> Self {
17 Self{}
18 }
19}
20
21impl Factory for AtrFactory {
22 fn create() -> Box<dyn Next<f64, Output = Box<[f64]>>> {
23 Box::new(SimpleMovingAverage::default())
24 }
25}
26
27
28#[derive(Debug, Clone)]
79pub struct AverageTrueRange {
80 true_range: TrueRange,
81 ema: ExponentialMovingAverage,
82}
83
84impl AverageTrueRange {
85 pub fn new(length: u32) -> Result<Self> {
86 let indicator = Self {
87 true_range: TrueRange::new(),
88 ema: ExponentialMovingAverage::new(length)?,
89 };
90 Ok(indicator)
91 }
92}
93
94impl Next<f64> for AverageTrueRange {
95 type Output = f64;
96
97 fn next(&mut self, input: f64) -> Self::Output {
98 self.ema.next(self.true_range.next(input))
99 }
100}
101
102impl<'a, T: High + Low + Close> Next<&'a T> for AverageTrueRange {
103 type Output = f64;
104
105 fn next(&mut self, input: &'a T) -> Self::Output {
106 self.ema.next(self.true_range.next(input))
107 }
108}
109
110impl Reset for AverageTrueRange {
111 fn reset(&mut self) {
112 self.true_range.reset();
113 self.ema.reset();
114 }
115}
116
117impl Default for AverageTrueRange {
118 fn default() -> Self {
119 Self::new(14).unwrap()
120 }
121}
122
123impl fmt::Display for AverageTrueRange {
124 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
125 write!(f, "ATR({})", self.ema.length())
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::test_helper::*;
133
134 #[test]
137 fn test_new() {
138 assert!(AverageTrueRange::new(0).is_err());
139 assert!(AverageTrueRange::new(1).is_ok());
140 }
141 #[test]
142 fn test_next() {
143 let mut atr = AverageTrueRange::new(3).unwrap();
144
145 let bar1 = Bar::new().high(10).low(7.5).close(9);
146 let bar2 = Bar::new().high(11).low(9).close(9.5);
147 let bar3 = Bar::new().high(9).low(5).close(8);
148
149 assert_eq!(atr.next(&bar1), 2.5);
150 assert_eq!(atr.next(&bar2), 2.25);
151 assert_eq!(atr.next(&bar3), 3.375);
152 }
153
154 #[test]
155 fn test_reset() {
156 let mut atr = AverageTrueRange::new(9).unwrap();
157
158 let bar1 = Bar::new().high(10).low(7.5).close(9);
159 let bar2 = Bar::new().high(11).low(9).close(9.5);
160
161 atr.next(&bar1);
162 atr.next(&bar2);
163
164 atr.reset();
165 let bar3 = Bar::new().high(60).low(15).close(51);
166 assert_eq!(atr.next(&bar3), 45.0);
167 }
168
169 #[test]
170 fn test_default() {
171 AverageTrueRange::default();
172 }
173
174 #[test]
175 fn test_display() {
176 let indicator = AverageTrueRange::new(8).unwrap();
177 assert_eq!(format!("{}", indicator), "ATR(8)");
178 }
179}