Skip to content

Commit

Permalink
refactor; atr
Browse files Browse the repository at this point in the history
  • Loading branch information
m5l14i11 committed Jul 1, 2023
1 parent db6971c commit 2b950cf
Show file tree
Hide file tree
Showing 29 changed files with 291 additions and 179 deletions.
25 changes: 24 additions & 1 deletion ta_lib/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion ta_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ members = [
"overlap",
"momentum",
"price",
"statistics"
"trend",
"volatility",
"volume",
"utils"
]
22 changes: 6 additions & 16 deletions ta_lib/momentum/src/aosc.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
use overlap::sma::sma;
use price::median::median_price;

pub fn aosc(
high: &[f64],
low: &[f64],
short_period: usize,
long_period: usize,
) -> Vec<Option<f64>> {
let median_price = median_price(high, low);
let median_price_values = median_price
.iter()
.map(|&x| x.unwrap_or(0.0))
.collect::<Vec<_>>();

let ao_short = sma(&median_price_values, short_period);
let ao_long = sma(&median_price_values, long_period);
pub fn aosc(hl2: &[f64], short_period: usize, long_period: usize) -> Vec<Option<f64>> {
let ao_short = sma(hl2, short_period);
let ao_long = sma(hl2, long_period);

ao_short
.iter()
Expand All @@ -29,16 +17,18 @@ pub fn aosc(
#[cfg(test)]
mod tests {
use super::*;
use price::median::median_price;

#[test]
fn test_aosc() {
let high = &[3.0, 4.0, 5.0, 6.0, 7.0];
let low = &[1.0, 2.0, 3.0, 4.0, 5.0];
let hl2 = median_price(high, low);
let short_period = 2;
let long_period = 4;
let expected_result = vec![None, None, None, Some(1.0), Some(1.0)];

let result = aosc(high, low, short_period, long_period);
let result = aosc(&hl2, short_period, long_period);

assert_eq!(result, expected_result);
}
Expand Down
12 changes: 6 additions & 6 deletions ta_lib/momentum/src/macd.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use overlap::ema::ema;

pub fn macd(
data: &[f64],
source: &[f64],
fast_period: usize,
slow_period: usize,
signal_period: usize,
) -> (Vec<Option<f64>>, Vec<Option<f64>>, Vec<Option<f64>>) {
let ema_fast = ema(data, fast_period);
let ema_slow = ema(data, slow_period);
let ema_fast = ema(source, fast_period);
let ema_slow = ema(source, slow_period);

let macd_line = ema_fast
.iter()
Expand Down Expand Up @@ -44,7 +44,7 @@ mod tests {

#[test]
fn test_macd() {
let data = vec![2.0, 4.0, 6.0, 8.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0];
let source = vec![2.0, 4.0, 6.0, 8.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0];
let fast_period = 3;
let slow_period = 5;
let signal_period = 4;
Expand Down Expand Up @@ -87,9 +87,9 @@ mod tests {
];

let (macd_line, signal_line, histogram) =
macd(&data, fast_period, slow_period, signal_period);
macd(&source, fast_period, slow_period, signal_period);

for i in 0..data.len() {
for i in 0..source.len() {
match (macd_line[i], expected_macd_line[i]) {
(Some(a), Some(b)) => {
assert!((a - b).abs() < epsilon, "at position {}: {} != {}", i, a, b)
Expand Down
28 changes: 14 additions & 14 deletions ta_lib/momentum/src/rsi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use overlap::smma::smma;

pub fn rsi(data: &[f64], period: usize) -> Vec<Option<f64>> {
let len = data.len();
pub fn rsi(source: &[f64], period: usize) -> Vec<Option<f64>> {
let len = source.len();

if len < period {
return vec![None; len];
Expand All @@ -10,8 +10,8 @@ pub fn rsi(data: &[f64], period: usize) -> Vec<Option<f64>> {
let mut gains = vec![0.0; len];
let mut losses = vec![0.0; len];

for i in 1..data.len() {
let change = data[i] - data[i - 1];
for i in 1..len {
let change = source[i] - source[i - 1];

gains[i] = change.max(0.0);
losses[i] = (-change).max(0.0);
Expand Down Expand Up @@ -41,28 +41,28 @@ mod test {

#[test]
fn test_rsi_len() {
let data = vec![5.0];
let result = rsi(&data, 1);
assert_eq!(data.len(), result.len());
let source = vec![5.0];
let result = rsi(&source, 1);
assert_eq!(source.len(), result.len());
}

#[test]
fn test_rsi_empty() {
let data = vec![];
let result = rsi(&data, 14);
let source = vec![];
let result = rsi(&source, 14);
assert_eq!(result, vec![]);
}

#[test]
fn test_rsi_single_value() {
let data = [10.0];
let rsi_values = rsi(&data, 14);
let source = [10.0];
let rsi_values = rsi(&source, 14);
assert_eq!(rsi_values, vec![None]);
}

#[test]
fn test_rsi_with_valid_data() {
let data = vec![
let source = vec![
44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42, 45.84,
];
let epsilon = 0.001;
Expand All @@ -78,9 +78,9 @@ mod test {
Some(84.221979),
];

let result = rsi(&data, 6);
let result = rsi(&source, 6);

for i in 0..result.len() {
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)
Expand Down
2 changes: 0 additions & 2 deletions ta_lib/overlap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,3 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
price = { path = "../price" }
statistics = { path = "../statistics" }
22 changes: 11 additions & 11 deletions ta_lib/overlap/src/ema.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub fn ema(data: &[f64], period: usize) -> Vec<Option<f64>> {
let len = data.len();
pub fn ema(source: &[f64], period: usize) -> Vec<Option<f64>> {
let len = source.len();

if len < period {
return vec![None; len];
Expand All @@ -8,10 +8,10 @@ pub fn ema(data: &[f64], period: usize) -> Vec<Option<f64>> {
let alpha = 2.0 / (period as f64 + 1.0);

let mut ema = vec![None; len];
let mut ema_current = data[0];
let mut ema_current = source[0];

for i in 1..len {
ema_current = (data[i] - ema_current) * alpha + ema_current;
ema_current = (source[i] - ema_current) * alpha + ema_current;

if i >= period - 1 {
ema[i] = Some(ema_current);
Expand All @@ -27,22 +27,22 @@ mod tests {

#[test]
fn test_ema_len() {
let data = vec![1.0, 2.0];
let result = ema(&data, 3);
assert_eq!(data.len(), result.len());
let source = vec![1.0, 2.0];
let result = ema(&source, 3);
assert_eq!(source.len(), result.len());
}

#[test]
fn test_ema_edge_case() {
let data = vec![1.0, 2.0];
let result = ema(&data, 3);
let source = vec![1.0, 2.0];
let result = ema(&source, 3);
assert_eq!(result, vec![None, None]);
}

#[test]
fn test_ema() {
let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let result = ema(&data, 3);
let source = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let result = ema(&source, 3);
assert_eq!(
result,
vec![None, None, Some(2.25), Some(3.125), Some(4.0625)]
Expand Down
3 changes: 1 addition & 2 deletions ta_lib/overlap/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pub mod ema;
pub mod sma;
pub mod smma;
pub mod vwap;
pub mod zlema;
pub mod wma;
22 changes: 11 additions & 11 deletions ta_lib/overlap/src/sma.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub fn sma(data: &[f64], period: usize) -> Vec<Option<f64>> {
let len = data.len();
pub fn sma(source: &[f64], period: usize) -> Vec<Option<f64>> {
let len = source.len();

if len < period {
return vec![None; len];
Expand All @@ -9,10 +9,10 @@ pub fn sma(data: &[f64], period: usize) -> Vec<Option<f64>> {
let mut sum = 0.0;

for i in 0..len {
sum += data[i];
sum += source[i];

if i >= period {
sum -= data[i - period];
sum -= source[i - period];
sma[i] = Some(sum / period as f64);
} else if i + 1 == period {
sma[i] = Some(sum / period as f64);
Expand All @@ -28,22 +28,22 @@ mod tests {

#[test]
fn test_sma_len() {
let data = vec![1.0, 2.0];
let result = sma(&data, 3);
assert_eq!(data.len(), result.len());
let source = vec![1.0, 2.0];
let result = sma(&source, 3);
assert_eq!(source.len(), result.len());
}

#[test]
fn test_sma_edge_case() {
let data = vec![1.0, 2.0];
let result = sma(&data, 3);
let source = vec![1.0, 2.0];
let result = sma(&source, 3);
assert_eq!(result, vec![None, None]);
}

#[test]
fn test_sma() {
let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let result = sma(&data, 3);
let source = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let result = sma(&source, 3);
assert_eq!(result, vec![None, None, Some(2.0), Some(3.0), Some(4.0)]);
}
}
24 changes: 12 additions & 12 deletions ta_lib/overlap/src/smma.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub fn smma(data: &[f64], period: usize) -> Vec<Option<f64>> {
let len = data.len();
pub fn smma(source: &[f64], period: usize) -> Vec<Option<f64>> {
let len = source.len();

if len < period {
return vec![None; len];
Expand All @@ -8,10 +8,10 @@ pub fn smma(data: &[f64], period: usize) -> Vec<Option<f64>> {
let alpha = 1.0 / period as f64;

let mut smma = vec![None; len];
let mut smma_current = data[0];
let mut smma_current = source[0];

for i in 1..len {
smma_current = (data[i] - smma_current) * alpha + smma_current;
smma_current = (source[i] - smma_current) * alpha + smma_current;

if i >= period - 1 {
smma[i] = Some(smma_current);
Expand All @@ -27,27 +27,27 @@ mod tests {

#[test]
fn test_smma_len() {
let data = vec![1.0, 2.0];
let result = smma(&data, 3);
assert_eq!(data.len(), result.len());
let source = vec![1.0, 2.0];
let result = smma(&source, 3);
assert_eq!(source.len(), result.len());
}

#[test]
fn test_smmma_edge_case() {
let data = vec![1.0, 2.0];
let result = smma(&data, 3);
let source = vec![1.0, 2.0];
let result = smma(&source, 3);
assert_eq!(result, vec![None, None]);
}

#[test]
fn test_smma() {
let data = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let source = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let expected = vec![None, None, Some(1.888), Some(2.592), Some(3.395)];
let epsilon = 0.001;

let result = smma(&data, 3);
let result = smma(&source, 3);

for i in 0..result.len() {
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)
Expand Down
Loading

0 comments on commit 2b950cf

Please sign in to comment.