From 925760b614a847c228425d6f5fbed9e0a0203af0 Mon Sep 17 00:00:00 2001 From: NexVeridian Date: Tue, 21 Nov 2023 19:25:32 +0000 Subject: [PATCH] 21shares --- Cargo.toml | 2 +- src/main.rs | 4 ++-- src/util.rs | 38 +++++++++++++++++++++++++++++++------- tests/integration.rs | 26 +++++++++++++++++++------- 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d2414c9..ed8dfd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ glob = { version = "0.3" } clokwerk = "0.4" strum_macros = "0.25" strum = "0.25" -tokio = { version = "1.26", features = ["full"] } +tokio = { version = "1.34", features = ["full"] } openssl = { version = "0.10", features = ["vendored"] } chrono = { version = "0.4", features = ["serde"] } serde_json = "1.0" diff --git a/src/main.rs b/src/main.rs index 49c7cb9..4ea4338 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,7 +67,7 @@ async fn spawn_ark_plan(ticker: Ticker) -> Result<(), Error> { async fn ark_etf() { let futures = Ticker::iter() - .filter(|&x| x != Ticker::ARKVC) + .filter(|&x| x != Ticker::ARKVX) .map(spawn_ark_plan) .collect::>(); @@ -99,7 +99,7 @@ async fn main() { scheduler .every(5.day()) .at("11:30 pm") - .run(|| async { if spawn_ark_plan(Ticker::ARKVC).await.is_ok() {} }); + .run(|| async { if spawn_ark_plan(Ticker::ARKVX).await.is_ok() {} }); loop { scheduler.run_pending().await; diff --git a/src/util.rs b/src/util.rs index 3bfdab7..5fe11bc 100644 --- a/src/util.rs +++ b/src/util.rs @@ -15,7 +15,7 @@ use strum_macros::{EnumIter, EnumString}; #[derive(Debug, Default, strum_macros::Display, EnumIter, Clone, Copy, PartialEq)] pub enum Ticker { - ARKVC, + ARKVX, ARKF, ARKG, #[default] @@ -23,17 +23,27 @@ pub enum Ticker { ARKQ, ARKW, ARKX, + // ARKA, + // ARKZ, + ARKC, + ARKD, + ARKY, } impl Ticker { pub fn value(&self) -> &str { match *self { - Ticker::ARKVC => "ARKVC", + Ticker::ARKVX => "ARKVX", Ticker::ARKF => "FINTECH_INNOVATION", Ticker::ARKG => "GENOMIC_REVOLUTION", Ticker::ARKK => "INNOVATION", Ticker::ARKQ => "AUTONOMOUS_TECH._&_ROBOTICS", Ticker::ARKW => "NEXT_GENERATION_INTERNET", Ticker::ARKX => "SPACE_EXPLORATION_&_INNOVATION", + // Ticker::ARKA => "ARKA", + // Ticker::ARKZ => "ARKZ", + Ticker::ARKC => "ARKC", + Ticker::ARKD => "ARKD", + Ticker::ARKY => "ARKY", } } } @@ -342,7 +352,7 @@ impl Ark { expressions.push( col("ticker") .str() - .replace_all(lit("(?i) fp| uq| un| uw"), lit(""), true) + .replace_all(lit("(?i) fp| uq| un| uw | cn"), lit(""), true) .str() .replace(lit("DKNN"), lit("DKNG"), true) .str() @@ -402,6 +412,18 @@ impl Ark { df = df.select(["date", "ticker", "cusip", "company", "weight"])?; } + // ARKVX + if !df.get_column_names().contains(&"market_value") { + df = df + .lazy() + .with_columns([ + Series::new("market_value", [None::]).lit(), + Series::new("shares", [None::]).lit(), + Series::new("share_price", [None::]).lit(), + ]) + .collect()?; + } + Ok(df.into()) } @@ -411,8 +433,8 @@ impl Ark { source: Option<&Source>, ) -> Result { let url = match (&self.ticker, last_day) { - (self::Ticker::ARKVC, Some(last_day)) => format!( - "https://api.nexveridian.com/arkvc_holdings?start={}", + (self::Ticker::ARKVX, Some(last_day)) => format!( + "https://api.nexveridian.com/ARKVX_holdings?start={}", last_day ), (tic, Some(last_day)) => match source { @@ -425,7 +447,7 @@ impl Ark { tic, last_day ), }, - (self::Ticker::ARKVC, None) => "https://api.nexveridian.com/arkvc_holdings".to_owned(), + (self::Ticker::ARKVX, None) => "https://api.nexveridian.com/ARKVX_holdings".to_owned(), (tic, None) => match source { Some(Source::ArkFundsIoFull) => { format!("https://arkfunds.io/api/v2/etf/holdings?symbol={}", tic) @@ -455,7 +477,9 @@ impl Ark { pub fn get_csv_ark(&self) -> Result { let url = match self.ticker { - self::Ticker::ARKVC => "https://ark-ventures.com/wp-content/uploads/funds-etf-csv/ARK_VENTURE_FUND_HOLDINGS.csv".to_owned(), + self::Ticker::ARKVX => "https://ark-ventures.com/wp-content/uploads/funds-etf-csv/ARK_VENTURE_FUND_HOLDINGS.csv".to_owned(), + // self::Ticker::ARKA | self::Ticker::ARKZ | + self::Ticker::ARKC | self::Ticker::ARKD | self::Ticker::ARKY => format!("https://cdn.21shares-funds.com/uploads/fund-documents/us-bank/holdings/product/current/{}-Export.csv", self.ticker.value()), _ => format!("https://ark-funds.com/wp-content/uploads/funds-etf-csv/ARK_{}_ETF_{}_HOLDINGS.csv", self.ticker.value(), self.ticker), }; Reader::Csv.get_data_url(url) diff --git a/tests/integration.rs b/tests/integration.rs index 342b2dc..9171d39 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,12 +1,12 @@ +use anyhow::{Error, Result}; use ark_invest_api_rust_data::util::*; use chrono::NaiveDate; use polars::datatypes::DataType; use serial_test::serial; -use std::error::Error; #[test] #[serial] -fn get_api_arkk() -> Result<(), Box> { +fn get_api_arkk() -> Result<(), Error> { let df = Ark::new( Source::ApiIncremental, Ticker::ARKK, @@ -36,7 +36,7 @@ fn get_api_arkk() -> Result<(), Box> { #[test] #[serial] -fn get_api_format_arkk() -> Result<(), Box> { +fn get_api_format_arkk() -> Result<(), Error> { let dfl = Ark::new( Source::ApiIncremental, Ticker::ARKK, @@ -76,10 +76,10 @@ fn get_api_format_arkk() -> Result<(), Box> { #[test] #[serial] -fn get_api_format_arkvc() -> Result<(), Box> { +fn get_api_format_arkvx() -> Result<(), Error> { let dfl = Ark::new( Source::ApiIncremental, - Ticker::ARKVC, + Ticker::ARKVX, Some("data/test".to_owned()), )? .get_api(NaiveDate::from_ymd_opt(2023, 1, 1), None)?; @@ -88,13 +88,25 @@ fn get_api_format_arkvc() -> Result<(), Box> { assert_eq!( (df.get_column_names(), df.dtypes(), df.shape().1 > 1), ( - vec!["date", "ticker", "cusip", "company", "weight"], + vec![ + "date", + "ticker", + "cusip", + "company", + "market_value", + "shares", + "share_price", + "weight", + ], vec![ DataType::Date, DataType::Utf8, DataType::Utf8, DataType::Utf8, - DataType::Float64 + DataType::Int64, + DataType::Int64, + DataType::Float64, + DataType::Float64, ], true )