trading_toolkit/indicator/
moving_average.rs1use crate::types::data::BaseData;
2
3#[derive(Debug, Clone, Copy)]
4pub enum MovingAverage {
5 Simple(f64),
6 Exponential(f64),
7}
8
9impl MovingAverage {
10 pub fn simple<T>(data: &[T]) -> Self
12 where
13 T: BaseData,
14 {
15 let mut sum = 0f64;
16 let mut count = 0f64;
17 for elem in data.iter() {
18 sum += elem.value();
19 count += 1f64;
20 }
21 Self::Simple(sum / count)
22 }
23
24 pub fn simple_from<T>(scope: usize, prev: &Self, oldest_data: &T, new_data: &T) -> Self
26 where
27 T: BaseData,
28 {
29 let prev = prev.inner();
30 let numerator = prev * (scope as f64);
31 Self::Simple((numerator - oldest_data.value() + new_data.value()) / (scope as f64))
32 }
33
34 pub fn exponential<T>(data: &[T]) -> Self
36 where
37 T: BaseData + Clone,
38 {
39 let mut data = data.to_vec();
40 data.sort_by_key(|k| k.epoch_time());
41 let len = data.len() as f64;
42 let k = 2f64 / (len as f64 + 1f64);
43
44 let seed = data.iter().map(|d| d.value()).sum::<f64>() / len as f64;
45 let mut result = seed;
46
47 for curr in data.iter() {
48 result = curr.value() * k + result * (1f64 - k);
49 }
50 Self::Exponential(result)
51 }
52
53 pub fn exponential_from<T>(scope: usize, prev: &Self, new_data: &T) -> Self
55 where
56 T: BaseData + Clone,
57 {
58 let k = 2f64 / ((scope + 1) as f64);
59 Self::Exponential(new_data.value() * k + prev.inner() * (1f64 - k))
60 }
61
62 pub fn inner(&self) -> f64 {
63 match self {
64 Self::Simple(f) | Self::Exponential(f) => f.clone(),
65 }
66 }
67}