ta/indicators/
true_range.rs1use std::fmt;
2
3use crate::helpers::max3;
4use crate::{Close, High, Low, Next, Reset};
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
53#[derive(Debug, Clone)]
54pub struct TrueRange {
55 prev_close: Option<f64>,
56}
57
58impl TrueRange {
59 pub fn new() -> Self {
60 Self { prev_close: None }
61 }
62}
63
64impl Default for TrueRange {
65 fn default() -> Self {
66 Self::new()
67 }
68}
69
70impl fmt::Display for TrueRange {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 write!(f, "TRUE_RANGE()")
73 }
74}
75
76impl Next<f64> for TrueRange {
77 type Output = f64;
78
79 fn next(&mut self, input: f64) -> Self::Output {
80 let distance = match self.prev_close {
81 Some(prev) => (input - prev).abs(),
82 None => 0.0,
83 };
84 self.prev_close = Some(input);
85 distance
86 }
87}
88
89impl<T: High + Low + Close> Next<&T> for TrueRange {
90 type Output = f64;
91
92 fn next(&mut self, bar: &T) -> Self::Output {
93 let max_dist = match self.prev_close {
94 Some(prev_close) => {
95 let dist1 = bar.high() - bar.low();
96 let dist2 = (bar.high() - prev_close).abs();
97 let dist3 = (bar.low() - prev_close).abs();
98 max3(dist1, dist2, dist3)
99 }
100 None => bar.high() - bar.low(),
101 };
102 self.prev_close = Some(bar.close());
103 max_dist
104 }
105}
106
107impl Reset for TrueRange {
108 fn reset(&mut self) {
109 self.prev_close = None;
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 use crate::test_helper::*;
117
118 test_indicator!(TrueRange);
119
120 #[test]
121 fn test_next_f64() {
122 let mut tr = TrueRange::new();
123 assert_eq!(round(tr.next(2.5)), 0.0);
124 assert_eq!(round(tr.next(3.6)), 1.1);
125 assert_eq!(round(tr.next(3.3)), 0.3);
126 }
127
128 #[test]
129 fn test_next_bar() {
130 let mut tr = TrueRange::new();
131
132 let bar1 = Bar::new().high(10).low(7.5).close(9);
133 let bar2 = Bar::new().high(11).low(9).close(9.5);
134 let bar3 = Bar::new().high(9).low(5).close(8);
135
136 assert_eq!(tr.next(&bar1), 2.5);
137 assert_eq!(tr.next(&bar2), 2.0);
138 assert_eq!(tr.next(&bar3), 4.5);
139 }
140
141 #[test]
142 fn test_reset() {
143 let mut tr = TrueRange::new();
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
148 tr.next(&bar1);
149 tr.next(&bar2);
150
151 tr.reset();
152 let bar3 = Bar::new().high(60).low(15).close(51);
153 assert_eq!(tr.next(&bar3), 45.0);
154 }
155
156 #[test]
157 fn test_default() {
158 TrueRange::default();
159 }
160
161 #[test]
162 fn test_display() {
163 let indicator = TrueRange::new();
164 assert_eq!(format!("{}", indicator), "TRUE_RANGE()");
165 }
166}