use rust_decimal::{Decimal, serde::str_option::deserialize as option_decimal};
use serde::{Deserialize, Serialize};
use serde_aux::prelude::{
deserialize_number_from_string as number,
deserialize_option_number_from_string as option_number,
};
use crate::{
ContractType, CopyTrading, CurAuctionPhase, Side, Status, Timestamp,
enums::{Category, Interval},
serde::{empty_string_as_none, string_to_bool},
};
#[derive(Debug, Serialize)]
pub struct GetKLinesParams {
pub category: Category,
pub symbol: String,
pub interval: Interval,
pub start: Option<Timestamp>,
pub end: Option<Timestamp>,
pub limit: Option<u64>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(tag = "category")]
pub enum KLine {
#[serde(rename = "inverse")]
Inverse { symbol: String, list: Vec<KLineRow> },
#[serde(rename = "linear")]
Linear { symbol: String, list: Vec<KLineRow> },
#[serde(rename = "option")]
Option { symbol: String, list: Vec<KLineRow> },
#[serde(rename = "spot")]
Spot { symbol: String, list: Vec<KLineRow> },
}
#[derive(Debug, Deserialize, PartialEq)]
pub struct KLineRow {
#[serde(rename = "startTime", deserialize_with = "number")]
pub start_time: Timestamp,
#[serde(rename = "openPrice")]
pub open_price: Decimal,
#[serde(rename = "highPrice")]
pub high_price: Decimal,
#[serde(rename = "lowPrice")]
pub low_price: Decimal,
#[serde(rename = "closePrice")]
pub close_price: Decimal,
#[serde(rename = "volume")]
pub volume: Decimal,
#[serde(rename = "turnover")]
pub turnover: Decimal,
}
#[derive(Debug, Serialize)]
pub struct GetTickersParams {
pub category: Category,
pub symbol: Option<String>,
pub base_coin: Option<String>,
pub exp_date: Option<String>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(tag = "category")]
pub enum Ticker {
#[serde(rename = "inverse")]
Inverse { list: Vec<LinearInverseTicker> },
#[serde(rename = "linear")]
Linear { list: Vec<LinearInverseTicker> },
#[serde(rename = "option")]
Option { list: Vec<OptionTicker> },
#[serde(rename = "spot")]
Spot { list: Vec<SpotTicker> },
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct LinearInverseTicker {
pub symbol: String,
pub last_price: Decimal,
pub mark_price: Decimal,
pub index_price: Decimal,
pub prev_price24h: Decimal,
pub price24h_pcnt: Decimal,
pub high_price24h: Decimal,
pub low_price24h: Decimal,
pub prev_price1h: Decimal,
pub open_interest: Decimal,
pub open_interest_value: Decimal,
pub turnover24h: Decimal,
pub volume24h: Decimal,
#[serde(default, deserialize_with = "option_decimal")]
pub funding_rate: Option<Decimal>,
#[serde(deserialize_with = "number")]
pub next_funding_time: Timestamp,
#[serde(default, deserialize_with = "option_decimal")]
pub predicted_delivery_price: Option<Decimal>,
#[serde(default, deserialize_with = "option_decimal")]
pub basis_rate: Option<Decimal>,
#[serde(default, deserialize_with = "option_decimal")]
pub basis: Option<Decimal>,
#[serde(default, deserialize_with = "option_decimal")]
pub delivery_fee_rate: Option<Decimal>,
#[serde(deserialize_with = "option_number")]
pub delivery_time: Option<Timestamp>,
pub bid1_price: Decimal,
pub bid1_size: Decimal,
pub ask1_price: Decimal,
pub ask1_size: Decimal,
#[serde(default, deserialize_with = "option_decimal")]
pub pre_open_price: Option<Decimal>,
#[serde(default, deserialize_with = "option_decimal")]
pub pre_qty: Option<Decimal>,
#[serde(default, deserialize_with = "empty_string_as_none")]
pub cur_pre_listing_phase: Option<CurAuctionPhase>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct OptionTicker {
pub symbol: String,
pub bid1_price: Decimal,
pub bid1_size: Decimal,
pub bid1_iv: Decimal,
pub ask1_price: Decimal,
pub ask1_size: Decimal,
pub ask1_iv: Decimal,
pub last_price: Decimal,
pub high_price24h: Decimal,
pub low_price24h: Decimal,
pub mark_price: Decimal,
pub index_price: Decimal,
pub mark_iv: Decimal,
pub underlying_price: Decimal,
pub open_interest: Decimal,
pub turnover24h: Decimal,
pub volume24h: Decimal,
pub total_volume: Decimal,
pub total_turnover: Decimal,
pub delta: Decimal,
pub gamma: Decimal,
pub vega: Decimal,
pub theta: Decimal,
pub predicted_delivery_price: Decimal,
pub change24h: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SpotTicker {
pub symbol: String,
pub bid1_price: Decimal,
pub bid1_size: Decimal,
pub ask1_price: Decimal,
pub ask1_size: Decimal,
pub last_price: Decimal,
pub prev_price24h: Decimal,
pub price24h_pcnt: Decimal,
pub high_price24h: Decimal,
pub low_price24h: Decimal,
pub turnover24h: Decimal,
pub volume24h: Decimal,
#[serde(default, deserialize_with = "option_decimal")]
pub usd_index_price: Option<Decimal>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetTradesParams {
pub category: Category,
pub symbol: Option<String>,
pub base_coin: Option<String>,
pub option_type: Option<u64>,
pub limit: Option<u64>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(tag = "category")]
pub enum Trade {
#[serde(rename = "inverse")]
Inverse { list: Vec<InverseLinearSpotTrade> },
#[serde(rename = "linear")]
Linear { list: Vec<InverseLinearSpotTrade> },
#[serde(rename = "option")]
Option { list: Vec<OptionTrade> },
#[serde(rename = "spot")]
Spot { list: Vec<InverseLinearSpotTrade> },
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct InverseLinearSpotTrade {
pub exec_id: String,
pub symbol: String,
pub price: Decimal,
pub size: Decimal,
pub side: Side,
#[serde(deserialize_with = "number")]
pub time: Timestamp,
pub is_block_trade: bool,
#[serde(rename = "isRPITrade")]
pub is_rpi_trade: bool,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct OptionTrade {
pub exec_id: String,
pub symbol: String,
pub price: Decimal,
pub size: Decimal,
pub side: Side,
#[serde(deserialize_with = "number")]
pub time: Timestamp,
pub is_block_trade: bool,
#[serde(rename = "isRPITrade")]
pub is_rpi_trade: bool,
#[serde(rename = "mP")]
pub mark_price: Decimal,
#[serde(rename = "iP")]
pub index_price: Decimal,
#[serde(rename = "mIv")]
pub mark_iv: Decimal,
#[serde(rename = "iv")]
pub iv: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ServerTime {
#[serde(deserialize_with = "number")]
pub time_second: u64,
#[serde(deserialize_with = "number")]
pub time_nano: u64,
}
#[derive(Debug, Serialize)]
pub struct GetInstrumentsInfoParams {
pub category: Category,
pub symbol: Option<String>,
pub status: Option<Status>,
pub base_coin: Option<String>,
pub limit: Option<i64>,
pub cursor: Option<String>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(tag = "category")]
pub enum InstrumentsInfo {
#[serde(rename = "inverse", rename_all = "camelCase")]
Inverse {
next_page_cursor: String,
list: Vec<InverseLinearInstrumentsInfo>,
},
#[serde(rename = "linear", rename_all = "camelCase")]
Linear {
next_page_cursor: String,
list: Vec<InverseLinearInstrumentsInfo>,
},
#[serde(rename = "option", rename_all = "camelCase")]
Option {
next_page_cursor: String,
list: Vec<OptionInstrumentsInfo>,
},
#[serde(rename = "spot", rename_all = "camelCase")]
Spot {
#[serde(default, deserialize_with = "empty_string_as_none")]
next_page_cursor: Option<String>,
list: Vec<SpotInstrumentsInfo>,
},
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct InverseLinearInstrumentsInfo {
pub symbol: String,
pub contract_type: ContractType,
pub status: Status,
pub base_coin: String,
pub quote_coin: String,
#[serde(deserialize_with = "number")]
pub launch_time: Timestamp,
#[serde(deserialize_with = "number")]
pub delivery_time: Timestamp,
#[serde(deserialize_with = "option_decimal")]
pub delivery_fee_rate: Option<Decimal>,
#[serde(deserialize_with = "number")]
pub price_scale: i64,
pub leverage_filter: LeverageFilter,
pub price_filter: PriceFilter,
pub lot_size_filter: LotSizeFilter,
pub unified_margin_trade: bool,
pub funding_interval: i64,
pub settle_coin: String,
pub copy_trading: CopyTrading,
pub upper_funding_rate: Decimal,
pub lower_funding_rate: Decimal,
pub risk_parameters: RiskParameters,
pub is_pre_listing: bool,
pub pre_listing_info: Option<PreListingInfo>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct OptionInstrumentsInfo {
pub symbol: String,
pub contract_type: ContractType,
pub status: Status,
pub base_coin: String,
pub quote_coin: String,
#[serde(deserialize_with = "number")]
pub launch_time: i64,
#[serde(deserialize_with = "number")]
pub delivery_time: i64,
#[serde(deserialize_with = "option_decimal")]
pub delivery_fee_rate: Option<Decimal>,
#[serde(deserialize_with = "number")]
pub price_scale: i64,
pub leverage_filter: LeverageFilter,
pub price_filter: PriceFilter,
pub lot_size_filter: LotSizeFilter,
pub unified_margin_trade: bool,
pub funding_interval: i64,
pub settle_coin: String,
pub copy_trading: CopyTrading,
pub upper_funding_rate: Decimal,
pub lower_funding_rate: Decimal,
pub risk_parameters: RiskParameters,
pub is_pre_listing: bool,
pub pre_listing_info: Option<PreListingInfo>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SpotInstrumentsInfo {
pub symbol: String,
pub base_coin: String,
pub quote_coin: String,
#[serde(deserialize_with = "string_to_bool")]
pub innovation: bool,
pub status: Status,
pub margin_trading: String,
#[serde(deserialize_with = "string_to_bool")]
pub st_tag: bool,
pub lot_size_filter: SpotLotSizeFilter,
pub price_filter: SpotPriceFilter,
pub risk_parameters: RiskParameters,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct LeverageFilter {
pub min_leverage: Decimal,
pub max_leverage: Decimal,
pub leverage_step: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PriceFilter {
pub min_price: Decimal,
pub max_price: Decimal,
pub tick_size: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SpotPriceFilter {
pub tick_size: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct LotSizeFilter {
pub min_notional_value: Decimal,
pub max_order_qty: Decimal,
pub max_mkt_order_qty: Decimal,
pub min_order_qty: Decimal,
pub qty_step: Decimal,
pub post_only_max_order_qty: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SpotLotSizeFilter {
pub base_precision: Decimal,
pub quote_precision: Decimal,
pub min_order_qty: Decimal,
pub max_order_qty: Decimal,
pub min_order_amt: Decimal,
pub max_order_amt: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct RiskParameters {
pub price_limit_ratio_x: Decimal,
pub price_limit_ratio_y: Decimal,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PreListingInfo {
pub cur_auction_phase: CurAuctionPhase,
pub phases: Vec<Phase>,
pub auction_fee_info: AuctionFeeInfo,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Phase {
pub phase: CurAuctionPhase,
#[serde(deserialize_with = "option_number")]
pub start_time: Option<Timestamp>,
#[serde(deserialize_with = "option_number")]
pub end_time: Option<Timestamp>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct AuctionFeeInfo {
pub auction_fee_rate: Decimal,
pub taker_fee_rate: Decimal,
pub maker_fee_rate: Decimal,
}