use crate::download::oauth_client::OAuthClient; use crate::download::requester::DQRequester; use crate::download::requester::DQTimeseriesRequestArgs; use crate::download::timeseries::DQTimeSeriesResponse; use crate::download::timeseries::JPMaQSIndicator; use std::error::Error; const DEFAULT_JPMAQS_METRICS: [&str; 4] = ["value", "grading", "eop_lag", "mop_lag"]; fn ticker_to_expressions(ticker: &str) -> Vec { DEFAULT_JPMAQS_METRICS .iter() .map(|metric| format!("DB(JPMAQS,{},{})", ticker, metric)) .collect::>() } fn construct_expressions(tickers: Vec) -> Vec { tickers .iter() .flat_map(|ticker| ticker_to_expressions(ticker)) .collect() } fn is_jpmaq_expression(expression: &str) -> bool { expression.starts_with("DB(JPMAQS,") && expression.ends_with(")") && expression.split(',').count() == 3 && expression.split(',').nth(0).unwrap() == "DB(JPMAQS" && expression.split(',').nth(2).unwrap().ends_with(")") } fn all_jpmaq_expressions(expressions: Vec) -> bool { expressions .iter() .all(|expression| is_jpmaq_expression(expression)) } #[derive(Debug, Clone)] pub struct JPMaQSDownload { requester: DQRequester, } impl Default for JPMaQSDownload { fn default() -> Self { let requester = DQRequester::default(); JPMaQSDownload { requester } } } impl JPMaQSDownload { pub fn new(client_id: String, client_secret: String) -> Self { let oauth_client = OAuthClient::new(client_id.clone(), client_secret.clone()); let requester = DQRequester::new(oauth_client); JPMaQSDownload { requester } } pub fn check_connection(&mut self) -> Result<(), Box> { self.requester.check_connection() } pub fn get_catalogue(&mut self) -> Result, Box> { let dq_catalogue = self.requester.get_catalogue("JPMAQS", 1000)?; Ok(dq_catalogue.all_instruments) } pub fn get_expressions( &mut self, expressions: Vec, ) -> Result, Box> { let dqts_vec = self.requester.get_timeseries(DQTimeseriesRequestArgs { expressions: expressions, ..Default::default() })?; Ok(dqts_vec) } pub fn get_indicators( &mut self, tickers: Vec, ) -> Result, Box> { let expressions = construct_expressions(tickers); assert!(all_jpmaq_expressions(expressions.clone())); let dqts_vec = self.get_expressions(expressions)?; let indicators = dqts_vec .iter() .flat_map(|dqts| dqts.get_timeseries_by_ticker()) .map(|tsv| JPMaQSIndicator::new(tsv)) .collect::, Box>>()?; Ok(indicators) } }