use crate::prelude::*;
use pretty_simple_display::{DebugPretty, DisplaySimple};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
pub struct TradingLimit {
#[serde(default)]
pub total: RateLimit,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
pub struct AccountLimits {
#[serde(default)]
pub limits_per_currency: bool,
#[serde(default)]
pub non_matching_engine: RateLimit,
#[serde(default)]
pub matching_engine: MatchingEngineLimit,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
pub struct RateLimit {
#[serde(default)]
pub burst: u32,
#[serde(default)]
pub rate: u32,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
pub struct MatchingEngineLimit {
#[serde(default)]
pub trading: TradingLimit,
#[serde(default)]
pub spot: RateLimit,
#[serde(default)]
pub quotes: RateLimit,
#[serde(default)]
pub max_quotes: RateLimit,
#[serde(default)]
pub guaranteed_quotes: RateLimit,
#[serde(default)]
pub cancel_all: RateLimit,
}
pub type UserTradeResponse = Vec<UserTrade>;
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct UserTradeWithPaginationResponse {
pub trades: Vec<UserTrade>,
pub has_more: bool,
}
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct ContractSizeResponse {
pub contract_size: f64,
}
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct TestResponse {
pub version: String,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct StatusResponse {
pub locked: Option<bool>,
pub message: Option<String>,
pub locked_indices: Option<Vec<String>>,
#[serde(flatten)]
pub additional_fields: std::collections::HashMap<String, serde_json::Value>,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct AprHistoryResponse {
pub data: Vec<AprDataPoint>,
pub continuation: Option<String>,
}
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct HelloResponse {
pub version: String,
}
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct DeliveryPricesResponse {
pub data: Vec<DeliveryPriceData>,
pub records_total: u32,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct AprDataPoint {
pub apr: f64,
pub timestamp: Option<u64>,
pub day: i32,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct ExpirationsResponse {
pub future: Option<Vec<String>>,
pub option: Option<Vec<String>>,
#[serde(flatten)]
pub currencies: std::collections::HashMap<String, CurrencyExpirations>,
}
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct LastTradesResponse {
pub has_more: bool,
pub trades: Vec<LastTrade>,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct SettlementsResponse {
pub continuation: Option<String>,
pub settlements: Vec<Settlement>,
}
impl SettlementsResponse {
pub fn new(settlements: Vec<Settlement>) -> Self {
Self {
continuation: None,
settlements,
}
}
pub fn with_continuation(
settlements: Vec<crate::model::settlement::Settlement>,
continuation: String,
) -> Self {
Self {
continuation: Some(continuation),
settlements,
}
}
pub fn has_more(&self) -> bool {
self.continuation.is_some()
}
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize, Default)]
pub struct TransactionLogResponse {
pub continuation: Option<u64>,
pub logs: Vec<TransactionLogEntry>,
}
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct TransferResultResponse {
pub id: String,
pub status: String,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccountInfo {
pub id: u64,
pub email: String,
pub system_name: Option<String>,
pub username: Option<String>,
pub block_rfq_self_match_prevention: Option<bool>,
pub creation_timestamp: Option<u64>,
#[serde(rename = "type")]
pub account_type: Option<String>,
pub referrer_id: Option<String>,
pub login_enabled: Option<bool>,
pub security_keys_enabled: Option<bool>,
pub mmp_enabled: Option<bool>,
pub interuser_transfers_enabled: Option<bool>,
pub self_trading_reject_mode: Option<String>,
pub self_trading_extended_to_subaccounts: Option<bool>,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct AccountSummaryResponse {
#[serde(default)]
pub id: u64,
#[serde(default)]
pub email: String,
#[serde(default)]
pub system_name: String,
#[serde(default)]
pub username: String,
#[serde(default)]
pub block_rfq_self_match_prevention: bool,
#[serde(default)]
pub creation_timestamp: u64,
#[serde(rename = "type", default)]
pub account_type: String,
pub referrer_id: Option<String>,
#[serde(default)]
pub login_enabled: bool,
#[serde(default)]
pub security_keys_enabled: bool,
#[serde(default)]
pub mmp_enabled: bool,
#[serde(default)]
pub interuser_transfers_enabled: bool,
#[serde(default)]
pub self_trading_reject_mode: String,
#[serde(default)]
pub self_trading_extended_to_subaccounts: bool,
#[serde(default)]
pub summaries: Vec<AccountResult>,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct AccountSummariesResponse {
#[serde(flatten)]
pub account: AccountInfo,
pub summaries: Vec<AccountResult>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(from = "(u64, f64)", into = "(u64, f64)")]
pub struct MarkPriceHistoryPoint {
pub timestamp: u64,
pub mark_price: f64,
}
impl From<(u64, f64)> for MarkPriceHistoryPoint {
fn from((timestamp, mark_price): (u64, f64)) -> Self {
Self {
timestamp,
mark_price,
}
}
}
impl From<MarkPriceHistoryPoint> for (u64, f64) {
fn from(point: MarkPriceHistoryPoint) -> Self {
(point.timestamp, point.mark_price)
}
}
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IndexNameInfo {
pub name: String,
pub future_combo_enabled: Option<bool>,
pub option_combo_enabled: Option<bool>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TradeVolume {
pub currency: String,
pub calls_volume: f64,
pub puts_volume: f64,
pub futures_volume: f64,
pub spot_volume: f64,
pub calls_volume_7d: Option<f64>,
pub puts_volume_7d: Option<f64>,
pub futures_volume_7d: Option<f64>,
pub spot_volume_7d: Option<f64>,
pub calls_volume_30d: Option<f64>,
pub puts_volume_30d: Option<f64>,
pub futures_volume_30d: Option<f64>,
pub spot_volume_30d: Option<f64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VolatilityIndexCandle {
pub timestamp: u64,
pub open: f64,
pub high: f64,
pub low: f64,
pub close: f64,
}
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VolatilityIndexData {
#[serde(deserialize_with = "deserialize_candles")]
pub data: Vec<VolatilityIndexCandle>,
pub continuation: Option<u64>,
}
fn deserialize_candles<'de, D>(deserializer: D) -> Result<Vec<VolatilityIndexCandle>, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
let raw: Vec<Vec<serde_json::Value>> = Vec::deserialize(deserializer)?;
let mut candles = Vec::with_capacity(raw.len());
for arr in raw {
if arr.len() != 5 {
return Err(D::Error::custom(format!(
"expected 5 elements in candle array, got {}",
arr.len()
)));
}
let timestamp = arr[0]
.as_u64()
.ok_or_else(|| D::Error::custom("invalid timestamp"))?;
let open = arr[1]
.as_f64()
.ok_or_else(|| D::Error::custom("invalid open"))?;
let high = arr[2]
.as_f64()
.ok_or_else(|| D::Error::custom("invalid high"))?;
let low = arr[3]
.as_f64()
.ok_or_else(|| D::Error::custom("invalid low"))?;
let close = arr[4]
.as_f64()
.ok_or_else(|| D::Error::custom("invalid close"))?;
candles.push(VolatilityIndexCandle {
timestamp,
open,
high,
low,
close,
});
}
Ok(candles)
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
pub struct AccountResult {
#[serde(default)]
pub currency: String,
pub balance: f64,
pub equity: f64,
pub available_funds: f64,
pub margin_balance: f64,
pub total_pl: Option<f64>,
pub session_rpl: Option<f64>,
pub session_upl: Option<f64>,
pub maintenance_margin: f64,
pub initial_margin: f64,
pub available_withdrawal_funds: Option<f64>,
pub cross_collateral_enabled: Option<bool>,
pub delta_total: Option<f64>,
pub futures_pl: Option<f64>,
pub futures_session_rpl: Option<f64>,
pub futures_session_upl: Option<f64>,
pub options_delta: Option<f64>,
pub options_gamma: Option<f64>,
pub options_pl: Option<f64>,
pub options_session_rpl: Option<f64>,
pub options_session_upl: Option<f64>,
pub options_theta: Option<f64>,
pub options_vega: Option<f64>,
pub portfolio_margining_enabled: Option<bool>,
pub projected_delta_total: Option<f64>,
pub projected_initial_margin: Option<f64>,
pub projected_maintenance_margin: Option<f64>,
pub delta_total_map: Option<std::collections::HashMap<String, f64>>,
pub deposit_address: Option<String>,
pub fees: Option<Vec<FeeStructure>>,
pub limits: Option<AccountLimits>,
pub margin_model: Option<String>,
pub options_gamma_map: Option<std::collections::HashMap<String, f64>>,
pub options_theta_map: Option<std::collections::HashMap<String, f64>>,
pub options_vega_map: Option<std::collections::HashMap<String, f64>>,
pub options_value: Option<f64>,
pub spot_reserve: Option<f64>,
pub estimated_liquidation_ratio: Option<f64>,
pub estimated_liquidation_ratio_map: Option<std::collections::HashMap<String, f64>>,
pub fee_balance: Option<f64>,
pub additional_reserve: Option<f64>,
pub has_non_block_chain_equity: Option<bool>,
pub total_margin_balance_usd: Option<f64>,
pub total_delta_total_usd: Option<f64>,
pub total_initial_margin_usd: Option<f64>,
pub total_maintenance_margin_usd: Option<f64>,
pub total_equity_usd: Option<f64>,
pub system_name: Option<String>,
pub account_type: Option<String>,
}