quantaxis_rs/indicators/
true_range.rs1use std::fmt;
2
3use crate::helpers::max3;
4use crate::{Close, High, Low, Next, Reset, Update};
5
6
7#[derive(Debug, Clone)]
8pub struct TrueRange {
9
10
11 prev_closeque: Vec<f64>
12
13}
14
15impl TrueRange {
16 pub fn new() -> Self {
17 Self { prev_closeque:vec![] }
18 }
19}
20
21impl Default for TrueRange {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl fmt::Display for TrueRange {
28 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29 write!(f, "TRUE_RANGE()")
30 }
31}
32
33impl Next<f64> for TrueRange {
34 type Output = f64;
35
36 fn next(&mut self, input: f64) -> Self::Output {
37 if self.prev_closeque.len()<1{
38 self.prev_closeque.push(input);
39 0.0
40 }else {
41 let distance = match self.prev_closeque[self.prev_closeque.len() - 1] {
42 prev => (input - prev).abs(),
43 _ => 0.0
44 };
45
46 self.prev_closeque.push(input);
47 distance
48 }
49
50
51 }
52}
53impl Update<f64> for TrueRange {
54 type Output = f64;
55
56 fn update(&mut self, input: f64) -> Self::Output {
57
58 if self.prev_closeque.len()<2{
59 let u = self.prev_closeque.last_mut().unwrap();
60 *u = input;
61 0.0
62 }else{
63 let distance = match self.prev_closeque[self.prev_closeque.len() -2]{
64 prev => (input - prev).abs(),
65 _ => 0.0
66 };
67
68 let u = self.prev_closeque.last_mut().unwrap();
69 *u = input;
70 distance
72 }
73
74 }
75}
76
77impl<'a, T: High + Low + Close> Next<&'a T> for TrueRange {
78 type Output = f64;
79
80 fn next(&mut self, bar: &'a T) -> Self::Output {
81 if self.prev_closeque.len()<1{
82 self.prev_closeque.push(bar.close());
83 bar.high()- bar.low()
84 }else{
85 let max_dist = match self.prev_closeque[self.prev_closeque.len() - 1] {
86 prev_close => {
87 let dist1 = bar.high() - bar.low();
88 let dist2 = (bar.high() - prev_close).abs();
89 let dist3 = (bar.low() - prev_close).abs();
90 max3(dist1, dist2, dist3)
91 }
92 _ => bar.high() - bar.low(),
93 };
94 self.prev_closeque.push(bar.close());
95 max_dist
96 }
97 }
98}
99impl<'a, T: High + Low + Close> Update<&'a T> for TrueRange {
100 type Output = f64;
101
102 fn update(&mut self, bar: &'a T) -> Self::Output {
103 if self.prev_closeque.len()<2{
104 let u = self.prev_closeque.last_mut().unwrap();
105 *u = bar.close();
106 bar.high() - bar.low()
107 }else{
108 let max_dist = match self.prev_closeque[self.prev_closeque.len() -2] {
109 prev_close => {
110 let dist1 = bar.high() - bar.low();
111 let dist2 = (bar.high() - prev_close).abs();
112 let dist3 = (bar.low() - prev_close).abs();
113 max3(dist1, dist2, dist3)
114 }
115 _ => bar.high() - bar.low(),
116 };
117 let u = self.prev_closeque.last_mut().unwrap();
118 *u = bar.close();
119 max_dist
120 }
121
122 }
123}
124
125impl Reset for TrueRange {
126 fn reset(&mut self) {
127 self.prev_closeque = vec![];
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use crate::test_helper::*;
135 macro_rules! test_indicator {
136 ($i:tt) => {
137 #[test]
138 fn test_indicator() {
139 let bar = Bar::new();
140
141 let mut indicator = $i::default();
143
144 let first_output = indicator.next(12.3);
146
147 indicator.next(&bar);
149
150 indicator.reset();
152 assert_eq!(indicator.next(12.3), first_output);
153
154 format!("{}", indicator);
156 }
157 };
158 }
159 test_indicator!(TrueRange);
160
161 #[test]
162 fn test_next_f64() {
163 let mut tr = TrueRange::new();
164 assert_eq!(round(tr.next(2.5)), 0.0);
165 assert_eq!(round(tr.next(3.6)), 1.1);
166 assert_eq!(round(tr.next(3.3)), 0.3);
167 }
168
169
170
171 #[test]
172 fn test_update_f64() {
173 let mut tr = TrueRange::new();
174 assert_eq!(round(tr.next(2.5)), 0.0);
175
176 assert_eq!(round(tr.update(3.3)), 0.0);
177
178
179 let mut tr = TrueRange::new();
180 assert_eq!(round(tr.next(2.5)), 0.0);
181 println!("{:#?}", tr);
182 assert_eq!(round(tr.update(3.3)), 0.0);
183 println!("{:#?}", tr);
184 assert_eq!(round(tr.next(2.5)), 0.8);
186 println!("{:#?}", tr);
187 assert_eq!(round(tr.update(3.6)), 0.3);
188 println!("{:#?}", tr);
189
190 }
191
192 #[test]
193 fn test_next_bar() {
194 let mut tr = TrueRange::new();
195
196 let bar1 = Bar::new().high(10).low(7.5).close(9);
197 let bar2 = Bar::new().high(11).low(9).close(9.5);
198 let bar3 = Bar::new().high(9).low(5).close(8);
199
200 assert_eq!(tr.next(&bar1), 2.5);
201 assert_eq!(tr.next(&bar2), 2.0);
202 assert_eq!(tr.next(&bar3), 4.5);
203 }
204
205 #[test]
206 fn test_reset() {
207 let mut tr = TrueRange::new();
208
209 let bar1 = Bar::new().high(10).low(7.5).close(9);
210 let bar2 = Bar::new().high(11).low(9).close(9.5);
211
212 tr.next(&bar1);
213 tr.next(&bar2);
214
215 tr.reset();
216 let bar3 = Bar::new().high(60).low(15).close(51);
217 assert_eq!(tr.next(&bar3), 45.0);
218 }
219
220 #[test]
221 fn test_default() {
222 TrueRange::default();
223 }
224
225 #[test]
226 fn test_display() {
227 let indicator = TrueRange::new();
228 assert_eq!(format!("{}", indicator), "TRUE_RANGE()");
229 }
230}