egui_charts/studies/builtin/
average_daily_range.rs1use super::over_finite_bars;
23use crate::model::Bar;
24use crate::studies::palette;
25use crate::studies::stepper::{rolling_mean, update_window, usable_behind};
26use crate::studies::{Indicator, IndicatorValue, IndicatorValues};
27use egui::Color32;
28
29#[derive(Clone)]
31pub struct AverageDailyRange {
32 period: usize,
33 values: IndicatorValues,
34 color: Color32,
35 visible: bool,
36}
37
38impl AverageDailyRange {
39 pub fn new(period: usize) -> Self {
41 Self {
42 period: period.max(1),
43 values: IndicatorValues::new(),
44 color: palette::BLUE,
45 visible: true,
46 }
47 }
48}
49
50impl AverageDailyRange {
51 fn compute(&self, data: &[Bar]) -> IndicatorValues {
52 let ranges: Vec<f64> = data.iter().map(|b| b.high - b.low).collect();
53 rolling_mean(&ranges, self.period)
54 .into_iter()
55 .map(IndicatorValue::Single)
56 .collect()
57 }
58}
59
60impl Default for AverageDailyRange {
61 fn default() -> Self {
62 Self::new(14)
63 }
64}
65
66impl Indicator for AverageDailyRange {
67 crate::studies::inputs::study_inputs!(self;
68 period: length("Length", 1, usize::MAX)
69 ; {});
70
71 fn value_format(&self) -> crate::scales::StudyFormat {
72 crate::scales::StudyFormat::Price
73 }
74
75 fn name(&self) -> &str {
76 "Average Daily Range"
77 }
78
79 fn desc(&self) -> &str {
80 "Average Daily Range - Simple average of the high-low range"
81 }
82
83 fn calculate(&mut self, data: &[Bar]) {
84 self.update(data, 0);
85 }
86
87 fn update(&mut self, data: &[Bar], from: usize) {
88 let mut values = std::mem::take(&mut self.values);
89 update_window(
90 &mut values,
91 data,
92 from,
93 usable_behind(self.period - 1, |b| b.high.is_finite() && b.low.is_finite()),
94 |data| {
95 over_finite_bars(
96 data,
97 |b| b.high.is_finite() && b.low.is_finite(),
98 |data| self.compute(data),
99 )
100 },
101 );
102 self.values = values;
103 }
104
105 fn is_incremental(&self) -> bool {
106 true
107 }
108
109 fn values(&self) -> &IndicatorValues {
110 &self.values
111 }
112
113 fn colors(&self) -> Vec<Color32> {
114 vec![self.color]
115 }
116
117 fn set_colors(&mut self, colors: Vec<Color32>) {
118 if let Some(&color) = colors.first() {
119 self.color = color;
120 }
121 }
122
123 fn is_overlay(&self) -> bool {
124 false
125 }
126
127 fn is_visible(&self) -> bool {
128 self.visible
129 }
130
131 fn set_visible(&mut self, visible: bool) {
132 self.visible = visible;
133 }
134
135 fn clone_box(&self) -> Box<dyn Indicator> {
136 Box::new(self.clone())
137 }
138
139 fn line_names(&self) -> Vec<String> {
140 vec![format!("ADR({})", self.period)]
141 }
142}