Skip to main content

bybit_rust_api/ws/private/
execution.rs

1//! Execution stream — real-time trade execution updates.
2//!
3//! # Topics
4//! - `execution` (all categories)
5//! - `execution.linear`, `execution.inverse`, `execution.option`
6//! - `execution.fast` (fast execution, lower latency)
7
8use serde::Deserialize;
9
10/// Execution/trade fill data from private WebSocket.
11#[derive(Debug, Clone, Deserialize)]
12pub struct ExecutionData {
13    /// Category: "linear", "inverse", "spot", "option"
14    #[serde(rename = "category")]
15    #[serde(default)]
16    pub category: Option<String>,
17    /// Symbol
18    #[serde(rename = "symbol")]
19    #[serde(default)]
20    pub symbol: Option<String>,
21    /// Execution fee rate
22    #[serde(rename = "execFee")]
23    #[serde(default)]
24    pub exec_fee: Option<String>,
25    /// Execution ID
26    #[serde(rename = "execId")]
27    #[serde(default)]
28    pub exec_id: Option<String>,
29    /// Execution price
30    #[serde(rename = "execPrice")]
31    #[serde(default)]
32    pub exec_price: Option<String>,
33    /// Execution quantity
34    #[serde(rename = "execQty")]
35    #[serde(default)]
36    pub exec_qty: Option<String>,
37    /// Execution type: "Trade", "AdlTrade", "Funding", "BustTrade"
38    #[serde(rename = "execType")]
39    #[serde(default)]
40    pub exec_type: Option<String>,
41    /// Execution value
42    #[serde(rename = "execValue")]
43    #[serde(default)]
44    pub exec_value: Option<String>,
45    /// Fee currency
46    #[serde(rename = "feeCurrency")]
47    #[serde(default)]
48    pub fee_currency: Option<String>,
49    /// Whether the trade is maker (true) or taker (false)
50    #[serde(rename = "isMaker")]
51    #[serde(default)]
52    pub is_maker: Option<bool>,
53    /// Fee rate
54    #[serde(rename = "feeRate")]
55    #[serde(default)]
56    pub fee_rate: Option<String>,
57    /// Trade ID for this execution
58    #[serde(rename = "tradeIv")]
59    #[serde(default)]
60    pub trade_iv: Option<String>,
61    /// Mark price at execution time
62    #[serde(rename = "markIv")]
63    #[serde(default)]
64    pub mark_iv: Option<String>,
65    /// Index price at execution time
66    #[serde(rename = "indexIv")]
67    #[serde(default)]
68    pub index_iv: Option<String>,
69    /// Block trade ID
70    #[serde(rename = "blockTradeId")]
71    #[serde(default)]
72    pub block_trade_id: Option<String>,
73    /// Mark price
74    #[serde(rename = "markPrice")]
75    #[serde(default)]
76    pub mark_price: Option<String>,
77    /// Index price
78    #[serde(rename = "indexPrice")]
79    #[serde(default)]
80    pub index_price: Option<String>,
81    /// Underlying price (options)
82    #[serde(rename = "underlyingPrice")]
83    #[serde(default)]
84    pub underlying_price: Option<String>,
85    /// Order ID
86    #[serde(rename = "orderId")]
87    #[serde(default)]
88    pub order_id: Option<String>,
89    /// Order link ID
90    #[serde(rename = "orderLinkId")]
91    #[serde(default)]
92    pub order_link_id: Option<String>,
93    /// Order price
94    #[serde(rename = "orderPrice")]
95    #[serde(default)]
96    pub order_price: Option<String>,
97    /// Order quantity
98    #[serde(rename = "orderQty")]
99    #[serde(default)]
100    pub order_qty: Option<String>,
101    /// Order type: "Market", "Limit"
102    #[serde(rename = "orderType")]
103    #[serde(default)]
104    pub order_type: Option<String>,
105    /// Stop order type
106    #[serde(rename = "stopOrderType")]
107    #[serde(default)]
108    pub stop_order_type: Option<String>,
109    /// Side: "Buy" or "Sell"
110    #[serde(rename = "side")]
111    #[serde(default)]
112    pub side: Option<String>,
113    /// Execution timestamp
114    #[serde(rename = "execTime")]
115    #[serde(default)]
116    pub exec_time: Option<String>,
117    /// Is leverage token?
118    #[serde(rename = "isLeverage")]
119    #[serde(default)]
120    pub is_leverage: Option<String>,
121    /// Closed size (for reduce-only orders)
122    #[serde(rename = "closedSize")]
123    #[serde(default)]
124    pub closed_size: Option<String>,
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn test_parse_execution() {
133        let json = serde_json::json!({
134            "category": "linear",
135            "symbol": "BTCUSDT",
136            "execId": "abc-123",
137            "execPrice": "50000.00",
138            "execQty": "0.01",
139            "execType": "Trade",
140            "side": "Buy",
141            "orderId": "order-456",
142            "isMaker": false
143        });
144
145        let exec: ExecutionData = serde_json::from_value(json).unwrap();
146        assert_eq!(exec.symbol.as_deref(), Some("BTCUSDT"));
147        assert_eq!(exec.side.as_deref(), Some("Buy"));
148        assert_eq!(exec.exec_qty.as_deref(), Some("0.01"));
149    }
150}