Compare commits
No commits in common. "38cd013ab98c2299ff9faf5146b21ed5af5a31b1" and "89487c886593745306a4d5fe965691ee61289019" have entirely different histories.
38cd013ab9
...
89487c8865
4 changed files with 33 additions and 155 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1 @@
|
||||||
1--transforming-sync-to-async/provided-code/target
|
1--transforming-sync-to-async/provided-code/target
|
||||||
target
|
|
||||||
|
|
103
Cargo.lock
generated
103
Cargo.lock
generated
|
@ -95,24 +95,6 @@ dependencies = [
|
||||||
"event-listener",
|
"event-listener",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-process"
|
|
||||||
version = "1.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9"
|
|
||||||
dependencies = [
|
|
||||||
"async-io",
|
|
||||||
"async-lock",
|
|
||||||
"autocfg",
|
|
||||||
"blocking",
|
|
||||||
"cfg-if",
|
|
||||||
"event-listener",
|
|
||||||
"futures-lite",
|
|
||||||
"rustix",
|
|
||||||
"signal-hook",
|
|
||||||
"windows-sys 0.48.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-std"
|
name = "async-std"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
|
@ -124,7 +106,6 @@ dependencies = [
|
||||||
"async-global-executor",
|
"async-global-executor",
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock",
|
||||||
"async-process",
|
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -387,47 +368,20 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
|
||||||
dependencies = [
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"futures-executor",
|
|
||||||
"futures-io",
|
|
||||||
"futures-sink",
|
|
||||||
"futures-task",
|
|
||||||
"futures-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.30"
|
version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.30"
|
version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-executor"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core",
|
|
||||||
"futures-task",
|
|
||||||
"futures-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
|
@ -450,45 +404,28 @@ dependencies = [
|
||||||
"waker-fn",
|
"waker-fn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-macro"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.52",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.30"
|
version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.30"
|
version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.30"
|
version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
|
||||||
"futures-macro",
|
|
||||||
"futures-sink",
|
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"memchr",
|
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
"slab",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -726,7 +663,6 @@ dependencies = [
|
||||||
"async-std",
|
"async-std",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"futures",
|
|
||||||
"yahoo_finance_api",
|
"yahoo_finance_api",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1151,25 +1087,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"signal-hook-registry",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-registry"
|
|
||||||
version = "1.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
|
|
|
@ -10,5 +10,4 @@ version = "0.1.0"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
clap = {version = "3.1.8", features = ["derive"]}
|
clap = {version = "3.1.8", features = ["derive"]}
|
||||||
yahoo_finance_api = "1.1"
|
yahoo_finance_api = "1.1"
|
||||||
async-std = { version = "1.6", features = ["attributes", "tokio1", "unstable"] }
|
async-std = { version = "1.6", features = ["attributes", "tokio1"] }
|
||||||
futures = "0.3"
|
|
||||||
|
|
81
src/main.rs
81
src/main.rs
|
@ -1,12 +1,6 @@
|
||||||
use async_std::prelude::*;
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use futures::future::try_join_all;
|
use std::io::{Error, ErrorKind};
|
||||||
use std::{
|
|
||||||
io::{Error, ErrorKind},
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
use yahoo_finance_api as yahoo;
|
use yahoo_finance_api as yahoo;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
|
@ -124,52 +118,6 @@ async fn fetch_closing_data(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_csv_line(closes: Vec<f64>, from: DateTime<Utc>, symbol: &str) {
|
|
||||||
let period_max: f64 = max(&closes).unwrap();
|
|
||||||
let period_min: f64 = min(&closes).unwrap();
|
|
||||||
let last_price = *closes.last().unwrap_or(&0.0);
|
|
||||||
let (_, pct_change) = price_diff(&closes).unwrap_or((0.0, 0.0));
|
|
||||||
let sma = n_window_sma(30, &closes).unwrap_or_default();
|
|
||||||
|
|
||||||
// a simple way to output CSV data
|
|
||||||
println!(
|
|
||||||
"{},{},${:.2},{:.2}%,${:.2},${:.2},${:.2}",
|
|
||||||
from.to_rfc3339(),
|
|
||||||
symbol,
|
|
||||||
last_price,
|
|
||||||
pct_change * 100.0,
|
|
||||||
period_min,
|
|
||||||
period_max,
|
|
||||||
sma.last().unwrap_or(&0.0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn fetch_and_output_closing_data(
|
|
||||||
symbol: &str,
|
|
||||||
from: DateTime<Utc>,
|
|
||||||
to: DateTime<Utc>,
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
let closes = fetch_closing_data(&symbol, &from, &to).await?;
|
|
||||||
if !closes.is_empty() {
|
|
||||||
output_csv_line(closes, from, symbol);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn fetch_and_output_symbol_data(
|
|
||||||
symbols: &str,
|
|
||||||
from: DateTime<Utc>,
|
|
||||||
to: DateTime<Utc>,
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
let mut fs = vec![];
|
|
||||||
for symbol in symbols.split(',') {
|
|
||||||
let f = fetch_and_output_closing_data(symbol, from, to);
|
|
||||||
fs.push(f);
|
|
||||||
}
|
|
||||||
try_join_all(fs).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
let opts = Opts::parse();
|
let opts = Opts::parse();
|
||||||
|
@ -178,13 +126,28 @@ async fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
// a simple way to output a CSV header
|
// a simple way to output a CSV header
|
||||||
println!("period start,symbol,price,change %,min,max,30d avg");
|
println!("period start,symbol,price,change %,min,max,30d avg");
|
||||||
|
for symbol in opts.symbols.split(',') {
|
||||||
|
let closes = fetch_closing_data(&symbol, &from, &to).await?;
|
||||||
|
if !closes.is_empty() {
|
||||||
|
// min/max of the period. unwrap() because those are Option types
|
||||||
|
let period_max: f64 = max(&closes).unwrap();
|
||||||
|
let period_min: f64 = min(&closes).unwrap();
|
||||||
|
let last_price = *closes.last().unwrap_or(&0.0);
|
||||||
|
let (_, pct_change) = price_diff(&closes).unwrap_or((0.0, 0.0));
|
||||||
|
let sma = n_window_sma(30, &closes).unwrap_or_default();
|
||||||
|
|
||||||
// initial data fetch
|
// a simple way to output CSV data
|
||||||
fetch_and_output_symbol_data(&opts.symbols, from, to).await?;
|
println!(
|
||||||
|
"{},{},${:.2},{:.2}%,${:.2},${:.2},${:.2}",
|
||||||
let mut interval = async_std::stream::interval(Duration::from_secs(30));
|
from.to_rfc3339(),
|
||||||
while let Some(_) = interval.next().await {
|
symbol,
|
||||||
fetch_and_output_symbol_data(&opts.symbols, from, to).await?;
|
last_price,
|
||||||
|
pct_change * 100.0,
|
||||||
|
period_min,
|
||||||
|
period_max,
|
||||||
|
sma.last().unwrap_or(&0.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue