Skip to content

Commit

Permalink
bbands
Browse files Browse the repository at this point in the history
  • Loading branch information
m5l14i11 committed Jun 30, 2023
1 parent f34b893 commit e5ba77b
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
10 changes: 10 additions & 0 deletions ta_lib/volatility/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "volatility"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
statistics = { path = "../statistics" }
overlap = { path = "../overlap" }
110 changes: 110 additions & 0 deletions ta_lib/volatility/src/bbands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use overlap::sma::sma;
use statistics::stddev::std_dev;

pub fn bbands(
data: &[f64],
period: usize,
factor: usize,
) -> (Vec<Option<f64>>, Vec<Option<f64>>, Vec<Option<f64>>) {
let len = data.len();
let stddev = std_dev(data, period);
let middle_band = sma(data, period);

let mut upper_band = vec![None; len];
let mut lower_band = vec![None; len];

for i in 0..len {
if let (Some(middle), Some(std_dev)) = (middle_band[i], stddev[i]) {
upper_band[i] = Some(middle + (std_dev * factor as f64));
lower_band[i] = Some(middle - (std_dev * factor as f64));
}
}

(upper_band, middle_band, lower_band)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_bbands() {
let data = vec![2.0, 4.0, 6.0, 8.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0];
let period = 3;
let factor = 2;
let epsilon = 0.001;
let expected_upper_band = vec![
None,
None,
Some(7.265986),
Some(9.265986),
Some(11.265986),
Some(10.632993),
Some(10.632993),
Some(9.632993),
Some(8.632993),
Some(7.632993),
];
let expected_middle_band = vec![
None,
None,
Some(4.0),
Some(6.0),
Some(8.0),
Some(9.0),
Some(9.0),
Some(8.0),
Some(7.0),
Some(6.0),
];
let expected_lower_band = vec![
None,
None,
Some(0.734014),
Some(2.734014),
Some(4.734014),
Some(7.367007),
Some(7.367007),
Some(6.367007),
Some(5.367007),
Some(4.367007),
];

let (upper_band, middle_band, lower_band) = bbands(&data, period, factor);

for i in 0..data.len() {
match (upper_band[i], expected_upper_band[i]) {
(Some(a), Some(b)) => {
assert!((a - b).abs() < epsilon, "at position {}: {} != {}", i, a, b)
}
(None, None) => {}
_ => panic!(
"at position {}: {:?} != {:?}",
i, upper_band[i], expected_upper_band[i]
),
}

match (middle_band[i], expected_middle_band[i]) {
(Some(a), Some(b)) => {
assert!((a - b).abs() < epsilon, "at position {}: {} != {}", i, a, b)
}
(None, None) => {}
_ => panic!(
"at position {}: {:?} != {:?}",
i, middle_band[i], expected_middle_band[i]
),
}

match (lower_band[i], expected_lower_band[i]) {
(Some(a), Some(b)) => {
assert!((a - b).abs() < epsilon, "at position {}: {} != {}", i, a, b)
}
(None, None) => {}
_ => panic!(
"at position {}: {:?} != {:?}",
i, lower_band[i], expected_lower_band[i]
),
}
}
}
}
1 change: 1 addition & 0 deletions ta_lib/volatility/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod bbands;

0 comments on commit e5ba77b

Please sign in to comment.