1use crate::prelude::*;
7use pretty_simple_display::{DebugPretty, DisplaySimple};
8use serde::{Deserialize, Serialize};
9use serde_with::skip_serializing_none;
10
11#[skip_serializing_none]
13#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
14pub struct TradingLimit {
15 pub total: RateLimit,
17}
18
19#[skip_serializing_none]
21#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
22pub struct AccountLimits {
23 pub limits_per_currency: bool,
25 pub non_matching_engine: RateLimit,
27 pub matching_engine: MatchingEngineLimit,
29}
30
31#[skip_serializing_none]
33#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
34pub struct RateLimit {
35 pub burst: u32,
37 pub rate: u32,
39}
40
41#[skip_serializing_none]
43#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
44pub struct MatchingEngineLimit {
45 pub trading: TradingLimit,
47 pub spot: RateLimit,
49 pub quotes: RateLimit,
51 pub max_quotes: RateLimit,
53 pub guaranteed_quotes: RateLimit,
55 pub cancel_all: RateLimit,
57}
58
59pub type UserTradeResponse = Vec<UserTrade>;
61
62#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
64pub struct UserTradeWithPaginationResponse {
65 pub trades: Vec<UserTrade>,
67 pub has_more: bool,
69}
70
71#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
73pub struct ContractSizeResponse {
74 pub contract_size: f64,
76}
77
78#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
80pub struct TestResponse {
81 pub version: String,
83}
84
85#[skip_serializing_none]
87#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
88pub struct StatusResponse {
89 pub locked: Option<bool>,
91 pub message: Option<String>,
93 pub locked_indices: Option<Vec<String>>,
95 #[serde(flatten)]
97 pub additional_fields: std::collections::HashMap<String, serde_json::Value>,
98}
99
100#[skip_serializing_none]
102#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
103pub struct AprHistoryResponse {
104 pub data: Vec<AprDataPoint>,
106 pub continuation: Option<String>,
108}
109
110#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
112pub struct HelloResponse {
113 pub version: String,
115}
116
117#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
119pub struct DeliveryPricesResponse {
120 pub data: Vec<DeliveryPriceData>,
122 pub records_total: u32,
124}
125
126#[skip_serializing_none]
128#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
129pub struct AprDataPoint {
130 pub apr: f64,
132 pub timestamp: Option<u64>,
134 pub day: i32,
136}
137
138#[skip_serializing_none]
140#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
141pub struct ExpirationsResponse {
142 pub future: Option<Vec<String>>,
144 pub option: Option<Vec<String>>,
146 #[serde(flatten)]
148 pub currencies: std::collections::HashMap<String, CurrencyExpirations>,
149}
150
151#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
153pub struct LastTradesResponse {
154 pub has_more: bool,
156 pub trades: Vec<LastTrade>,
158}
159
160#[skip_serializing_none]
162#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
163pub struct SettlementsResponse {
164 pub continuation: Option<String>,
166 pub settlements: Vec<Settlement>,
168}
169
170impl SettlementsResponse {
171 pub fn new(settlements: Vec<Settlement>) -> Self {
173 Self {
174 continuation: None,
175 settlements,
176 }
177 }
178
179 pub fn with_continuation(
181 settlements: Vec<crate::model::settlement::Settlement>,
182 continuation: String,
183 ) -> Self {
184 Self {
185 continuation: Some(continuation),
186 settlements,
187 }
188 }
189
190 pub fn has_more(&self) -> bool {
192 self.continuation.is_some()
193 }
194}
195
196#[skip_serializing_none]
198#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize, Default)]
199pub struct TransactionLogResponse {
200 pub continuation: Option<u64>,
202 pub logs: Vec<TransactionLogEntry>,
204}
205
206#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
208pub struct TransferResultResponse {
209 pub id: String,
211 pub status: String,
213}
214
215#[skip_serializing_none]
217#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
218pub struct AccountSummaryResponse {
219 pub id: u64,
221 pub email: String,
223 pub system_name: String,
225 pub username: String,
227 pub block_rfq_self_match_prevention: bool,
229 pub creation_timestamp: u64,
231 #[serde(rename = "type")]
233 pub account_type: String,
234 pub referrer_id: Option<String>,
236 pub login_enabled: bool,
238 pub security_keys_enabled: bool,
240 pub mmp_enabled: bool,
242 pub interuser_transfers_enabled: bool,
244 pub self_trading_reject_mode: String,
246 pub self_trading_extended_to_subaccounts: bool,
248 pub summaries: Vec<AccountResult>,
250}
251
252#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
257#[serde(from = "(u64, f64)", into = "(u64, f64)")]
258pub struct MarkPriceHistoryPoint {
259 pub timestamp: u64,
261 pub mark_price: f64,
263}
264
265impl From<(u64, f64)> for MarkPriceHistoryPoint {
266 fn from((timestamp, mark_price): (u64, f64)) -> Self {
267 Self {
268 timestamp,
269 mark_price,
270 }
271 }
272}
273
274impl From<MarkPriceHistoryPoint> for (u64, f64) {
275 fn from(point: MarkPriceHistoryPoint) -> Self {
276 (point.timestamp, point.mark_price)
277 }
278}
279
280#[skip_serializing_none]
285#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
286pub struct IndexNameInfo {
287 pub name: String,
289 pub future_combo_enabled: Option<bool>,
291 pub option_combo_enabled: Option<bool>,
293}
294
295#[skip_serializing_none]
300#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
301pub struct TradeVolume {
302 pub currency: String,
304 pub calls_volume: f64,
306 pub puts_volume: f64,
308 pub futures_volume: f64,
310 pub spot_volume: f64,
312 pub calls_volume_7d: Option<f64>,
314 pub puts_volume_7d: Option<f64>,
316 pub futures_volume_7d: Option<f64>,
318 pub spot_volume_7d: Option<f64>,
320 pub calls_volume_30d: Option<f64>,
322 pub puts_volume_30d: Option<f64>,
324 pub futures_volume_30d: Option<f64>,
326 pub spot_volume_30d: Option<f64>,
328}
329
330#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
334pub struct VolatilityIndexCandle {
335 pub timestamp: u64,
337 pub open: f64,
339 pub high: f64,
341 pub low: f64,
343 pub close: f64,
345}
346
347#[skip_serializing_none]
351#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
352pub struct VolatilityIndexData {
353 #[serde(deserialize_with = "deserialize_candles")]
355 pub data: Vec<VolatilityIndexCandle>,
356 pub continuation: Option<u64>,
358}
359
360fn deserialize_candles<'de, D>(deserializer: D) -> Result<Vec<VolatilityIndexCandle>, D::Error>
362where
363 D: serde::Deserializer<'de>,
364{
365 use serde::de::Error;
366 let raw: Vec<Vec<serde_json::Value>> = Vec::deserialize(deserializer)?;
367 let mut candles = Vec::with_capacity(raw.len());
368
369 for arr in raw {
370 if arr.len() != 5 {
371 return Err(D::Error::custom(format!(
372 "expected 5 elements in candle array, got {}",
373 arr.len()
374 )));
375 }
376 let timestamp = arr[0]
377 .as_u64()
378 .ok_or_else(|| D::Error::custom("invalid timestamp"))?;
379 let open = arr[1]
380 .as_f64()
381 .ok_or_else(|| D::Error::custom("invalid open"))?;
382 let high = arr[2]
383 .as_f64()
384 .ok_or_else(|| D::Error::custom("invalid high"))?;
385 let low = arr[3]
386 .as_f64()
387 .ok_or_else(|| D::Error::custom("invalid low"))?;
388 let close = arr[4]
389 .as_f64()
390 .ok_or_else(|| D::Error::custom("invalid close"))?;
391
392 candles.push(VolatilityIndexCandle {
393 timestamp,
394 open,
395 high,
396 low,
397 close,
398 });
399 }
400
401 Ok(candles)
402}
403
404#[skip_serializing_none]
406#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
407pub struct AccountResult {
408 pub currency: String,
410 pub balance: f64,
412 pub equity: f64,
414 pub available_funds: f64,
416 pub margin_balance: f64,
418 pub total_pl: Option<f64>,
420 pub session_rpl: Option<f64>,
422 pub session_upl: Option<f64>,
424 pub maintenance_margin: f64,
426 pub initial_margin: f64,
428 pub available_withdrawal_funds: Option<f64>,
430 pub cross_collateral_enabled: Option<bool>,
432 pub delta_total: Option<f64>,
434 pub futures_pl: Option<f64>,
436 pub futures_session_rpl: Option<f64>,
438 pub futures_session_upl: Option<f64>,
440 pub options_delta: Option<f64>,
442 pub options_gamma: Option<f64>,
444 pub options_pl: Option<f64>,
446 pub options_session_rpl: Option<f64>,
448 pub options_session_upl: Option<f64>,
450 pub options_theta: Option<f64>,
452 pub options_vega: Option<f64>,
454 pub portfolio_margining_enabled: Option<bool>,
456 pub projected_delta_total: Option<f64>,
458 pub projected_initial_margin: Option<f64>,
460 pub projected_maintenance_margin: Option<f64>,
462 pub delta_total_map: Option<std::collections::HashMap<String, f64>>,
464 pub deposit_address: Option<String>,
466 pub fees: Option<Vec<FeeStructure>>,
468 pub limits: Option<AccountLimits>,
470 pub margin_model: Option<String>,
472 pub options_gamma_map: Option<std::collections::HashMap<String, f64>>,
474 pub options_theta_map: Option<std::collections::HashMap<String, f64>>,
476 pub options_vega_map: Option<std::collections::HashMap<String, f64>>,
478 pub options_value: Option<f64>,
480 pub spot_reserve: Option<f64>,
482 pub estimated_liquidation_ratio: Option<f64>,
484 pub estimated_liquidation_ratio_map: Option<std::collections::HashMap<String, f64>>,
486 pub fee_balance: Option<f64>,
488 pub additional_reserve: Option<f64>,
490
491 pub has_non_block_chain_equity: Option<bool>,
494 pub total_margin_balance_usd: Option<f64>,
496 pub total_delta_total_usd: Option<f64>,
498 pub total_initial_margin_usd: Option<f64>,
500 pub total_maintenance_margin_usd: Option<f64>,
502 pub total_equity_usd: Option<f64>,
504 pub system_name: Option<String>,
506 pub account_type: Option<String>,
508}