finance_solution/stocks/ta/
ring.rs1#[derive(Clone, Debug)]
5pub(crate) struct RingF64 {
6 buf: Vec<f64>,
7 head: usize,
9 len: usize,
11 sum: f64,
12}
13
14impl RingF64 {
15 pub(crate) fn with_capacity(cap: usize) -> Self {
16 debug_assert!(cap >= 1);
17 Self {
18 buf: vec![0.0; cap],
19 head: 0,
20 len: 0,
21 sum: 0.0,
22 }
23 }
24
25 pub(crate) fn capacity(&self) -> usize {
26 self.buf.len()
27 }
28
29 pub(crate) fn len(&self) -> usize {
30 self.len
31 }
32
33 pub(crate) fn is_full(&self) -> bool {
34 self.len == self.buf.len()
35 }
36
37 pub(crate) fn sum(&self) -> f64 {
38 self.sum
39 }
40
41 pub(crate) fn clear(&mut self) {
42 self.head = 0;
43 self.len = 0;
44 self.sum = 0.0;
45 }
46
47 pub(crate) fn push(&mut self, value: f64) {
49 let cap = self.buf.len();
50 if self.len < cap {
51 self.buf[self.head] = value;
52 self.sum += value;
53 self.head = (self.head + 1) % cap;
54 self.len += 1;
55 } else {
56 let old = self.buf[self.head];
57 self.sum += value - old;
58 self.buf[self.head] = value;
59 self.head = (self.head + 1) % cap;
60 }
61 }
62
63 pub(crate) fn copy_ordered(&self, out: &mut Vec<f64>) {
65 out.clear();
66 if self.len == 0 {
67 return;
68 }
69 let cap = self.buf.len();
70 let start = if self.len < cap { 0 } else { self.head };
71 for i in 0..self.len {
72 out.push(self.buf[(start + i) % cap]);
73 }
74 }
75
76 pub(crate) fn mean(&self) -> Option<f64> {
77 if self.len == 0 {
78 None
79 } else {
80 Some(self.sum / self.len as f64)
81 }
82 }
83
84 pub(crate) fn max(&self) -> Option<f64> {
85 if self.len == 0 {
86 return None;
87 }
88 let cap = self.buf.len();
89 let start = if self.len < cap { 0 } else { self.head };
90 let mut m = f64::NEG_INFINITY;
91 for i in 0..self.len {
92 m = m.max(self.buf[(start + i) % cap]);
93 }
94 Some(m)
95 }
96
97 pub(crate) fn min(&self) -> Option<f64> {
98 if self.len == 0 {
99 return None;
100 }
101 let cap = self.buf.len();
102 let start = if self.len < cap { 0 } else { self.head };
103 let mut m = f64::INFINITY;
104 for i in 0..self.len {
105 m = m.min(self.buf[(start + i) % cap]);
106 }
107 Some(m)
108 }
109}
110
111#[derive(Clone, Debug)]
113pub(crate) struct RingPv {
114 pv: RingF64,
115 vol: RingF64,
116}
117
118impl RingPv {
119 pub(crate) fn with_capacity(cap: usize) -> Self {
120 Self {
121 pv: RingF64::with_capacity(cap),
122 vol: RingF64::with_capacity(cap),
123 }
124 }
125
126 pub(crate) fn clear(&mut self) {
127 self.pv.clear();
128 self.vol.clear();
129 }
130
131 pub(crate) fn is_full(&self) -> bool {
132 self.pv.is_full()
133 }
134
135 pub(crate) fn len(&self) -> usize {
136 self.pv.len()
137 }
138
139 pub(crate) fn push(&mut self, price: f64, volume: f64) {
140 self.pv.push(price * volume);
141 self.vol.push(volume);
142 }
143
144 pub(crate) fn vwap(&self) -> Option<f64> {
145 let v = self.vol.sum();
146 if v > 0.0 {
147 Some(self.pv.sum() / v)
148 } else {
149 None
150 }
151 }
152}