binance/
ws_model.rs

1use crate::rest_model::{string_or_float, Asks, Bids, OrderBook, OrderSide, OrderStatus, OrderType, TimeInForce};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4#[serde(tag = "e")]
5pub enum WebsocketEvent {
6    #[serde(alias = "aggTrade")]
7    AggTrade(Box<TradesEvent>),
8    #[serde(alias = "trade")]
9    Trade(Box<TradeEvent>),
10    #[serde(alias = "kline")]
11    Kline(Box<KlineEvent>),
12    #[serde(alias = "24hrTicker")]
13    DayTicker(Box<DayTickerEvent>),
14    #[serde(alias = "24hrMiniTicker")]
15    DayMiniTicker(Box<MiniDayTickerEvent>),
16    #[serde(alias = "depthUpdate")]
17    DepthOrderBook(Box<DepthOrderBookEvent>),
18    #[serde(alias = "outboundAccountPosition")]
19    AccountPositionUpdate(Box<AccountPositionUpdate>),
20    #[serde(alias = "balanceUpdate")]
21    BalanceUpdate(Box<BalanceUpdate>),
22    #[serde(alias = "executionReport")]
23    OrderUpdate(Box<OrderUpdate>),
24    #[serde(alias = "listStatus")]
25    ListOrderUpdate(Box<OrderListUpdate>),
26    #[serde(alias = "markPriceUpdate")]
27    MarkPriceUpdate(Box<MarkPriceEvent>),
28}
29
30#[derive(Serialize, Deserialize, Debug)]
31pub struct QueryResult {
32    pub result: Option<String>,
33    pub id: i64,
34}
35
36#[derive(Debug, Serialize, Deserialize, Clone)]
37#[serde(rename_all = "camelCase")]
38pub struct TradesEvent {
39    #[serde(rename = "E")]
40    pub event_time: u64,
41
42    #[serde(rename = "s")]
43    pub symbol: String,
44
45    #[serde(rename = "a")]
46    pub aggregated_trade_id: u64,
47
48    #[serde(rename = "p")]
49    pub price: String,
50
51    #[serde(rename = "q")]
52    pub qty: String,
53
54    #[serde(rename = "f")]
55    pub first_break_trade_id: u64,
56
57    #[serde(rename = "l")]
58    pub last_break_trade_id: u64,
59
60    #[serde(rename = "T")]
61    pub trade_order_time: u64,
62
63    #[serde(rename = "m")]
64    pub is_buyer_maker: bool,
65
66    #[serde(skip, rename = "M")]
67    pub m_ignore: bool,
68}
69
70#[derive(Debug, Serialize, Deserialize, Clone)]
71#[serde(rename_all = "camelCase")]
72pub struct TradeEvent {
73    #[serde(rename = "E")]
74    pub event_time: u64,
75
76    #[serde(rename = "s")]
77    pub symbol: String,
78
79    #[serde(rename = "t")]
80    pub trade_id: u64,
81
82    #[serde(rename = "p")]
83    pub price: String,
84
85    #[serde(rename = "q")]
86    pub qty: String,
87
88    #[serde(rename = "b")]
89    pub buyer_order_id: u64,
90
91    #[serde(rename = "a")]
92    pub seller_order_id: u64,
93
94    #[serde(rename = "T")]
95    pub trade_order_time: u64,
96
97    #[serde(rename = "m")]
98    pub is_buyer_maker: bool,
99
100    #[serde(skip, rename = "M")]
101    pub m_ignore: bool,
102}
103
104#[derive(Debug, Serialize, Deserialize, Clone)]
105#[serde(rename_all = "camelCase")]
106pub struct DayTickerEvent {
107    #[serde(rename = "E")]
108    pub event_time: u64,
109    #[serde(rename = "s")]
110    pub symbol: String,
111    #[serde(rename = "p")]
112    pub price_change: String,
113    #[serde(rename = "P")]
114    pub price_change_percent: String,
115    #[serde(rename = "w")]
116    pub average_price: String,
117    #[serde(rename = "x")]
118    pub prev_close: String,
119    #[serde(rename = "c")]
120    pub current_close: String,
121    #[serde(rename = "Q")]
122    pub current_close_qty: String,
123    #[serde(rename = "b")]
124    pub best_bid: String,
125    #[serde(rename = "B")]
126    pub best_bid_qty: String,
127    #[serde(rename = "a")]
128    pub best_ask: String,
129    #[serde(rename = "A")]
130    pub best_ask_qty: String,
131    #[serde(rename = "o")]
132    pub open: String,
133    #[serde(rename = "h")]
134    pub high: String,
135    #[serde(rename = "l")]
136    pub low: String,
137    #[serde(rename = "v")]
138    pub volume: String,
139    #[serde(rename = "q")]
140    pub quote_volume: String,
141    #[serde(rename = "O")]
142    pub open_time: u64,
143    #[serde(rename = "C")]
144    pub close_time: u64,
145    #[serde(rename = "F")]
146    pub first_trade_id: i64,
147    #[serde(rename = "L")]
148    pub last_trade_id: i64,
149    #[serde(rename = "n")]
150    pub num_trades: u64,
151}
152
153#[derive(Debug, Serialize, Deserialize, Clone)]
154#[serde(rename_all = "camelCase")]
155pub struct MiniDayTickerEvent {
156    #[serde(rename = "E")]
157    pub event_time: u64,
158    #[serde(rename = "s")]
159    pub symbol: String,
160    #[serde(rename = "c")]
161    pub current_close: String,
162    #[serde(rename = "o")]
163    pub open: String,
164    #[serde(rename = "h")]
165    pub high: String,
166    #[serde(rename = "l")]
167    pub low: String,
168    #[serde(rename = "v")]
169    pub volume: String,
170    #[serde(rename = "q")]
171    pub quote_volume: String,
172}
173
174#[derive(Debug, Serialize, Deserialize, Clone)]
175#[serde(rename_all = "camelCase")]
176pub struct KlineEvent {
177    #[serde(rename = "E")]
178    pub event_time: u64,
179    #[serde(rename = "s")]
180    pub symbol: String,
181    #[serde(rename = "k")]
182    pub kline: Kline,
183}
184
185#[derive(Debug, Serialize, Deserialize, Clone)]
186#[serde(rename_all = "camelCase")]
187pub struct Kline {
188    #[serde(rename = "t")]
189    pub start_time: i64,
190    #[serde(rename = "T")]
191    pub end_time: i64,
192    #[serde(rename = "s")]
193    pub symbol: String,
194    #[serde(rename = "i")]
195    pub interval: String,
196    #[serde(rename = "f")]
197    pub first_trade_id: i64,
198    #[serde(rename = "L")]
199    pub last_trade_id: i64,
200    #[serde(with = "string_or_float")]
201    #[serde(rename = "o")]
202    pub open: f64,
203    #[serde(with = "string_or_float")]
204    #[serde(rename = "c")]
205    pub close: f64,
206    #[serde(with = "string_or_float")]
207    #[serde(rename = "h")]
208    pub high: f64,
209    #[serde(with = "string_or_float")]
210    #[serde(rename = "l")]
211    pub low: f64,
212    #[serde(with = "string_or_float")]
213    #[serde(rename = "v")]
214    pub volume: f64,
215    #[serde(rename = "n")]
216    pub number_of_trades: i64,
217    #[serde(rename = "x")]
218    pub is_final_bar: bool,
219    #[serde(with = "string_or_float")]
220    #[serde(rename = "q")]
221    pub quote_volume: f64,
222    #[serde(with = "string_or_float")]
223    #[serde(rename = "V")]
224    pub active_buy_volume: f64,
225    #[serde(with = "string_or_float")]
226    #[serde(rename = "Q")]
227    pub active_volume_buy_quote: f64,
228    #[serde(skip, rename = "B")]
229    pub ignore_me: String,
230}
231
232#[derive(Debug, Serialize, Deserialize, Clone)]
233#[serde(rename_all = "camelCase")]
234pub struct DepthOrderBookEvent {
235    #[serde(rename = "E")]
236    pub event_time: u64,
237    #[serde(rename = "s")]
238    pub symbol: String,
239    #[serde(rename = "U")]
240    pub first_update_id: u64,
241    #[serde(rename = "u")]
242    pub final_update_id: u64,
243    #[serde(rename = "b")]
244    pub bids: Vec<Bids>,
245    #[serde(rename = "a")]
246    pub asks: Vec<Asks>,
247}
248
249#[derive(Debug, Serialize, Deserialize, Clone)]
250#[serde(rename_all = "camelCase")]
251pub struct BookTickerEvent {
252    #[serde(rename = "u")]
253    pub update_id: u64,
254
255    #[serde(rename = "s")]
256    pub symbol: String,
257
258    #[serde(rename = "b", with = "string_or_float")]
259    pub best_bid: f64,
260
261    #[serde(rename = "B", with = "string_or_float")]
262    pub best_bid_qty: f64,
263
264    #[serde(rename = "a", with = "string_or_float")]
265    pub best_ask: f64,
266
267    #[serde(rename = "A", with = "string_or_float")]
268    pub best_ask_qty: f64,
269}
270
271#[derive(Debug, Serialize, Deserialize, Clone)]
272#[serde(rename_all = "camelCase")]
273pub struct MarkPriceEvent {
274    #[serde(rename = "E")]
275    pub event_time: u64,
276
277    #[serde(rename = "s")]
278    pub symbol: String,
279
280    #[serde(rename = "p")]
281    pub mark_price: String,
282
283    #[serde(rename = "i")]
284    pub index_price: String,
285
286    #[serde(rename = "P")]
287    pub estimated_settle_price: String,
288
289    #[serde(rename = "r")]
290    pub funding_rate: String,
291
292    #[serde(rename = "T")]
293    pub next_funding_time: u64,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize)]
297pub struct CombinedStreamEvent<T> {
298    stream: String,
299    pub data: T,
300}
301
302///
303#[derive(Debug, Clone, Serialize, Deserialize)]
304#[serde(untagged)]
305pub enum WebsocketEventUntag {
306    WebsocketEvent(WebsocketEvent),
307    Orderbook(Box<OrderBook>),
308    BookTicker(Box<BookTickerEvent>),
309}
310
311impl<T> CombinedStreamEvent<T> {
312    /// Returns (stream_name, channel)
313    pub fn parse_stream(&self) -> (String, String) {
314        let mut parsed = self.stream.clone();
315        if let Some(0) = parsed.find('!') {
316            parsed.remove(0);
317        }
318        let split = parsed.split_once('@').unwrap_or((&parsed, ""));
319        (split.0.to_string(), split.1.to_string())
320    }
321}
322
323/// User Stream related events
324
325/// Account position update
326#[derive(Debug, Serialize, Deserialize, Clone)]
327#[serde(rename_all = "camelCase")]
328pub struct AccountPositionUpdate {
329    #[serde(alias = "E")]
330    pub event_time: u64,
331
332    #[serde(alias = "u")]
333    pub last_update_time: u64,
334
335    #[serde(alias = "B")]
336    pub balances: Vec<EventBalance>,
337}
338
339#[derive(Debug, Serialize, Deserialize, Clone)]
340#[serde(rename_all = "camelCase")]
341pub struct AccountUpdate {
342    #[serde(alias = "E")]
343    pub event_time: u64,
344
345    /// Maker commission rate (bips)
346    #[serde(alias = "m")]
347    maker_commission_rate: u64,
348    /// Taker commission rate (bips)
349    #[serde(alias = "t")]
350    taker_commission_rate: u64,
351    /// Buyer commission rate (bips)
352    #[serde(alias = "b")]
353    buyer_commission_rate: u64,
354    /// Seller commission rate (bips)
355    #[serde(alias = "s")]
356    seller_commission_rate: u64,
357
358    #[serde(alias = "T")]
359    can_trade: bool,
360    #[serde(alias = "W")]
361    can_withdraw: bool,
362    #[serde(alias = "D")]
363    can_deposit: bool,
364
365    #[serde(alias = "B")]
366    pub balances: Vec<EventBalance>,
367}
368
369#[derive(Debug, Serialize, Deserialize, Clone)]
370#[serde(rename_all = "camelCase")]
371pub struct EventBalance {
372    #[serde(rename = "a")]
373    pub asset: String,
374    #[serde(rename = "f")]
375    #[serde(with = "string_or_float")]
376    pub free: f64,
377    #[serde(rename = "l")]
378    #[serde(with = "string_or_float")]
379    pub locked: f64,
380}
381
382#[derive(Debug, Serialize, Deserialize, Clone)]
383#[serde(rename_all = "camelCase")]
384pub struct BalanceUpdate {
385    #[serde(alias = "E")]
386    pub event_time: u64,
387
388    #[serde(rename = "a")]
389    pub asset: String,
390
391    #[serde(rename = "d")]
392    #[serde(with = "string_or_float")]
393    pub delta: f64,
394
395    #[serde(alias = "T")]
396    pub clear_time: u64,
397}
398
399#[derive(Debug, Serialize, Deserialize, Clone)]
400#[serde(rename_all = "camelCase")]
401pub struct OrderUpdate {
402    #[serde(rename = "E")]
403    pub event_time: u64,
404    #[serde(rename = "s")]
405    pub symbol: String,
406    #[serde(rename = "c")]
407    pub client_order_id: Option<String>,
408    #[serde(rename = "S")]
409    pub side: OrderSide,
410    #[serde(rename = "o")]
411    pub order_type: OrderType,
412    #[serde(rename = "f")]
413    pub time_in_force: TimeInForce,
414    #[serde(rename = "q")]
415    #[serde(with = "string_or_float")]
416    pub qty: f64,
417    #[serde(rename = "p")]
418    #[serde(with = "string_or_float")]
419    pub price: f64,
420    #[serde(rename = "P")]
421    #[serde(with = "string_or_float")]
422    pub stop_price: f64,
423    #[serde(rename = "F")]
424    #[serde(with = "string_or_float")]
425    pub iceberg_qty: f64,
426    #[serde(rename = "g")]
427    pub order_list_id: i64,
428    #[serde(rename = "C")]
429    pub origin_client_id: Option<String>,
430    #[serde(rename = "x")]
431    pub execution_type: OrderStatus,
432    #[serde(rename = "X")]
433    pub current_order_status: OrderStatus,
434    #[serde(rename = "r")]
435    pub order_reject_reason: String,
436    #[serde(rename = "i")]
437    pub order_id: u64,
438    #[serde(rename = "l")]
439    #[serde(with = "string_or_float")]
440    pub qty_last_executed: f64,
441    #[serde(rename = "z")]
442    #[serde(with = "string_or_float")]
443    pub cumulative_filled_qty: f64,
444    #[serde(rename = "L")]
445    #[serde(with = "string_or_float")]
446    pub last_executed_price: f64,
447    #[serde(rename = "n")]
448    #[serde(with = "string_or_float")]
449    pub commission: f64,
450    #[serde(rename = "N")]
451    pub commission_asset: Option<String>,
452    #[serde(rename = "T")]
453    pub trade_order_time: u64,
454    #[serde(rename = "t")]
455    pub trade_id: i64,
456    #[serde(skip, rename = "I")]
457    pub i_ignore: u64,
458    #[serde(rename = "w")]
459    pub is_order_on_the_book: bool,
460    #[serde(rename = "m")]
461    pub is_buyer_maker: bool,
462    #[serde(skip, rename = "M")]
463    pub m_ignore: bool,
464    #[serde(rename = "O")]
465    pub order_creation_time: u64,
466    #[serde(rename = "Z")]
467    #[serde(with = "string_or_float")]
468    pub cumulative_quote_asset_transacted_qty: f64,
469    /// (i.e. lastPrice * lastQty)
470    #[serde(rename = "Y")]
471    #[serde(with = "string_or_float")]
472    pub last_quote_asset_transacted_qty: f64,
473    #[serde(rename = "Q")]
474    #[serde(with = "string_or_float")]
475    pub quote_order_qty: f64,
476}
477
478/// For OCO Events
479#[derive(Debug, Serialize, Deserialize, Clone)]
480#[serde(rename_all = "camelCase")]
481pub struct OrderListUpdate {
482    #[serde(rename = "E")]
483    pub event_time: u64,
484    #[serde(rename = "s")]
485    pub symbol: String,
486    #[serde(rename = "g")]
487    order_list_id: i64,
488    #[serde(rename = "c")]
489    contingency_type: String,
490    #[serde(rename = "l")]
491    list_status_type: String,
492    #[serde(rename = "L")]
493    list_order_status: String,
494    #[serde(rename = "r")]
495    list_reject_reason: String,
496    #[serde(rename = "C")]
497    list_client_order_id: String,
498    #[serde(rename = "T")]
499    pub transaction_time: u64,
500    #[serde(rename = "O")]
501    pub objects: Vec<OrderListTransaction>,
502}
503
504#[derive(Debug, Serialize, Deserialize, Clone)]
505#[serde(rename_all = "camelCase")]
506pub struct OrderListTransaction {
507    #[serde(rename = "s")]
508    pub symbol: String,
509    #[serde(rename = "i")]
510    pub order_id: i64,
511    #[serde(rename = "c")]
512    pub client_order_id: String,
513}