Skip to main content

deribit_http/model/response/
other.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 15/9/25
5******************************************************************************/
6use crate::prelude::*;
7use pretty_simple_display::{DebugPretty, DisplaySimple};
8use serde::{Deserialize, Serialize};
9use serde_with::skip_serializing_none;
10
11/// Trading limit structure
12#[skip_serializing_none]
13#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
14pub struct TradingLimit {
15    /// Total rate limit for trading operations
16    #[serde(default)]
17    pub total: RateLimit,
18}
19
20/// Account limits structure
21#[skip_serializing_none]
22#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
23pub struct AccountLimits {
24    /// Whether limits are applied per currency
25    #[serde(default)]
26    pub limits_per_currency: bool,
27    /// Rate limits for non-matching engine operations
28    #[serde(default)]
29    pub non_matching_engine: RateLimit,
30    /// Rate limits for matching engine operations
31    #[serde(default)]
32    pub matching_engine: MatchingEngineLimit,
33}
34
35/// Rate limit structure
36#[skip_serializing_none]
37#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
38pub struct RateLimit {
39    /// Maximum burst capacity for rate limiting
40    #[serde(default)]
41    pub burst: u32,
42    /// Rate limit per time unit
43    #[serde(default)]
44    pub rate: u32,
45}
46
47/// Matching engine limits
48#[skip_serializing_none]
49#[derive(DebugPretty, DisplaySimple, Clone, Default, Serialize, Deserialize)]
50pub struct MatchingEngineLimit {
51    /// Trading limits configuration
52    #[serde(default)]
53    pub trading: TradingLimit,
54    /// Spot trading rate limits
55    #[serde(default)]
56    pub spot: RateLimit,
57    /// Quote request rate limits
58    #[serde(default)]
59    pub quotes: RateLimit,
60    /// Maximum quotes rate limits
61    #[serde(default)]
62    pub max_quotes: RateLimit,
63    /// Guaranteed quotes rate limits
64    #[serde(default)]
65    pub guaranteed_quotes: RateLimit,
66    /// Cancel all orders rate limits
67    #[serde(default)]
68    pub cancel_all: RateLimit,
69}
70
71/// Response type for user trades, containing a vector of user trade data
72pub type UserTradeResponse = Vec<UserTrade>;
73
74/// Response type for user trades with pagination info (used by instrument-specific endpoints)
75#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
76pub struct UserTradeWithPaginationResponse {
77    /// List of user trades
78    pub trades: Vec<UserTrade>,
79    /// Whether there are more trades available
80    pub has_more: bool,
81}
82
83/// Contract size response
84#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
85pub struct ContractSizeResponse {
86    /// Contract size value
87    pub contract_size: f64,
88}
89
90/// Test response for connectivity checks
91#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
92pub struct TestResponse {
93    /// Version information
94    pub version: String,
95}
96
97/// Status response
98#[skip_serializing_none]
99#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
100pub struct StatusResponse {
101    /// Whether the system is locked (optional)
102    pub locked: Option<bool>,
103    /// Status message (optional)
104    pub message: Option<String>,
105    /// List of locked indices (optional)
106    pub locked_indices: Option<Vec<String>>,
107    /// Additional fields that might be present in the API response
108    #[serde(flatten)]
109    pub additional_fields: std::collections::HashMap<String, serde_json::Value>,
110}
111
112/// APR history response
113#[skip_serializing_none]
114#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
115pub struct AprHistoryResponse {
116    /// List of APR data points
117    pub data: Vec<AprDataPoint>,
118    /// Continuation token for pagination
119    pub continuation: Option<String>,
120}
121
122/// Hello response
123#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
124pub struct HelloResponse {
125    /// Version string
126    pub version: String,
127}
128
129/// Delivery prices response
130#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
131pub struct DeliveryPricesResponse {
132    /// List of delivery price data
133    pub data: Vec<DeliveryPriceData>,
134    /// Total number of records
135    pub records_total: u32,
136}
137
138/// APR data point
139#[skip_serializing_none]
140#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
141pub struct AprDataPoint {
142    /// Annual percentage rate
143    pub apr: f64,
144    /// Timestamp of the data point (optional)
145    pub timestamp: Option<u64>,
146    /// Day of the data point
147    pub day: i32,
148}
149
150/// Expirations response
151#[skip_serializing_none]
152#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
153pub struct ExpirationsResponse {
154    /// Direct future expirations (when currency="any")
155    pub future: Option<Vec<String>>,
156    /// Direct option expirations (when currency="any")
157    pub option: Option<Vec<String>>,
158    /// Map of currency to their expirations (when specific currency)
159    #[serde(flatten)]
160    pub currencies: std::collections::HashMap<String, CurrencyExpirations>,
161}
162
163/// Last trades response
164#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
165pub struct LastTradesResponse {
166    /// Whether there are more trades available
167    pub has_more: bool,
168    /// List of recent trades
169    pub trades: Vec<LastTrade>,
170}
171
172/// Settlements response structure
173#[skip_serializing_none]
174#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
175pub struct SettlementsResponse {
176    /// Continuation token for pagination
177    pub continuation: Option<String>,
178    /// List of settlement events
179    pub settlements: Vec<Settlement>,
180}
181
182impl SettlementsResponse {
183    /// Create a new settlements response
184    pub fn new(settlements: Vec<Settlement>) -> Self {
185        Self {
186            continuation: None,
187            settlements,
188        }
189    }
190
191    /// Create settlements response with continuation token
192    pub fn with_continuation(
193        settlements: Vec<crate::model::settlement::Settlement>,
194        continuation: String,
195    ) -> Self {
196        Self {
197            continuation: Some(continuation),
198            settlements,
199        }
200    }
201
202    /// Check if there are more results
203    pub fn has_more(&self) -> bool {
204        self.continuation.is_some()
205    }
206}
207
208/// Paginated transaction log response
209#[skip_serializing_none]
210#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize, Default)]
211pub struct TransactionLogResponse {
212    /// Continuation token for pagination. NULL when no continuation.
213    pub continuation: Option<u64>,
214    /// List of transaction log entries
215    pub logs: Vec<TransactionLogEntry>,
216}
217
218/// Transfer result for order-related transfers (e.g., fee rebates)
219#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
220pub struct TransferResultResponse {
221    /// Transfer identifier
222    pub id: String,
223    /// Transfer status
224    pub status: String,
225}
226
227/// Shared account-level fields returned by both singular and plural account summary endpoints.
228#[skip_serializing_none]
229#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct AccountInfo {
231    /// Account id
232    pub id: u64,
233    /// User email
234    pub email: String,
235    /// System generated user nickname
236    pub system_name: Option<String>,
237    /// Account name (given by user)
238    pub username: Option<String>,
239    /// When Block RFQ Self Match Prevention is enabled
240    pub block_rfq_self_match_prevention: Option<bool>,
241    /// Time at which the account was created (milliseconds since the Unix epoch)
242    pub creation_timestamp: Option<u64>,
243    /// Account type
244    #[serde(rename = "type")]
245    pub account_type: Option<String>,
246    /// Optional identifier of the referrer
247    pub referrer_id: Option<String>,
248    /// Whether account is loginable using email and password
249    pub login_enabled: Option<bool>,
250    /// Whether Security Key authentication is enabled
251    pub security_keys_enabled: Option<bool>,
252    /// Whether MMP is enabled
253    pub mmp_enabled: Option<bool>,
254    /// true when the inter-user transfers are enabled for user
255    pub interuser_transfers_enabled: Option<bool>,
256    /// Self trading rejection behavior - reject_taker or cancel_maker
257    pub self_trading_reject_mode: Option<String>,
258    /// true if self trading rejection behavior is applied to trades between subaccounts
259    pub self_trading_extended_to_subaccounts: Option<bool>,
260}
261
262/// Account summary response containing user account information
263#[skip_serializing_none]
264#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
265pub struct AccountSummaryResponse {
266    /// Account id
267    #[serde(default)]
268    pub id: u64,
269    /// User email
270    #[serde(default)]
271    pub email: String,
272    /// System generated user nickname
273    #[serde(default)]
274    pub system_name: String,
275    /// Account name (given by user)
276    #[serde(default)]
277    pub username: String,
278    /// When Block RFQ Self Match Prevention is enabled
279    #[serde(default)]
280    pub block_rfq_self_match_prevention: bool,
281    /// Time at which the account was created (milliseconds since the Unix epoch)
282    #[serde(default)]
283    pub creation_timestamp: u64,
284    /// Account type
285    #[serde(rename = "type", default)]
286    pub account_type: String,
287    /// Optional identifier of the referrer
288    pub referrer_id: Option<String>,
289    /// Whether account is loginable using email and password
290    #[serde(default)]
291    pub login_enabled: bool,
292    /// Whether Security Key authentication is enabled
293    #[serde(default)]
294    pub security_keys_enabled: bool,
295    /// Whether MMP is enabled
296    #[serde(default)]
297    pub mmp_enabled: bool,
298    /// true when the inter-user transfers are enabled for user
299    #[serde(default)]
300    pub interuser_transfers_enabled: bool,
301    /// Self trading rejection behavior - reject_taker or cancel_maker
302    #[serde(default)]
303    pub self_trading_reject_mode: String,
304    /// true if self trading rejection behavior is applied to trades between subaccounts
305    #[serde(default)]
306    pub self_trading_extended_to_subaccounts: bool,
307    /// Aggregated list of per-currency account summaries
308    #[serde(default)]
309    pub summaries: Vec<AccountResult>,
310}
311
312/// Response from `get_account_summaries` (plural, all currencies).
313///
314/// Returns account-level fields with a `summaries` array containing
315/// per-currency financial data.
316#[skip_serializing_none]
317#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
318pub struct AccountSummariesResponse {
319    /// Account-level fields (id, email, type, etc.)
320    #[serde(flatten)]
321    pub account: AccountInfo,
322    /// Per-currency account summaries
323    pub summaries: Vec<AccountResult>,
324}
325
326/// Mark price history data point
327///
328/// Represents a single data point in mark price history.
329/// The API returns data as `[timestamp_ms, mark_price]` arrays.
330#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
331#[serde(from = "(u64, f64)", into = "(u64, f64)")]
332pub struct MarkPriceHistoryPoint {
333    /// Timestamp in milliseconds since Unix epoch
334    pub timestamp: u64,
335    /// Mark price value
336    pub mark_price: f64,
337}
338
339impl From<(u64, f64)> for MarkPriceHistoryPoint {
340    fn from((timestamp, mark_price): (u64, f64)) -> Self {
341        Self {
342            timestamp,
343            mark_price,
344        }
345    }
346}
347
348impl From<MarkPriceHistoryPoint> for (u64, f64) {
349    fn from(point: MarkPriceHistoryPoint) -> Self {
350        (point.timestamp, point.mark_price)
351    }
352}
353
354/// Index name information with extended details
355///
356/// Represents an index with optional combo trading availability flags.
357/// Returned by `get_supported_index_names` when `extended=true`.
358#[skip_serializing_none]
359#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
360pub struct IndexNameInfo {
361    /// Index name identifier (e.g., "btc_eth", "btc_usdc")
362    pub name: String,
363    /// Whether future combo creation is enabled for this index
364    pub future_combo_enabled: Option<bool>,
365    /// Whether option combo creation is enabled for this index
366    pub option_combo_enabled: Option<bool>,
367}
368
369/// Aggregated trade volume by currency
370///
371/// Contains 24-hour trade volumes for different instrument types.
372/// When `extended=true`, also includes 7-day and 30-day volumes.
373#[skip_serializing_none]
374#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
375pub struct TradeVolume {
376    /// Currency (e.g., "BTC", "ETH", "USDC")
377    pub currency: String,
378    /// Total 24h trade volume for call options
379    pub calls_volume: f64,
380    /// Total 24h trade volume for put options
381    pub puts_volume: f64,
382    /// Total 24h trade volume for futures
383    pub futures_volume: f64,
384    /// Total 24h trade volume for spot
385    pub spot_volume: f64,
386    /// Total 7d trade volume for call options (extended only)
387    pub calls_volume_7d: Option<f64>,
388    /// Total 7d trade volume for put options (extended only)
389    pub puts_volume_7d: Option<f64>,
390    /// Total 7d trade volume for futures (extended only)
391    pub futures_volume_7d: Option<f64>,
392    /// Total 7d trade volume for spot (extended only)
393    pub spot_volume_7d: Option<f64>,
394    /// Total 30d trade volume for call options (extended only)
395    pub calls_volume_30d: Option<f64>,
396    /// Total 30d trade volume for put options (extended only)
397    pub puts_volume_30d: Option<f64>,
398    /// Total 30d trade volume for futures (extended only)
399    pub futures_volume_30d: Option<f64>,
400    /// Total 30d trade volume for spot (extended only)
401    pub spot_volume_30d: Option<f64>,
402}
403
404/// A single volatility index candle
405///
406/// Represents OHLC data for a volatility index at a specific timestamp.
407#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
408pub struct VolatilityIndexCandle {
409    /// Timestamp in milliseconds since UNIX epoch
410    pub timestamp: u64,
411    /// Open value
412    pub open: f64,
413    /// High value
414    pub high: f64,
415    /// Low value
416    pub low: f64,
417    /// Close value
418    pub close: f64,
419}
420
421/// Response from get_volatility_index_data
422///
423/// Contains volatility index candles and optional continuation token.
424#[skip_serializing_none]
425#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
426pub struct VolatilityIndexData {
427    /// Candles as OHLC data
428    #[serde(deserialize_with = "deserialize_candles")]
429    pub data: Vec<VolatilityIndexCandle>,
430    /// Continuation token for pagination (use as end_timestamp for next request)
431    pub continuation: Option<u64>,
432}
433
434/// Deserialize candles from array of arrays format
435fn deserialize_candles<'de, D>(deserializer: D) -> Result<Vec<VolatilityIndexCandle>, D::Error>
436where
437    D: serde::Deserializer<'de>,
438{
439    use serde::de::Error;
440    let raw: Vec<Vec<serde_json::Value>> = Vec::deserialize(deserializer)?;
441    let mut candles = Vec::with_capacity(raw.len());
442
443    for arr in raw {
444        if arr.len() != 5 {
445            return Err(D::Error::custom(format!(
446                "expected 5 elements in candle array, got {}",
447                arr.len()
448            )));
449        }
450        let timestamp = arr[0]
451            .as_u64()
452            .ok_or_else(|| D::Error::custom("invalid timestamp"))?;
453        let open = arr[1]
454            .as_f64()
455            .ok_or_else(|| D::Error::custom("invalid open"))?;
456        let high = arr[2]
457            .as_f64()
458            .ok_or_else(|| D::Error::custom("invalid high"))?;
459        let low = arr[3]
460            .as_f64()
461            .ok_or_else(|| D::Error::custom("invalid low"))?;
462        let close = arr[4]
463            .as_f64()
464            .ok_or_else(|| D::Error::custom("invalid close"))?;
465
466        candles.push(VolatilityIndexCandle {
467            timestamp,
468            open,
469            high,
470            low,
471            close,
472        });
473    }
474
475    Ok(candles)
476}
477
478/// Account summary information
479#[skip_serializing_none]
480#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
481pub struct AccountResult {
482    /// Currency of the summary
483    #[serde(default)]
484    pub currency: String,
485    /// The account's balance
486    pub balance: f64,
487    /// The account's current equity
488    pub equity: f64,
489    /// The account's available funds
490    pub available_funds: f64,
491    /// The account's margin balance
492    pub margin_balance: f64,
493    /// Profit and loss
494    pub total_pl: Option<f64>,
495    /// Session realized profit and loss
496    pub session_rpl: Option<f64>,
497    /// Session unrealized profit and loss
498    pub session_upl: Option<f64>,
499    /// The maintenance margin
500    pub maintenance_margin: f64,
501    /// The account's initial margin
502    pub initial_margin: f64,
503    /// The account's available to withdrawal funds
504    pub available_withdrawal_funds: Option<f64>,
505    /// When true cross collateral is enabled for user
506    pub cross_collateral_enabled: Option<bool>,
507    /// The sum of position deltas
508    pub delta_total: Option<f64>,
509    /// Futures profit and Loss
510    pub futures_pl: Option<f64>,
511    /// Futures session realized profit and Loss
512    pub futures_session_rpl: Option<f64>,
513    /// Futures session unrealized profit and Loss
514    pub futures_session_upl: Option<f64>,
515    /// Options summary delta
516    pub options_delta: Option<f64>,
517    /// Options summary gamma
518    pub options_gamma: Option<f64>,
519    /// Options profit and Loss
520    pub options_pl: Option<f64>,
521    /// Options session realized profit and Loss
522    pub options_session_rpl: Option<f64>,
523    /// Options session unrealized profit and Loss
524    pub options_session_upl: Option<f64>,
525    /// Options summary theta
526    pub options_theta: Option<f64>,
527    /// Options summary vega
528    pub options_vega: Option<f64>,
529    /// true when portfolio margining is enabled for user
530    pub portfolio_margining_enabled: Option<bool>,
531    /// The sum of position deltas without positions that will expire during closest expiration
532    pub projected_delta_total: Option<f64>,
533    /// Projected initial margin
534    pub projected_initial_margin: Option<f64>,
535    /// Projected maintenance margin
536    pub projected_maintenance_margin: Option<f64>,
537    /// Delta total map (currency -> delta)
538    pub delta_total_map: Option<std::collections::HashMap<String, f64>>,
539    /// The deposit address for the account (if available)
540    pub deposit_address: Option<String>,
541    /// List of fee objects for all currency pairs and instrument types
542    pub fees: Option<Vec<FeeStructure>>,
543    /// Account limits structure
544    pub limits: Option<AccountLimits>,
545    /// Name of user's currently enabled margin model
546    pub margin_model: Option<String>,
547    /// Map of options' gammas per index
548    pub options_gamma_map: Option<std::collections::HashMap<String, f64>>,
549    /// Map of options' thetas per index
550    pub options_theta_map: Option<std::collections::HashMap<String, f64>>,
551    /// Map of options' vegas per index
552    pub options_vega_map: Option<std::collections::HashMap<String, f64>>,
553    /// Options value
554    pub options_value: Option<f64>,
555    /// The account's balance reserved in active spot orders
556    pub spot_reserve: Option<f64>,
557    /// Estimated Liquidation Ratio
558    pub estimated_liquidation_ratio: Option<f64>,
559    /// Estimated liquidation ratio map
560    pub estimated_liquidation_ratio_map: Option<std::collections::HashMap<String, f64>>,
561    /// The account's fee balance (it can be used to pay for fees)
562    pub fee_balance: Option<f64>,
563    /// The account's balance reserved in other orders
564    pub additional_reserve: Option<f64>,
565
566    // Additional fields for cross-collateral users
567    /// Optional field returned with value true when user has non block chain equity
568    pub has_non_block_chain_equity: Option<bool>,
569    /// The account's total margin balance in all cross collateral currencies, expressed in USD
570    pub total_margin_balance_usd: Option<f64>,
571    /// The account's total delta total in all cross collateral currencies, expressed in USD
572    pub total_delta_total_usd: Option<f64>,
573    /// The account's total initial margin in all cross collateral currencies, expressed in USD
574    pub total_initial_margin_usd: Option<f64>,
575    /// The account's total maintenance margin in all cross collateral currencies, expressed in USD
576    pub total_maintenance_margin_usd: Option<f64>,
577    /// The account's total equity in all cross collateral currencies, expressed in USD
578    pub total_equity_usd: Option<f64>,
579    /// System name for the account
580    pub system_name: Option<String>,
581    /// Account type
582    pub account_type: Option<String>,
583}