quantaxis_rs/qaindicator.rs
1
2// use std::f64::NAN;
3
4
5// use ndarray;
6// use ndarray::prelude::*;
7// use std::iter::FromIterator;
8
9
10// #[derive(Debug)]
11// pub enum Err {
12// NotEnoughtData, // not enought data to compute requested values
13// }
14
15
16// pub fn round_array(array: &mut [f64], decimals: u8) {
17// let divider = (10.0 as f64).powi(decimals as i32);
18// for number in array {
19// *number = (*number * divider).round() / divider;
20// }
21// }
22
23
24
25
26// //pub fn HHV(data: &[f64], period: usize) -> Result<Vec<f64>, Err> {
27// // if length <= 0 {
28// // return Err(Err::NotEnoughtData);
29// // }
30// //
31// // let highest = source.get(0);
32// //
33// // if highest.is_none() {
34// // return Err(Err::NotEnoughtData);
35// // }
36// //
37// // let mut highest = highest.unwrap();
38// //
39// // for index in 1..(length) {
40// // match source.get(index) {
41// // None => {}
42// // Some(maybe_highest) => {
43// // if maybe_highest > highest {
44// // highest = maybe_highest;
45// // }
46// // }
47// // }
48// // }
49// //
50// // Ok(highest)
51// //}
52// //
53
54// pub fn ema(data: &[f64], period: usize) -> Result<Vec<f64>, Err> {
55// if period > data.len() {
56// return Err(Err::NotEnoughtData);
57// }
58// let mut ema = Vec::new();
59// let mut j = 1;
60
61// // get period sma first and calculate the next period period ema
62// let sma = (data[0..period])
63// .iter()
64// .sum::<f64>() / period as f64;
65// let multiplier: f64 = 2.0 / (1.0 + period as f64);
66// ema.push(sma);
67
68// // EMA(current) = ( (Price(current) - EMA(prev) ) x Multiplier) + EMA(prev)
69// ema.push(((data[period] - sma) * multiplier) + sma);
70
71// // now calculate the rest of the values
72// for i in &data[period + 1..data.len()] {
73// println!("{:#?}", i);
74// let tmp = ((*i - ema[j]) * multiplier) + ema[j];
75// j = j + 1;
76// ema.push(tmp);
77// }
78
79// Ok(ema)
80// }
81
82// pub fn sma(data: &[f64], period: usize) -> Result<Vec<f64>, Err> {
83// if period > data.len() {
84// return Err(Err::NotEnoughtData);
85// }
86
87// let mut result = Vec::new();
88// let mut running_total = 0.0;
89
90// for i in 0..data.len() {
91// running_total += data[i];
92// if i >= period {
93// running_total -= data[i - period];
94// }
95// if i >= period - 1 {
96// result.push(running_total / period as f64);
97// }
98// }
99// Ok(result)
100// }
101
102
103// pub fn psar(high: &[f64], low: &[f64], iaf: f64, maxaf: f64) -> Result<Vec<f64>, Err> {
104// let mut psar = vec![NAN; high.len()];
105
106// if high.len() < 2 {
107// return Err(Err::NotEnoughtData);
108// };
109
110// let mut long = false;
111// if high[0] + low[0] <= high[1] + low[1] {
112// long = true;
113// }
114
115// let mut sar;
116// let mut extreme;
117
118// if long {
119// extreme = high[0];
120// sar = low[0];
121// } else {
122// extreme = low[0];
123// sar = high[0];
124// }
125
126// psar[0] = sar;
127
128// let mut af = iaf;
129
130// for i in 1..high.len() {
131// sar = (extreme - sar) * af + sar;
132
133// if long {
134// if i >= 2 && (sar > low[i - 2]) {
135// sar = low[i - 2]
136// };
137// if sar > low[i - 1] {
138// sar = low[i - 1]
139// };
140
141// if af < maxaf && high[i] > extreme {
142// af += iaf;
143// if af > maxaf {
144// af = maxaf
145// };
146// }
147
148// if high[i] > extreme {
149// extreme = high[i];
150// }
151// } else {
152// if i >= 2 && sar < high[i - 2] {
153// sar = high[i - 2]
154// };
155// if sar < high[i - 1] {
156// sar = high[i - 1]
157// };
158
159// if af < maxaf && low[i] < extreme {
160// af += iaf;
161// if af > maxaf {
162// af = maxaf
163// };
164// }
165
166// if low[i] < extreme {
167// extreme = low[i]
168// };
169// }
170
171// if long && low[i] < sar || !long && high[i] > sar {
172// af = iaf;
173// sar = extreme;
174
175// long = !long;
176
177// if !long {
178// extreme = low[i];
179// } else {
180// extreme = high[i];
181// }
182// }
183
184// psar[i] = sar;
185// }
186
187// Ok(psar)
188// }
189
190
191// pub fn rsi(data: &[f64], period: usize) -> Result<Vec<f64>, Err> {
192// if period > data.len() {
193// return Err(Err::NotEnoughtData);
194// }
195
196// let mut changes = Vec::new();
197// for i in 0..data.len() - 1 {
198// let change = data[i + 1] - data[i];
199// changes.push(change);
200// }
201
202// let rsi_range = data.len() - period;
203
204// let mut rsis = vec![NAN ; rsi_range];
205
206// // gains & losses
207// let mut gains = Vec::new();
208// let mut losses = Vec::new();
209
210// for i in 0..changes.len() {
211// if changes[i] > 0.0 {
212// gains.push(changes[i]);
213// losses.push(0.0);
214// } else if changes[i] < 0.0 {
215// losses.push(changes[i] * -1.0);
216// gains.push(0.0);
217// } else {
218// gains.push(0.0);
219// losses.push(0.0);
220// }
221// }
222
223// let mut avg_gain: f64 = gains[..period].iter().sum::<f64>() / gains[..period].len() as f64;
224// let mut avg_loss: f64 = losses[..period].iter().sum::<f64>() / losses[..period].len() as f64;
225
226// if avg_loss == 0.0 {
227// rsis[0] = 100.0;
228// } else {
229// let rs = avg_gain / avg_loss;
230// rsis[0] = 100.0 - (100.0 / (1.0 + rs));
231// }
232
233// for i in 1..rsi_range {
234// avg_gain = (avg_gain * (period - 1) as f64 + gains[i + (period - 1)]) / period as f64;
235// avg_loss = (avg_loss * (period - 1) as f64 + losses[i + (period - 1)]) / period as f64;
236
237// if avg_loss == 0.0 {
238// rsis[i] = 100.0;
239// } else {
240// let rs = avg_gain / avg_loss;
241// rsis[i] = 100.0 - (100.0 / (1.0 + rs));
242// }
243// }
244
245// Ok(rsis)
246// }
247
248
249
250
251// // Some randomly generated data to test against TA-Lib (see generate_data.py & correct_values.py)
252// const OPEN: &[f64] = &[1984.03, 1959.83, 2041.42, 2019.04, 1969.53, 2082.75, 2209.52, 2200.9,
253// 2364.04, 2543.32, 2423.95, 2483.28, 2604.88, 2393.81, 2231.27, 2420.82,
254// 2544.0, 2766.67, 2919.62, 2763.25];
255// const HIGH: &[f64] = &[2174.72, 2129.49, 2158.92, 2050.2, 2042.12, 2151.19, 2220.64, 2352.98,
256// 2456.25, 2691.53, 2572.81, 2494.14, 2845.93, 2682.66, 2527.13, 2455.68,
257// 2607.54, 2872.17, 3004.26, 3036.05];
258// const LOW: &[f64] = &[1934.7, 1921.02, 1793.77, 1887.36, 1919.72, 1868.23, 1991.19, 2011.08,
259// 2193.91, 2183.96, 2223.15, 2363.19, 2240.03, 2208.31, 2192.15, 2199.02,
260// 2311.16, 2463.15, 2651.8, 2749.42];
261// const CLOSE: &[f64] = &[1959.83, 2041.42, 2019.04, 1969.53, 2082.75, 2209.52, 2200.9, 2364.04,
262// 2543.32, 2423.95, 2483.28, 2604.88, 2393.81, 2231.27, 2420.82, 2544.0,
263// 2766.67, 2919.62, 2763.25, 2922.14];
264
265
266// #[test]
267// fn sma_works() {
268// let mut result = sma(CLOSE, 4).unwrap();
269// let expected = &[1997.455, 2028.185, 2070.21, 2115.675, 2214.3025, 2329.445, 2383.0525,
270// 2453.6475, 2513.8575, 2476.48, 2428.31, 2412.695, 2397.475, 2490.69,
271// 2662.7775, 2748.385, 2842.92];
272// round_array(result.as_mut(), 4);
273// assert_eq!(result, expected);
274// }
275
276// #[test]
277// fn ema_works() {
278// let mut result = ema(CLOSE, 4).unwrap();
279// let expected = &[1997.455, 2031.573, 2102.7518, 2142.0111, 2230.8226, 2355.8216, 2383.073,
280// 2423.1558, 2495.8455, 2455.0313, 2365.5268, 2387.6441, 2450.1864, 2576.7799,
281// 2713.9159, 2733.6496, 2809.0457];
282// round_array(result.as_mut(), 4);
283// assert_eq!(result, expected);
284// }
285
286// #[test]
287// fn psar_works() {
288// let mut result = psar(HIGH, LOW, 0.02, 0.2).unwrap();
289// let expected = &[2174.72, 2169.646, 2158.92, 2158.92, 1793.77, 1800.9184, 1817.7073,
290// 1849.8236, 1898.3377, 1977.657, 2049.0443, 2113.2928, 2201.2093, 2845.93,
291// 2832.8544, 2820.0403, 2192.15, 2205.7504, 2237.6908];
292// round_array(result.as_mut(), 4);
293// // For some reasons, the first values are not exactly the same but since this indicator
294// // was not clearly described by its author, we can say that current implementation is correct.
295// assert_eq!(result[result.len() - 16..result.len()],
296// expected[expected.len() - 16..expected.len()]);
297// }
298
299// #[test]
300// fn rsi_works() {
301// let mut result = rsi(CLOSE, 6).unwrap();
302// let expected = &[79.9771, 86.5336, 90.5949, 73.0035, 75.8056, 80.7258, 56.706, 44.4766,
303// 57.3488, 63.879, 72.8847, 77.5072, 64.1009, 70.3536];
304// round_array(result.as_mut(), 4);
305// assert_eq!(result, expected);
306// }