binance_async_api/websocket/
usdm.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
use super::StreamTopic;
use crate::client::Product;
use serde::Deserialize;

#[derive(Debug, Clone, Copy)]
pub struct AggTradeStream<'a> {
    pub symbol: &'a str,
}

#[derive(Debug, Clone, Deserialize)]
pub struct AggTradeEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "a")]
    pub id: usize,
    #[serde(rename = "p")]
    pub price: String,
    #[serde(rename = "q")]
    pub qty: String,
    #[serde(rename = "f")]
    pub first_trade_id: usize,
    #[serde(rename = "l")]
    pub last_trade_id: usize,
    #[serde(rename = "T")]
    pub trade_time: usize,
    #[serde(rename = "m")]
    pub buyer_is_maker: bool,
}

impl<'a> StreamTopic for AggTradeStream<'a> {
    const PRODUCT: Product = Product::UsdMFutures;
    fn endpoint(&self) -> String {
        format!("/ws/{}@aggTrade", self.symbol.to_lowercase())
    }
    type Event = AggTradeEvent;
}

#[derive(Debug, Clone, Copy)]
pub struct BookTickerStream<'a> {
    pub symbol: &'a str,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BookTickerEvent {
    #[serde(rename = "u")]
    pub order_book_update_id: usize,
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "T")]
    pub transaction_time: usize,
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "b")]
    pub best_bid_price: String,
    #[serde(rename = "B")]
    pub best_bid_qty: String,
    #[serde(rename = "a")]
    pub best_ask_price: String,
    #[serde(rename = "A")]
    pub best_ask_qty: String,
}

impl<'a> StreamTopic for BookTickerStream<'a> {
    const PRODUCT: Product = Product::UsdMFutures;
    fn endpoint(&self) -> String {
        format!("/ws/{}@bookTicker", self.symbol.to_lowercase())
    }
    type Event = BookTickerEvent;
}

#[derive(Debug, Clone, Deserialize)]
pub struct DiffDepthEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "T")]
    pub transaction_time: usize,
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "U")]
    pub first_update_id: usize,
    #[serde(rename = "u")]
    pub final_update_id: usize,
    #[serde(rename = "pu")]
    pub last_event_final_update_id: usize,
    #[serde(rename = "b")]
    pub bid_updates: Vec<BookLevelUpdate>,
    #[serde(rename = "a")]
    pub ask_updates: Vec<BookLevelUpdate>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BookLevelUpdate {
    pub price: String,
    pub qty: String,
}

#[derive(Debug, Clone, Copy)]
pub struct DiffDepthStream<'a> {
    pub symbol: &'a str,
}

impl<'a> StreamTopic for DiffDepthStream<'a> {
    const PRODUCT: Product = Product::UsdMFutures;
    fn endpoint(&self) -> String {
        format!("/ws/{}@depth@100ms", self.symbol.to_lowercase())
    }
    type Event = DiffDepthEvent;
}

#[derive(Debug, Clone, Copy)]
pub struct UserStream<'a> {
    pub listen_key: &'a str,
}

#[derive(Debug, Clone, Deserialize)]
pub struct PositionMarginCall {
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "ps")]
    pub position_side: String,
    #[serde(rename = "pa")]
    pub position_amount: String,
    #[serde(rename = "mt")]
    pub margin_type: String,
    #[serde(rename = "iw")]
    pub isolated_wallet: Option<String>,
    #[serde(rename = "mp")]
    pub mark_price: String,
    #[serde(rename = "up")]
    pub unrealized_pnl: String,
    #[serde(rename = "mm")]
    pub required_maintenance_margin: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct MarginCallEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "cw")]
    pub cross_wallet_balance: Option<String>,
    #[serde(rename = "p")]
    pub positions: Vec<PositionMarginCall>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BalancePositionUpdateEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "T")]
    pub transaction_time: usize,
    #[serde(rename = "a")]
    pub balance_position_update: BalancePositionUpdate,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BalancePositionUpdate {
    #[serde(rename = "m")]
    pub reason: String,
    #[serde(rename = "B")]
    pub balance_updates: Vec<BalanceUpdate>,
    #[serde(rename = "P")]
    pub position_updates: Vec<PositionUpdate>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct BalanceUpdate {
    #[serde(rename = "a")]
    pub asset: String,
    #[serde(rename = "wb")]
    pub wallet_balance: String,
    #[serde(rename = "cw")]
    pub cross_wallet_balance: String,
    #[serde(rename = "bc")]
    pub balance_change: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct PositionUpdate {
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "pa")]
    pub position_amount: String,
    #[serde(rename = "ep")]
    pub entry_price: String,
    #[serde(rename = "bep")]
    pub breakeven_price: String,
    #[serde(rename = "cr")]
    pub realized_pnl: String,
    #[serde(rename = "up")]
    pub unrealized_pnl: String,
    #[serde(rename = "mt")]
    pub margin_type: String,
    #[serde(rename = "iw")]
    pub isolated_wallet: Option<String>,
    #[serde(rename = "ps")]
    pub position_side: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct OrderUpdateEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "T")]
    pub transaction_time: usize,
    #[serde(rename = "o")]
    pub order_update: OrderUpdate,
}

#[derive(Debug, Clone, Deserialize)]
pub struct OrderUpdate {
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "c")]
    pub client_order_id: String,
    #[serde(rename = "S")]
    pub side: String,
    #[serde(rename = "o")]
    pub order_type: String,
    #[serde(rename = "f")]
    pub time_in_force: String,
    #[serde(rename = "q")]
    pub orig_qty: String,
    #[serde(rename = "p")]
    pub orig_price: String,
    #[serde(rename = "ap")]
    pub average_price: String,
    #[serde(rename = "sp")]
    pub stop_price: String,
    #[serde(rename = "x")]
    pub current_order_execution_type: String,
    #[serde(rename = "X")]
    pub current_order_status: String,
    #[serde(rename = "i")]
    pub order_id: usize,
    #[serde(rename = "l")]
    pub last_filled_qty: String,
    #[serde(rename = "z")]
    pub cummulative_filled_qty: String,
    #[serde(rename = "L")]
    pub last_fill_price: String,
    #[serde(rename = "N")]
    pub commission_asset: Option<String>,
    #[serde(rename = "n")]
    pub commission_amount: Option<String>,
    #[serde(rename = "T")]
    pub order_trade_time: usize,
    #[serde(rename = "t")]
    pub order_trade_id: usize,
    #[serde(rename = "b")]
    pub bid_notional: String,
    #[serde(rename = "a")]
    pub ask_notional: String,
    #[serde(rename = "m")]
    pub is_trade_maker: bool,
    #[serde(rename = "R")]
    pub is_reduce_only: bool,
    #[serde(rename = "wt")]
    pub stop_price_working_type: String,
    #[serde(rename = "ot")]
    pub orig_order_type: String,
    #[serde(rename = "ps")]
    pub position_side: String,
    #[serde(rename = "cp")]
    pub close_position: bool,
    #[serde(rename = "AP")]
    pub activation_price: Option<String>,
    #[serde(rename = "cr")]
    pub callback_rate: Option<String>,
    #[serde(rename = "pP")]
    pub price_protection: bool,
    #[serde(rename = "rp")]
    pub trade_realized_profit: String,
    #[serde(rename = "V")]
    pub self_trade_prevention_mode: String,
    #[serde(rename = "gtd")]
    pub good_till_date: usize,
}

#[derive(Debug, Clone, Deserialize)]
pub struct AccountConfigurationUpdateEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "T")]
    pub transaction_time: usize,
    #[serde(rename = "ac")]
    pub leverage: Option<LeverageUpdate>,
    #[serde(rename = "ai")]
    pub multi_asset_mode: Option<MultiAssetModeUpdate>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct LeverageUpdate {
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "l")]
    pub leverage: usize,
}

#[derive(Debug, Clone, Deserialize)]
pub struct MultiAssetModeUpdate {
    #[serde(rename = "j")]
    pub multi_asset_mode: bool,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ConditionalOrderTriggerRejectEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "T")]
    pub transaction_time: usize,
    #[serde(rename = "or")]
    pub conditional_order_trigger_reject: ConditionalOrderTriggerReject,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ConditionalOrderTriggerReject {
    #[serde(rename = "s")]
    pub symbol: String,
    #[serde(rename = "i")]
    pub order_id: usize,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ListenKeyExpiredEvent {
    #[serde(rename = "E")]
    pub event_time: usize,
    #[serde(rename = "listenKey")]
    pub listen_key: String,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "e")]
#[allow(clippy::large_enum_variant)]
pub enum UserStreamEvent {
    #[serde(rename = "MARGIN_CALL")]
    MarginCall(MarginCallEvent),
    #[serde(rename = "ACCOUNT_UPDATE")]
    BalancePositionUpdate(BalancePositionUpdateEvent),
    #[serde(rename = "ORDER_TRADE_UPDATE")]
    OrderUpdate(OrderUpdateEvent),
    #[serde(rename = "ACCOUNT_CONFIG_UPDATE")]
    AccountConfigurationUpdate(AccountConfigurationUpdateEvent),
    #[serde(rename = "CONDITIONAL_ORDER_TRIGGER_REJECT")]
    ConditionalOrderTriggerReject(ConditionalOrderTriggerRejectEvent),
    #[serde(rename = "listenKeyExpired")]
    ListenKeyExpired(ListenKeyExpiredEvent),
}

impl<'a> StreamTopic for UserStream<'a> {
    const PRODUCT: Product = Product::UsdMFutures;
    fn endpoint(&self) -> String {
        format!("/ws/{}", self.listen_key)
    }
    type Event = UserStreamEvent;
}