use chrono::Utc;
use crate::{common::client::Client, market::parameter::{InstrumentsParam, MoversParam, OptionChainParam, PriceHistoryParam, QuotesParam}, utils::json_util};
const MARKET_BASE_URL: &str = "https://api.schwabapi.com/marketdata/v1";
impl Client {
pub async fn quotes(&self, param: QuotesParam) -> anyhow::Result<serde_json::Value> {
let query = json_util::query_params(param)?;
let url = format!("{}/quotes", MARKET_BASE_URL);
self.get_request(&url, &query).await
}
pub async fn single_quote(&self, symbol_id: &str, fields: Option<String>) -> anyhow::Result<serde_json::Value> {
let query = if let Some(v) = fields {
vec![("fields".to_string(), v)]
} else {
vec![("fields".to_string(), "all".to_string())]
};
let url = format!("{}/{}/quotes", MARKET_BASE_URL, symbol_id);
self.get_request(&url, &query).await
}
pub async fn option_chains(&self, param: OptionChainParam)-> anyhow::Result<serde_json::Value> {
let query = json_util::query_params(param)?;
let url = format!("{}/chains", MARKET_BASE_URL);
self.get_request(&url, &query).await
}
pub async fn option_expiration_chain(&self, symbol: &str)-> anyhow::Result<serde_json::Value> {
let query = vec![("symbol".to_string(), symbol.to_string())];
let url = format!("{}/expirationchain", MARKET_BASE_URL);
self.get_request(&url, &query).await
}
pub async fn price_history(&self, param: PriceHistoryParam)-> anyhow::Result<serde_json::Value> {
let query = json_util::query_params(param)?;
let url = format!("{}/pricehistory", MARKET_BASE_URL);
self.get_request(&url, &query).await
}
pub async fn movers(&self, param: MoversParam)-> anyhow::Result<serde_json::Value> {
let symbol_id = param.symbol_id.clone();
let query = json_util::query_params(param)?;
let url = format!("{}/movers/{}", MARKET_BASE_URL, symbol_id);
self.get_request(&url, &query).await
}
pub async fn market_hours(&self, markets: Vec<String>, date: Option<String>)-> anyhow::Result<serde_json::Value> {
if markets.is_empty() {
anyhow::bail!("markets cannot be empty!");
}
let markets_str = markets.join(",");
let mut query = vec![("markets".to_string(), markets_str)];
if let Some(v) = date {
query.push(("date".to_string(), v));
}
let url = format!("{}/markets", MARKET_BASE_URL);
self.get_request(&url, &query).await
}
pub async fn single_market_hours(&self, market_id: &str, date: Option<String>)-> anyhow::Result<serde_json::Value> {
let query = if let Some(v) = date {
vec![("date".to_string(), v)]
} else {
let today = Utc::now().format("%Y-%m-%d").to_string();
vec![("date".to_string(), today)]
};
let url = format!("{}/markets/{}", MARKET_BASE_URL, market_id);
self.get_request(&url, &query).await
}
pub async fn instruments(&self, param: InstrumentsParam)-> anyhow::Result<serde_json::Value> {
let query = json_util::query_params(param)?;
let url = format!("{}/instruments", MARKET_BASE_URL);
self.get_request(&url, &query).await
}
pub async fn single_instrument(&self, cusip_id: &str)-> anyhow::Result<serde_json::Value> {
let url = format!("{}/instruments/{}", MARKET_BASE_URL, cusip_id);
self.get_request(&url, &vec![]).await
}
}