From 984a9a77e64064ebcd4896f3be6f28c00011a4d8 Mon Sep 17 00:00:00 2001 From: m5l14i11 Date: Wed, 5 Jul 2023 10:13:34 +0300 Subject: [PATCH] vo --- ta_lib/volume/src/lib.rs | 1 + ta_lib/volume/src/vo.rs | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 ta_lib/volume/src/vo.rs diff --git a/ta_lib/volume/src/lib.rs b/ta_lib/volume/src/lib.rs index cb70ceb2..cc819733 100644 --- a/ta_lib/volume/src/lib.rs +++ b/ta_lib/volume/src/lib.rs @@ -1 +1,2 @@ +pub mod vo; pub mod vwap; diff --git a/ta_lib/volume/src/vo.rs b/ta_lib/volume/src/vo.rs new file mode 100644 index 00000000..3d5567c4 --- /dev/null +++ b/ta_lib/volume/src/vo.rs @@ -0,0 +1,39 @@ +use overlap::ema::ema; + +pub fn vo(source: &[f64], short_period: usize, long_period: usize) -> Vec> { + let vo_short = ema(source, short_period); + let vo_long = ema(source, long_period); + + vo_short + .iter() + .zip(&vo_long) + .map(|(&short, &long)| match (short, long) { + (Some(short), Some(long)) => Some(100.0 * (short - long) / long), + _ => None, + }) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_vo() { + let source = vec![1.0, 2.0, 3.0, 2.0, 1.0]; + let expected = vec![None, None, Some(13.5802), Some(2.83224), Some(-10.71604)]; + let epsilon = 0.001; + + let result = vo(&source, 2, 3); + + for i in 0..source.len() { + match (result[i], expected[i]) { + (Some(a), Some(b)) => { + assert!((a - b).abs() < epsilon, "at position {}: {} != {}", i, a, b) + } + (None, None) => {} + _ => panic!("at position {}: {:?} != {:?}", i, result[i], expected[i]), + } + } + } +}