egui_charts/studies/builtin/
typical_price.rs1use crate::model::Bar;
2use crate::studies::palette;
3use crate::studies::{Indicator, IndicatorValue, IndicatorValues};
4use egui::Color32;
5
6#[derive(Clone)]
12pub struct TypicalPrice {
13 values: IndicatorValues,
14 color: Color32,
15 visible: bool,
16}
17
18impl TypicalPrice {
19 pub fn new() -> Self {
21 Self {
22 values: IndicatorValues::new(),
23 color: palette::ORANGE,
24 visible: true,
25 }
26 }
27
28 pub fn with_color(mut self, color: Color32) -> Self {
30 self.color = color;
31 self
32 }
33}
34
35impl Default for TypicalPrice {
36 fn default() -> Self {
37 Self::new()
38 }
39}
40
41impl Indicator for TypicalPrice {
42 fn name(&self) -> &str {
43 "TP"
44 }
45
46 fn desc(&self) -> &str {
47 "Typical Price - (High + Low + Close) / 3"
48 }
49
50 fn calculate(&mut self, data: &[Bar]) {
51 self.update(data, 0);
52 }
53
54 fn update(&mut self, data: &[Bar], from: usize) {
55 let from = from.min(self.values.len()).min(data.len());
56 self.values.truncate(from);
57 for bar in &data[from..] {
58 let tp = (bar.high + bar.low + bar.close) / 3.0;
59 self.values.push(IndicatorValue::Single(tp));
60 }
61 }
62
63 fn is_incremental(&self) -> bool {
64 true
65 }
66
67 fn values(&self) -> &IndicatorValues {
68 &self.values
69 }
70
71 fn colors(&self) -> Vec<Color32> {
72 vec![self.color]
73 }
74
75 fn set_colors(&mut self, colors: Vec<Color32>) {
76 if !colors.is_empty() {
77 self.color = colors[0];
78 }
79 }
80
81 fn is_overlay(&self) -> bool {
82 true }
84
85 fn is_visible(&self) -> bool {
86 self.visible
87 }
88
89 fn set_visible(&mut self, visible: bool) {
90 self.visible = visible;
91 }
92
93 fn clone_box(&self) -> Box<dyn Indicator> {
94 Box::new(self.clone())
95 }
96
97 fn line_names(&self) -> Vec<String> {
98 vec!["TP".to_string()]
99 }
100}
101
102#[derive(Clone)]
104pub struct WeightedClose {
105 values: IndicatorValues,
106 color: Color32,
107 visible: bool,
108}
109
110impl WeightedClose {
111 pub fn new() -> Self {
113 Self {
114 values: IndicatorValues::new(),
115 color: palette::BLUE,
116 visible: true,
117 }
118 }
119
120 pub fn with_color(mut self, color: Color32) -> Self {
122 self.color = color;
123 self
124 }
125}
126
127impl Default for WeightedClose {
128 fn default() -> Self {
129 Self::new()
130 }
131}
132
133impl Indicator for WeightedClose {
134 fn name(&self) -> &str {
135 "WC"
136 }
137
138 fn desc(&self) -> &str {
139 "Weighted Close - (High + Low + 2*Close) / 4"
140 }
141
142 fn calculate(&mut self, data: &[Bar]) {
143 self.update(data, 0);
144 }
145
146 fn update(&mut self, data: &[Bar], from: usize) {
147 let from = from.min(self.values.len()).min(data.len());
148 self.values.truncate(from);
149 for bar in &data[from..] {
150 let wc = (bar.high + bar.low + 2.0 * bar.close) / 4.0;
151 self.values.push(IndicatorValue::Single(wc));
152 }
153 }
154
155 fn is_incremental(&self) -> bool {
156 true
157 }
158
159 fn values(&self) -> &IndicatorValues {
160 &self.values
161 }
162
163 fn colors(&self) -> Vec<Color32> {
164 vec![self.color]
165 }
166
167 fn set_colors(&mut self, colors: Vec<Color32>) {
168 if !colors.is_empty() {
169 self.color = colors[0];
170 }
171 }
172
173 fn is_overlay(&self) -> bool {
174 true
175 }
176
177 fn is_visible(&self) -> bool {
178 self.visible
179 }
180
181 fn set_visible(&mut self, visible: bool) {
182 self.visible = visible;
183 }
184
185 fn clone_box(&self) -> Box<dyn Indicator> {
186 Box::new(self.clone())
187 }
188
189 fn line_names(&self) -> Vec<String> {
190 vec!["WC".to_string()]
191 }
192}
193
194#[derive(Clone)]
198pub struct MedianPrice {
199 values: IndicatorValues,
200 color: Color32,
201 visible: bool,
202}
203
204impl MedianPrice {
205 pub fn new() -> Self {
207 Self {
208 values: IndicatorValues::new(),
209 color: palette::ORANGE,
210 visible: true,
211 }
212 }
213
214 pub fn with_color(mut self, color: Color32) -> Self {
216 self.color = color;
217 self
218 }
219}
220
221impl Default for MedianPrice {
222 fn default() -> Self {
223 Self::new()
224 }
225}
226
227impl Indicator for MedianPrice {
228 fn name(&self) -> &str {
229 "MP"
230 }
231
232 fn desc(&self) -> &str {
233 "Median Price - (High + Low) / 2"
234 }
235
236 fn calculate(&mut self, data: &[Bar]) {
237 self.update(data, 0);
238 }
239
240 fn update(&mut self, data: &[Bar], from: usize) {
241 let from = from.min(self.values.len()).min(data.len());
242 self.values.truncate(from);
243 for bar in &data[from..] {
244 let mp = (bar.high + bar.low) / 2.0;
245 self.values.push(IndicatorValue::Single(mp));
246 }
247 }
248
249 fn is_incremental(&self) -> bool {
250 true
251 }
252
253 fn values(&self) -> &IndicatorValues {
254 &self.values
255 }
256
257 fn colors(&self) -> Vec<Color32> {
258 vec![self.color]
259 }
260
261 fn set_colors(&mut self, colors: Vec<Color32>) {
262 if !colors.is_empty() {
263 self.color = colors[0];
264 }
265 }
266
267 fn is_overlay(&self) -> bool {
268 true
269 }
270
271 fn is_visible(&self) -> bool {
272 self.visible
273 }
274
275 fn set_visible(&mut self, visible: bool) {
276 self.visible = visible;
277 }
278
279 fn clone_box(&self) -> Box<dyn Indicator> {
280 Box::new(self.clone())
281 }
282
283 fn line_names(&self) -> Vec<String> {
284 vec!["MP".to_string()]
285 }
286}