use serde_json::Value;
use crate::client::api_request::ApiRequest;
use crate::client::http_client::HttpClient;
use crate::error::TigerError;
const VERSION_V1: &str = "1.0";
const VERSION_V3: &str = "3.0";
pub struct QuoteClient<'a> {
http_client: &'a HttpClient,
}
impl<'a> QuoteClient<'a> {
pub fn new(http_client: &'a HttpClient) -> Self {
Self { http_client }
}
async fn execute(&self, method: &str, params: Value) -> Result<Option<Value>, TigerError> {
let biz_content = serde_json::to_string(¶ms)
.map_err(|e| TigerError::Config(format!("failed to serialize biz params: {}", e)))?;
let req = ApiRequest::new(method, biz_content);
let resp = self.http_client.execute_request(&req).await?;
Ok(resp.data)
}
async fn execute_with_version(&self, method: &str, params: Value, version: &str) -> Result<Option<Value>, TigerError> {
let biz_content = serde_json::to_string(¶ms)
.map_err(|e| TigerError::Config(format!("failed to serialize biz params: {}", e)))?;
let req = ApiRequest::with_version(method, biz_content, version);
let resp = self.http_client.execute_request(&req).await?;
Ok(resp.data)
}
pub async fn market_state(&self, market: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"market": market});
self.execute("market_state", params).await
}
pub async fn get_market_state(&self, market: &str) -> Result<Option<Value>, TigerError> {
self.market_state(market).await
}
pub async fn quote_real_time(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbols": symbols});
self.execute("quote_real_time", params).await
}
pub async fn get_brief(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
self.quote_real_time(symbols).await
}
pub async fn kline(&self, symbol: &str, period: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbols": [symbol], "period": period});
self.execute("kline", params).await
}
pub async fn get_kline(&self, symbol: &str, period: &str) -> Result<Option<Value>, TigerError> {
self.kline(symbol, period).await
}
pub async fn timeline(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbols": symbols});
self.execute_with_version("timeline", params, VERSION_V3).await
}
pub async fn get_timeline(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
self.timeline(symbols).await
}
pub async fn trade_tick(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbols": symbols});
self.execute("trade_tick", params).await
}
pub async fn get_trade_tick(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
self.trade_tick(symbols).await
}
pub async fn quote_depth(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbol": symbol});
self.execute("quote_depth", params).await
}
pub async fn get_quote_depth(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
self.quote_depth(symbol).await
}
pub async fn option_expiration(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbols": [symbol]});
self.execute("option_expiration", params).await
}
pub async fn get_option_expiration(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
self.option_expiration(symbol).await
}
pub async fn option_chain(&self, symbol: &str, expiry: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({
"contracts": [{"symbol": symbol, "expiry": expiry}]
});
self.execute_with_version("option_chain", params, VERSION_V3).await
}
pub async fn get_option_chain(&self, symbol: &str, expiry: &str) -> Result<Option<Value>, TigerError> {
self.option_chain(symbol, expiry).await
}
pub async fn option_brief(&self, identifiers: &[&str]) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"identifiers": identifiers});
self.execute("option_brief", params).await
}
pub async fn get_option_brief(&self, identifiers: &[&str]) -> Result<Option<Value>, TigerError> {
self.option_brief(identifiers).await
}
pub async fn option_kline(&self, identifier: &str, period: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"identifier": identifier, "period": period});
self.execute("option_kline", params).await
}
pub async fn get_option_kline(&self, identifier: &str, period: &str) -> Result<Option<Value>, TigerError> {
self.option_kline(identifier, period).await
}
pub async fn future_exchange(&self) -> Result<Option<Value>, TigerError> {
self.execute("future_exchange", serde_json::json!({"sec_type": "FUT"})).await
}
pub async fn get_future_exchange(&self) -> Result<Option<Value>, TigerError> {
self.future_exchange().await
}
pub async fn future_contracts(&self, exchange: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"exchange": exchange});
self.execute("future_contracts", params).await
}
pub async fn get_future_contracts(&self, exchange: &str) -> Result<Option<Value>, TigerError> {
self.future_contracts(exchange).await
}
pub async fn future_real_time_quote(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbols": symbols});
self.execute("future_real_time_quote", params).await
}
pub async fn get_future_real_time_quote(&self, symbols: &[&str]) -> Result<Option<Value>, TigerError> {
self.future_real_time_quote(symbols).await
}
pub async fn future_kline(&self, symbol: &str, period: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbol": symbol, "period": period});
self.execute("future_kline", params).await
}
pub async fn get_future_kline(&self, symbol: &str, period: &str) -> Result<Option<Value>, TigerError> {
self.future_kline(symbol, period).await
}
pub async fn financial_daily(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbol": symbol});
self.execute("financial_daily", params).await
}
pub async fn get_financial_daily(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
self.financial_daily(symbol).await
}
pub async fn financial_report(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbol": symbol});
self.execute("financial_report", params).await
}
pub async fn get_financial_report(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
self.financial_report(symbol).await
}
pub async fn corporate_action(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbol": symbol});
self.execute("corporate_action", params).await
}
pub async fn get_corporate_action(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
self.corporate_action(symbol).await
}
pub async fn capital_flow(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbol": symbol});
self.execute("capital_flow", params).await
}
pub async fn get_capital_flow(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
self.capital_flow(symbol).await
}
pub async fn capital_distribution(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
let params = serde_json::json!({"symbol": symbol});
self.execute("capital_distribution", params).await
}
pub async fn get_capital_distribution(&self, symbol: &str) -> Result<Option<Value>, TigerError> {
self.capital_distribution(symbol).await
}
pub async fn market_scanner(&self, params: Value) -> Result<Option<Value>, TigerError> {
self.execute_with_version("market_scanner", params, VERSION_V1).await
}
pub async fn grab_quote_permission(&self) -> Result<Option<Value>, TigerError> {
self.execute("grab_quote_permission", serde_json::json!({})).await
}
}
#[cfg(test)]
mod tests;