use serde::Serialize;
use crate::error::TigerError;
#[derive(Debug, Clone, Serialize, Default)]
pub struct BriefRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub include_hour_trading: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct SymbolsRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub include_otc: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct TradeMetasRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct StockDetailsRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct DelayedQuoteRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct QuoteDepthRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trade_session: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct KlineRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub right: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trade_session: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub with_fundamental: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct KlineByPageRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_size: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_size: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub right: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trade_session: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct TimelineHistoryRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub right: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trade_session: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct TradeTickRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trade_session: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct TradeRankRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct ShortInterestRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct StockBrokerRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct StockFundamentalRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct StockIndustryRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sec_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct QuotePermissionRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct KlineQuotaRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub with_details: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionQueryItem {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expiry: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub strike: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub right: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_token: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct OptionChainItem {
pub symbol: String,
pub expiry: i64,
}
impl OptionChainItem {
pub fn new(symbol: impl Into<String>, expiry: i64) -> Self {
Self { symbol: symbol.into(), expiry }
}
pub fn from_date(symbol: impl Into<String>, date: &str) -> Result<Self, TigerError> {
let symbol = symbol.into();
let tz = infer_option_timezone(&symbol);
let expiry = date_to_expiry_ms(date, tz)?;
Ok(Self { symbol, expiry })
}
pub fn from_date_tz(symbol: impl Into<String>, date: &str, timezone: &str) -> Result<Self, TigerError> {
let symbol = symbol.into();
let expiry = date_to_expiry_ms(date, timezone)?;
Ok(Self { symbol, expiry })
}
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionChainRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub option_basic: Option<Vec<OptionChainItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
impl OptionChainRequest {
pub fn new(items: Vec<OptionChainItem>) -> Self {
Self { option_basic: Some(items), market: None, lang: None }
}
}
#[derive(Debug, Clone, Serialize)]
pub struct OptionContractItem {
pub symbol: String,
pub expiry: i64,
pub right: String,
pub strike: String,
}
impl OptionContractItem {
pub fn new(symbol: impl Into<String>, expiry: i64, right: impl Into<String>, strike: impl Into<String>) -> Self {
Self { symbol: symbol.into(), expiry, right: right.into(), strike: strike.into() }
}
pub fn from_occ(identifier: &str) -> Result<Self, TigerError> {
let c = parse_occ_identifier(identifier)?;
let tz = infer_option_timezone(&c.symbol);
let expiry = date_to_expiry_ms(&c.expiry_date, tz)?;
Ok(Self { symbol: c.symbol, expiry, right: c.right, strike: c.strike })
}
pub fn from_occ_tz(identifier: &str, timezone: &str) -> Result<Self, TigerError> {
let c = parse_occ_identifier(identifier)?;
let expiry = date_to_expiry_ms(&c.expiry_date, timezone)?;
Ok(Self { symbol: c.symbol, expiry, right: c.right, strike: c.strike })
}
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionQuoteRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub option_basic: Option<Vec<OptionContractItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
impl OptionQuoteRequest {
pub fn new(items: Vec<OptionContractItem>) -> Self {
Self { option_basic: Some(items), market: None, lang: None }
}
}
#[derive(Debug, Clone, Serialize)]
pub struct OptionKlineItem {
pub symbol: String,
pub expiry: i64,
pub right: String,
pub strike: String,
pub period: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
}
impl OptionKlineItem {
pub fn new(symbol: impl Into<String>, expiry: i64, right: impl Into<String>, strike: impl Into<String>, period: impl Into<String>) -> Self {
Self { symbol: symbol.into(), expiry, right: right.into(), strike: strike.into(), period: period.into(), begin_time: None, end_time: None, limit: None }
}
pub fn from_occ(identifier: &str, period: impl Into<String>) -> Result<Self, TigerError> {
let c = parse_occ_identifier(identifier)?;
let tz = infer_option_timezone(&c.symbol);
let expiry = date_to_expiry_ms(&c.expiry_date, tz)?;
Ok(Self { symbol: c.symbol, expiry, right: c.right, strike: c.strike, period: period.into(), begin_time: None, end_time: None, limit: None })
}
pub fn from_occ_tz(identifier: &str, period: impl Into<String>, timezone: &str) -> Result<Self, TigerError> {
let c = parse_occ_identifier(identifier)?;
let expiry = date_to_expiry_ms(&c.expiry_date, timezone)?;
Ok(Self { symbol: c.symbol, expiry, right: c.right, strike: c.strike, period: period.into(), begin_time: None, end_time: None, limit: None })
}
}
pub(crate) fn infer_option_timezone(symbol: &str) -> &'static str {
if symbol.chars().all(|c| c.is_ascii_digit()) || symbol.ends_with(".HK") {
return "Asia/Hong_Kong";
}
if symbol.chars().all(|c| c.is_ascii_alphabetic()) {
return "America/New_York";
}
"Asia/Shanghai"
}
pub(crate) fn date_to_expiry_ms(date: &str, timezone: &str) -> Result<i64, TigerError> {
use chrono::NaiveDate;
use chrono_tz::Tz;
let tz: Tz = timezone.parse().map_err(|_| {
TigerError::Config(format!("unknown timezone: {:?}", timezone))
})?;
let d = NaiveDate::parse_from_str(date, "%Y-%m-%d").map_err(|e| {
TigerError::Config(format!("invalid date {:?}: expected YYYY-MM-DD: {}", date, e))
})?;
let dt = d.and_hms_opt(0, 0, 0).unwrap();
let zdt = dt.and_local_timezone(tz).earliest().ok_or_else(|| {
TigerError::Config(format!("ambiguous or invalid local time for date {:?} in tz {:?}", date, timezone))
})?;
Ok(zdt.timestamp_millis())
}
struct OccContract {
symbol: String,
expiry_date: String, right: String,
strike: String,
}
fn parse_occ_identifier(identifier: &str) -> Result<OccContract, TigerError> {
let trimmed = identifier.trim();
let (symbol, rest) = if trimmed.contains(' ') {
let mut parts = trimmed.splitn(2, ' ');
let sym = parts.next().filter(|s| !s.is_empty())
.ok_or_else(|| TigerError::Config(format!("invalid OCC identifier: {:?}", identifier)))?
.to_string();
let rest = parts.next()
.ok_or_else(|| TigerError::Config(format!("invalid OCC identifier (missing suffix): {:?}", identifier)))?
.trim_start(); (sym, rest.to_string())
} else {
if !trimmed.is_ascii() {
return Err(TigerError::Config(format!("invalid OCC identifier (non-ASCII characters not supported): {:?}", identifier)));
}
if trimmed.len() < 15 {
return Err(TigerError::Config(format!("invalid OCC identifier (too short): {:?}", identifier)));
}
let suffix_start = trimmed.len() - 15;
let sym = trimmed[..suffix_start].to_string();
let rest = trimmed[suffix_start..].to_string();
(sym, rest)
};
if symbol.is_empty() {
return Err(TigerError::Config(format!("invalid OCC identifier (empty symbol): {:?}", identifier)));
}
if rest.len() < 15 {
return Err(TigerError::Config(format!("invalid OCC identifier (suffix too short): {:?}", identifier)));
}
let date_part = &rest[..6];
let right_char = &rest[6..7];
let strike_raw = &rest[7..];
let year = 2000 + date_part[..2].parse::<i32>().map_err(|_| TigerError::Config(format!("invalid OCC date: {:?}", identifier)))?;
let month = date_part[2..4].parse::<u32>().map_err(|_| TigerError::Config(format!("invalid OCC date: {:?}", identifier)))?;
let day = date_part[4..6].parse::<u32>().map_err(|_| TigerError::Config(format!("invalid OCC date: {:?}", identifier)))?;
let expiry_date = format!("{:04}-{:02}-{:02}", year, month, day);
let right = match right_char {
"C" => "CALL".to_string(),
"P" => "PUT".to_string(),
_ => return Err(TigerError::Config(format!("invalid OCC right {:?}: {:?}", right_char, identifier))),
};
let strike_int: u64 = strike_raw.parse().map_err(|_| TigerError::Config(format!("invalid OCC strike: {:?}", identifier)))?;
let strike = occ_strike_to_string(strike_int);
Ok(OccContract { symbol, expiry_date, right, strike })
}
fn occ_strike_to_string(strike_int: u64) -> String {
let int_part = strike_int / 1000;
let frac_part = strike_int % 1000;
if frac_part == 0 {
format!("{}.0", int_part)
} else if frac_part % 100 == 0 {
format!("{}.{}", int_part, frac_part / 100)
} else if frac_part % 10 == 0 {
format!("{}.{:02}", int_part, frac_part / 10)
} else {
format!("{}.{:03}", int_part, frac_part)
}
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionKlineRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub option_query: Option<Vec<OptionKlineItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionTradeTicksRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contracts: Option<Vec<OptionQueryItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionTimelineRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub option_query: Option<Vec<OptionQueryItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionDepthRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub option_basic: Option<Vec<OptionQueryItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionSymbolsRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct OptionAnalysisSymbol {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<String>,
}
impl OptionAnalysisSymbol {
pub fn new(symbol: impl Into<String>) -> Self {
Self { symbol: symbol.into(), period: None }
}
pub fn with_period(symbol: impl Into<String>, period: impl Into<String>) -> Self {
Self { symbol: symbol.into(), period: Some(period.into()) }
}
}
#[derive(Debug, Clone, Default)]
pub struct OptionAnalysisRequest {
pub symbols: Option<Vec<String>>,
pub symbol_items: Option<Vec<OptionAnalysisSymbol>>,
pub market: Option<String>,
pub period: Option<String>,
pub require_volatility_list: Option<bool>,
pub lang: Option<String>,
}
impl serde::Serialize for OptionAnalysisRequest {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap;
let mut map = serializer.serialize_map(None)?;
if let Some(ref items) = self.symbol_items {
map.serialize_entry("symbols", items)?;
} else if let Some(ref syms) = self.symbols {
map.serialize_entry("symbols", syms)?;
}
if let Some(ref v) = self.market { map.serialize_entry("market", v)?; }
if let Some(ref v) = self.period { map.serialize_entry("period", v)?; }
if let Some(v) = self.require_volatility_list { map.serialize_entry("require_volatility_list", &v)?; }
if let Some(ref v) = self.lang { map.serialize_entry("lang", v)?; }
map.end()
}
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureRealTimeQuoteRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_codes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureContractSingleRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_code: Option<String>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub contract_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct AllFutureContractsRequest {
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub contract_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exchange: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureContinuousContractsRequest {
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub contract_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureHistoryMainContractRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_codes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureKlineRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_codes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureKlineByPageRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub period: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_size: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_size: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureTradeTicksRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_index: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureDepthRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_codes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FutureTradingTimesRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trading_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FundSymbolsRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FundContractsRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FundQuoteRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FundHistoryQuoteRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct WarrantQuoteRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct WarrantFilterRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_size: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_field_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_dir: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub issuer_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expire_ym: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct IndustryListRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub industry_level: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct IndustryStocksRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub industry_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FinancialCurrencyRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct FinancialExchangeRateRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_list: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timezone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct TradingCalendarRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub begin_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_date: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct MarketScannerTagsRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub market: Option<String>,
#[serde(rename = "multi_tag_field_list", skip_serializing_if = "Option::is_none")]
pub multi_tags_fields: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct QuoteOvernightRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub symbols: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lang: Option<String>,
}