traits are async

This commit is contained in:
Paul Campbell 2024-03-10 16:56:02 +00:00
parent 7bfb2b915e
commit b109fc9394
3 changed files with 50 additions and 31 deletions

View file

@ -128,6 +128,17 @@ version = "4.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
[[package]]
name = "async-trait"
version = "0.1.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
@ -661,6 +672,7 @@ name = "manning-lp-async-rust-project-1-m1"
version = "0.1.0"
dependencies = [
"async-std",
"async-trait",
"chrono",
"clap",
"yahoo_finance_api",

View file

@ -10,4 +10,5 @@ version = "0.1.0"
chrono = { version = "0.4", features = ["serde"] }
clap = {version = "3.1.8", features = ["derive"]}
yahoo_finance_api = "1.1"
async-trait = "0.1"
async-std = { version = "1.6", features = ["attributes", "tokio1"] }

View file

@ -32,7 +32,7 @@ trait AsyncStockSignal {
///
/// The signal (using the provided type) or `None` on error/invalid data.
///
fn calculate(&self, series: &[f64]) -> Option<Self::SignalType>;
async fn calculate(&self, series: &[f64]) -> Option<Self::SignalType>;
}
///
@ -156,7 +156,7 @@ struct PriceDifference;
impl AsyncStockSignal for PriceDifference {
type SignalType = (f64, f64);
fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
async fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
price_diff(series)
}
}
@ -165,7 +165,7 @@ struct MinPrice;
impl AsyncStockSignal for MinPrice {
type SignalType = f64;
fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
async fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
min(series)
}
}
@ -174,7 +174,7 @@ struct MaxPrice;
impl AsyncStockSignal for MaxPrice {
type SignalType = f64;
fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
async fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
max(series)
}
}
@ -185,7 +185,7 @@ struct WindowedSMA {
impl AsyncStockSignal for WindowedSMA {
type SignalType = Vec<f64>;
fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
async fn calculate(&self, series: &[f64]) -> Option<Self::SignalType> {
n_window_sma(self.window_size, series)
}
}
@ -195,68 +195,74 @@ mod tests {
#![allow(non_snake_case)]
use super::*;
#[test]
fn test_PriceDifference_calculate() {
#[async_std::test]
async fn test_PriceDifference_calculate() {
let signal = PriceDifference {};
assert_eq!(signal.calculate(&[]), None);
assert_eq!(signal.calculate(&[1.0]), Some((0.0, 0.0)));
assert_eq!(signal.calculate(&[1.0, 0.0]), Some((-1.0, -1.0)));
assert_eq!(signal.calculate(&[]).await, None);
assert_eq!(signal.calculate(&[1.0]).await, Some((0.0, 0.0)));
assert_eq!(signal.calculate(&[1.0, 0.0]).await, Some((-1.0, -1.0)));
assert_eq!(
signal.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0]),
signal
.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0])
.await,
Some((8.0, 4.0))
);
assert_eq!(
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]),
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]).await,
Some((1.0, 1.0))
);
}
#[test]
fn test_MinPrice_calculate() {
#[async_std::test]
async fn test_MinPrice_calculate() {
let signal = MinPrice {};
assert_eq!(signal.calculate(&[]), None);
assert_eq!(signal.calculate(&[1.0]), Some(1.0));
assert_eq!(signal.calculate(&[1.0, 0.0]), Some(0.0));
assert_eq!(signal.calculate(&[]).await, None);
assert_eq!(signal.calculate(&[1.0]).await, Some(1.0));
assert_eq!(signal.calculate(&[1.0, 0.0]).await, Some(0.0));
assert_eq!(
signal.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0]),
signal
.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0])
.await,
Some(1.0)
);
assert_eq!(
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]),
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]).await,
Some(0.0)
);
}
#[test]
fn test_MaxPrice_calculate() {
#[async_std::test]
async fn test_MaxPrice_calculate() {
let signal = MaxPrice {};
assert_eq!(signal.calculate(&[]), None);
assert_eq!(signal.calculate(&[1.0]), Some(1.0));
assert_eq!(signal.calculate(&[1.0, 0.0]), Some(1.0));
assert_eq!(signal.calculate(&[]).await, None);
assert_eq!(signal.calculate(&[1.0]).await, Some(1.0));
assert_eq!(signal.calculate(&[1.0, 0.0]).await, Some(1.0));
assert_eq!(
signal.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0]),
signal
.calculate(&[2.0, 3.0, 5.0, 6.0, 1.0, 2.0, 10.0])
.await,
Some(10.0)
);
assert_eq!(
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]),
signal.calculate(&[0.0, 3.0, 5.0, 6.0, 1.0, 2.0, 1.0]).await,
Some(6.0)
);
}
#[test]
fn test_WindowedSMA_calculate() {
#[async_std::test]
async fn test_WindowedSMA_calculate() {
let series = vec![2.0, 4.5, 5.3, 6.5, 4.7];
let signal = WindowedSMA { window_size: 3 };
assert_eq!(
signal.calculate(&series),
signal.calculate(&series).await,
Some(vec![3.9333333333333336, 5.433333333333334, 5.5])
);
let signal = WindowedSMA { window_size: 5 };
assert_eq!(signal.calculate(&series), Some(vec![4.6]));
assert_eq!(signal.calculate(&series).await, Some(vec![4.6]));
let signal = WindowedSMA { window_size: 10 };
assert_eq!(signal.calculate(&series), Some(vec![]));
assert_eq!(signal.calculate(&series).await, Some(vec![]));
}
}