binance_api_async/
model.rs

1use serde::{Deserialize, Serialize};
2
3use crate::websocket::WebsocketEvent;
4
5#[derive(Serialize, Deserialize)]
6pub struct BinanceWsResponse {
7    pub stream: String,
8    pub data: WebsocketEvent,
9}
10
11#[derive(Serialize, Deserialize, Clone)]
12#[serde(rename_all = "camelCase")]
13pub struct ServerTime {
14    pub server_time: u64,
15}
16
17#[derive(Debug, Serialize, Deserialize, Clone)]
18#[serde(rename_all = "camelCase")]
19pub struct ExchangeInformation {
20    pub timezone: String,
21    pub server_time: u64,
22    pub rate_limits: Vec<RateLimit>,
23    pub symbols: Vec<Symbol>,
24}
25
26#[derive(Debug, Serialize, Deserialize, Clone)]
27#[serde(rename_all = "camelCase")]
28pub struct RateLimit {
29    pub rate_limit_type: String,
30    pub interval: String,
31    pub interval_num: u16,
32    pub limit: u64,
33}
34
35#[derive(Debug, Serialize, Deserialize, Clone)]
36#[serde(rename_all = "camelCase")]
37pub struct Symbol {
38    pub symbol: String,
39    pub status: String,
40    pub base_asset: String,
41    pub base_asset_precision: u64,
42    pub quote_asset: String,
43    pub quote_precision: u64,
44    pub order_types: Vec<String>,
45    pub iceberg_allowed: bool,
46    pub is_spot_trading_allowed: bool,
47    pub is_margin_trading_allowed: bool,
48    pub filters: Vec<Filters>,
49}
50
51#[derive(Debug, Serialize, Deserialize, Clone)]
52#[serde(tag = "filterType")]
53pub enum Filters {
54    #[serde(rename = "PRICE_FILTER")]
55    #[serde(rename_all = "camelCase")]
56    PriceFilter {
57        min_price: String,
58        max_price: String,
59        tick_size: String,
60    },
61    #[serde(rename = "PERCENT_PRICE")]
62    #[serde(rename_all = "camelCase")]
63    PercentPrice {
64        multiplier_up: String,
65        multiplier_down: String,
66        avg_price_mins: Option<f64>,
67    },
68    #[serde(rename = "LOT_SIZE")]
69    #[serde(rename_all = "camelCase")]
70    LotSize {
71        min_qty: String,
72        max_qty: String,
73        step_size: String,
74    },
75    #[serde(rename = "MIN_NOTIONAL")]
76    #[serde(rename_all = "camelCase")]
77    MinNotional {
78        min_notional: Option<String>,
79        apply_to_market: Option<bool>,
80        avg_price_mins: Option<f64>,
81    },
82    #[serde(rename = "ICEBERG_PARTS")]
83    #[serde(rename_all = "camelCase")]
84    IcebergParts { limit: Option<u16> },
85    #[serde(rename = "MAX_NUM_ORDERS")]
86    #[serde(rename_all = "camelCase")]
87    MaxNumOrders { limit: Option<u16> },
88    #[serde(rename = "MAX_NUM_ALGO_ORDERS")]
89    #[serde(rename_all = "camelCase")]
90    MaxNumAlgoOrders { max_num_algo_orders: Option<u16> },
91    #[serde(rename = "MAX_NUM_ICEBERG_ORDERS")]
92    #[serde(rename_all = "camelCase")]
93    MaxNumIcebergOrders { max_num_iceberg_orders: u16 },
94    #[serde(rename = "MAX_POSITION")]
95    #[serde(rename_all = "camelCase")]
96    MaxPosition { max_position: String },
97    #[serde(rename = "MARKET_LOT_SIZE")]
98    #[serde(rename_all = "camelCase")]
99    MarketLotSize {
100        min_qty: String,
101        max_qty: String,
102        step_size: String,
103    },
104}
105
106#[derive(Debug, Serialize, Deserialize, Clone)]
107#[serde(rename_all = "camelCase")]
108pub struct AccountInformation {
109    pub maker_commission: f32,
110    pub taker_commission: f32,
111    pub buyer_commission: f32,
112    pub seller_commission: f32,
113    pub can_trade: bool,
114    pub can_withdraw: bool,
115    pub can_deposit: bool,
116    pub balances: Vec<Balance>,
117}
118
119#[derive(Debug, Serialize, Deserialize, Clone)]
120#[serde(rename_all = "camelCase")]
121pub struct Balance {
122    pub asset: String,
123    pub free: String,
124    pub locked: String,
125}
126
127#[derive(Debug, Serialize, Deserialize, Clone)]
128#[serde(rename_all = "camelCase")]
129pub struct Order {
130    pub symbol: String,
131    pub order_id: u64,
132    pub client_order_id: String,
133    #[serde(with = "string_or_float")]
134    pub price: f64,
135    pub orig_qty: String,
136    pub executed_qty: String,
137    pub status: String,
138    pub time_in_force: String,
139    #[serde(rename = "type")]
140    pub type_name: String,
141    pub side: String,
142    #[serde(with = "string_or_float")]
143    pub stop_price: f64,
144    pub iceberg_qty: String,
145    pub time: u64,
146}
147
148#[derive(Debug, Serialize, Deserialize, Clone)]
149#[serde(rename_all = "camelCase")]
150pub struct OrderCanceled {
151    pub symbol: String,
152    pub orig_client_order_id: String,
153    pub order_id: u64,
154    pub client_order_id: String,
155}
156
157#[derive(Debug, Serialize, Deserialize, Clone)]
158#[serde(rename_all = "camelCase")]
159pub struct Transaction {
160    pub symbol: String,
161    pub order_id: u64,
162    pub client_order_id: String,
163    pub transact_time: u64,
164    #[serde(with = "string_or_float")]
165    pub price: f64,
166    #[serde(with = "string_or_float")]
167    pub orig_qty: f64,
168    #[serde(with = "string_or_float")]
169    pub executed_qty: f64,
170    #[serde(with = "string_or_float")]
171    pub cummulative_quote_qty: f64,
172    pub status: String,
173    pub time_in_force: String,
174    pub side: String,
175    pub fills: Vec<FillInfo>,
176}
177
178#[derive(Debug, Serialize, Deserialize, Clone)]
179#[serde(rename_all = "camelCase")]
180pub struct FillInfo {
181    #[serde(with = "string_or_float")]
182    pub price: f64,
183    #[serde(with = "string_or_float")]
184    pub qty: f64,
185    #[serde(with = "string_or_float")]
186    pub commission: f64,
187    pub commission_asset: String,
188    pub trade_id: Option<u64>,
189}
190
191/// Response to a test order (endpoint /api/v3/order/test).
192///
193/// Currently, the API responds {} on a successfull test transaction,
194/// hence this struct has no fields.
195#[derive(Debug, Serialize, Deserialize, Clone)]
196#[serde(rename_all = "camelCase")]
197pub struct TestResponse {}
198
199#[derive(Debug, Serialize, Deserialize, Clone)]
200#[serde(rename_all = "camelCase")]
201pub struct OrderBook {
202    pub last_update_id: u64,
203    pub bids: Vec<Bids>,
204    pub asks: Vec<Asks>,
205}
206
207#[derive(Debug, Serialize, Deserialize, Clone)]
208pub struct Bids {
209    #[serde(with = "string_or_float")]
210    pub price: f64,
211    #[serde(with = "string_or_float")]
212    pub qty: f64,
213
214    // Never serialized.
215    #[serde(skip)]
216    ignore: Vec<String>,
217}
218
219#[derive(Debug, Serialize, Deserialize, Clone)]
220pub struct Asks {
221    #[serde(with = "string_or_float")]
222    pub price: f64,
223    #[serde(with = "string_or_float")]
224    pub qty: f64,
225
226    // Never serialized.
227    #[serde(skip)]
228    ignore: Vec<String>,
229}
230
231#[derive(Debug, Serialize, Deserialize, Clone)]
232#[serde(rename_all = "camelCase")]
233pub struct UserDataStream {
234    pub listen_key: String,
235}
236
237#[derive(Debug, Serialize, Deserialize, Clone)]
238pub struct Success {}
239
240#[derive(Debug, Serialize, Deserialize, Clone)]
241#[serde(rename_all = "camelCase")]
242#[serde(untagged)]
243pub enum Prices {
244    AllPrices(Vec<SymbolPrice>),
245}
246
247#[derive(Debug, Serialize, Deserialize, Clone)]
248pub struct SymbolPrice {
249    pub symbol: String,
250    #[serde(with = "string_or_float")]
251    pub price: f64,
252}
253
254#[derive(Debug, Serialize, Deserialize, Clone)]
255pub struct AveragePrice {
256    pub mins: u64,
257    #[serde(with = "string_or_float")]
258    pub price: f64,
259}
260
261#[derive(Debug, Serialize, Deserialize, Clone)]
262#[serde(rename_all = "camelCase")]
263#[serde(untagged)]
264pub enum BookTickers {
265    AllBookTickers(Vec<Tickers>),
266}
267
268#[derive(Debug, Clone)]
269pub enum KlineSummaries {
270    AllKlineSummaries(Vec<KlineSummary>),
271}
272
273#[derive(Debug, Serialize, Deserialize, Clone)]
274#[serde(rename_all = "camelCase")]
275pub struct Tickers {
276    pub symbol: String,
277    #[serde(with = "string_or_float")]
278    pub bid_price: f64,
279    #[serde(with = "string_or_float")]
280    pub bid_qty: f64,
281    #[serde(with = "string_or_float")]
282    pub ask_price: f64,
283    #[serde(with = "string_or_float")]
284    pub ask_qty: f64,
285}
286
287#[derive(Debug, Serialize, Deserialize, Clone)]
288#[serde(rename_all = "camelCase")]
289pub struct TradeHistory {
290    pub id: u64,
291    #[serde(with = "string_or_float")]
292    pub price: f64,
293    #[serde(with = "string_or_float")]
294    pub qty: f64,
295    pub commission: String,
296    pub commission_asset: String,
297    pub time: u64,
298    pub is_buyer: bool,
299    pub is_maker: bool,
300    pub is_best_match: bool,
301}
302
303#[derive(Debug, Serialize, Deserialize, Clone)]
304#[serde(rename_all = "camelCase")]
305pub struct PriceStats {
306    pub price_change: String,
307    pub price_change_percent: String,
308    pub weighted_avg_price: String,
309    #[serde(with = "string_or_float")]
310    pub prev_close_price: f64,
311    #[serde(with = "string_or_float")]
312    pub last_price: f64,
313    #[serde(with = "string_or_float")]
314    pub bid_price: f64,
315    #[serde(with = "string_or_float")]
316    pub ask_price: f64,
317    #[serde(with = "string_or_float")]
318    pub open_price: f64,
319    #[serde(with = "string_or_float")]
320    pub high_price: f64,
321    #[serde(with = "string_or_float")]
322    pub low_price: f64,
323    #[serde(with = "string_or_float")]
324    pub volume: f64,
325    pub open_time: u64,
326    pub close_time: u64,
327    pub first_id: u64,
328    pub last_id: u64,
329    pub count: u64,
330}
331
332#[derive(Debug, Serialize, Deserialize, Clone)]
333#[serde(rename_all = "camelCase")]
334pub struct AccountUpdateEvent {
335    #[serde(rename = "e")]
336    pub event_type: String,
337
338    #[serde(rename = "E")]
339    pub event_time: u64,
340
341    m: u64,
342    t: u64,
343    b: u64,
344    s: u64,
345
346    #[serde(rename = "T")]
347    t_ignore: bool,
348    #[serde(rename = "W")]
349    w_ignore: bool,
350    #[serde(rename = "D")]
351    d_ignore: bool,
352
353    #[serde(rename = "B")]
354    pub balance: Vec<EventBalance>,
355}
356
357#[derive(Debug, Serialize, Deserialize, Clone)]
358#[serde(rename_all = "camelCase")]
359pub struct BalanceUpdateEvent {
360    #[serde(rename = "E")]
361    pub event_time: i64,
362    #[serde(rename = "a")]
363    pub asset: String,
364    #[serde(rename = "d")]
365    pub balance_delta: String,
366    #[serde(rename = "T")]
367    pub clear_time: i64,
368}
369
370#[derive(Debug, Serialize, Deserialize, Clone)]
371#[serde(rename_all = "camelCase")]
372pub struct EventBalance {
373    #[serde(rename = "a")]
374    pub asset: String,
375    #[serde(rename = "f")]
376    pub free: String,
377    #[serde(rename = "l")]
378    pub locked: String,
379}
380
381#[derive(Debug, Serialize, Deserialize, Clone)]
382#[serde(rename_all = "camelCase")]
383pub struct OrderTradeEvent {
384    #[serde(rename = "e")]
385    pub event_type: String,
386
387    #[serde(rename = "E")]
388    pub event_time: u64,
389
390    #[serde(rename = "s")]
391    pub symbol: String,
392
393    #[serde(rename = "c")]
394    pub new_client_order_id: String,
395
396    #[serde(rename = "S")]
397    pub side: String,
398
399    #[serde(rename = "o")]
400    pub order_type: String,
401
402    #[serde(rename = "f")]
403    pub time_in_force: String,
404
405    #[serde(rename = "q")]
406    pub qty: String,
407
408    #[serde(rename = "p")]
409    pub price: String,
410
411    #[serde(skip, rename = "P")]
412    pub p_ignore: String,
413
414    #[serde(skip, rename = "F")]
415    pub f_ignore: String,
416
417    #[serde(skip)]
418    pub g: i32,
419
420    #[serde(skip, rename = "C")]
421    pub c_ignore: Option<String>,
422
423    #[serde(rename = "x")]
424    pub execution_type: String,
425
426    #[serde(rename = "X")]
427    pub order_status: String,
428
429    #[serde(rename = "r")]
430    pub order_reject_reason: String,
431
432    #[serde(rename = "i")]
433    pub order_id: u64,
434
435    #[serde(rename = "l")]
436    pub qty_last_filled_trade: String,
437
438    #[serde(rename = "z")]
439    pub accumulated_qty_filled_trades: String,
440
441    #[serde(rename = "L")]
442    pub price_last_filled_trade: String,
443
444    #[serde(rename = "n")]
445    pub commission: String,
446
447    #[serde(skip, rename = "N")]
448    pub asset_commisioned: Option<String>,
449
450    #[serde(rename = "T")]
451    pub trade_order_time: u64,
452
453    #[serde(rename = "t")]
454    pub trade_id: i64,
455
456    #[serde(skip, rename = "I")]
457    pub i_ignore: u64,
458
459    #[serde(skip)]
460    pub w: bool,
461
462    #[serde(rename = "m")]
463    pub is_buyer_maker: bool,
464
465    #[serde(skip, rename = "M")]
466    pub m_ignore: bool,
467}
468
469#[derive(Debug, Serialize, Deserialize, Clone)]
470pub struct OneTradeEvent {
471    #[serde(rename = "e")]
472    pub trade_info_e: String,
473    #[serde(rename = "E")]
474    pub event_time: u128,
475    #[serde(rename = "s")]
476    pub symbol: String,
477    #[serde(rename = "t")]
478    pub trade_time: u128,
479    #[serde(rename = "p")]
480    pub price: String,
481    #[serde(rename = "q")]
482    pub qty: String,
483    pub b: i64,
484    pub a: i64,
485    #[serde(rename = "T")]
486    pub t: i64,
487    #[serde(rename = "m")]
488    pub trade_info_m: bool,
489    #[serde(rename = "M")]
490    pub m: bool,
491}
492
493#[derive(Debug, Serialize, Deserialize, Clone)]
494#[serde(rename_all = "camelCase")]
495pub struct TradesEvent {
496    #[serde(rename = "e")]
497    pub event_type: String,
498
499    #[serde(rename = "E")]
500    pub event_time: u64,
501
502    #[serde(rename = "s")]
503    pub symbol: String,
504
505    #[serde(rename = "a")]
506    pub aggregated_trade_id: u64,
507
508    #[serde(rename = "p")]
509    pub price: String,
510
511    #[serde(rename = "q")]
512    pub qty: String,
513
514    #[serde(rename = "f")]
515    pub first_break_trade_id: u64,
516
517    #[serde(rename = "l")]
518    pub last_break_trade_id: u64,
519
520    #[serde(rename = "T")]
521    pub trade_order_time: u64,
522
523    #[serde(rename = "m")]
524    pub is_buyer_maker: bool,
525
526    #[serde(skip, rename = "M")]
527    pub m_ignore: bool,
528}
529
530#[derive(Debug, Serialize, Deserialize, Clone)]
531#[serde(rename_all = "camelCase")]
532pub struct BookTickerEvent {
533    #[serde(rename = "u")]
534    pub update_id: u64,
535
536    #[serde(rename = "s")]
537    pub symbol: String,
538
539    #[serde(rename = "b")]
540    pub best_bid: String,
541
542    #[serde(rename = "B")]
543    pub best_bid_qty: String,
544
545    #[serde(rename = "a")]
546    pub best_ask: String,
547
548    #[serde(rename = "A")]
549    pub best_ask_qty: String,
550}
551
552#[derive(Debug, Serialize, Deserialize, Clone)]
553#[serde(rename_all = "camelCase")]
554pub struct DayTickerEvent {
555    #[serde(rename = "e")]
556    pub event_type: String,
557
558    #[serde(rename = "E")]
559    pub event_time: u64,
560
561    #[serde(rename = "s")]
562    pub symbol: String,
563
564    #[serde(rename = "p")]
565    pub price_change: String,
566
567    #[serde(rename = "P")]
568    pub price_change_percent: String,
569
570    #[serde(rename = "w")]
571    pub average_price: String,
572
573    #[serde(rename = "x")]
574    pub prev_close: String,
575
576    #[serde(rename = "c")]
577    pub current_close: String,
578
579    #[serde(rename = "Q")]
580    pub current_close_qty: String,
581
582    #[serde(rename = "b")]
583    pub best_bid: String,
584
585    #[serde(rename = "B")]
586    pub best_bid_qty: String,
587
588    #[serde(rename = "a")]
589    pub best_ask: String,
590
591    #[serde(rename = "A")]
592    pub best_ask_qty: String,
593
594    #[serde(rename = "o")]
595    pub open: String,
596
597    #[serde(rename = "h")]
598    pub high: String,
599
600    #[serde(rename = "l")]
601    pub low: String,
602
603    #[serde(rename = "v")]
604    pub volume: String,
605
606    #[serde(rename = "q")]
607    pub quote_volume: String,
608
609    #[serde(rename = "O")]
610    pub open_time: u64,
611
612    #[serde(rename = "C")]
613    pub close_time: u64,
614
615    #[serde(rename = "F")]
616    pub first_trade_id: i64,
617
618    #[serde(rename = "L")]
619    pub last_trade_id: i64,
620
621    #[serde(rename = "n")]
622    pub num_trades: u64,
623}
624
625#[derive(Debug, Serialize, Deserialize, Clone)]
626#[serde(rename_all = "camelCase")]
627pub struct KlineEvent {
628    #[serde(rename = "e")]
629    pub event_type: String,
630
631    #[serde(rename = "E")]
632    pub event_time: u64,
633
634    #[serde(rename = "s")]
635    pub symbol: String,
636
637    #[serde(rename = "k")]
638    pub kline: Kline,
639}
640
641#[derive(Debug, Clone)]
642pub struct KlineSummary {
643    pub open_time: i64,
644
645    pub open: f64,
646
647    pub high: f64,
648
649    pub low: f64,
650
651    pub close: f64,
652
653    pub volume: f64,
654
655    pub close_time: i64,
656
657    pub quote_asset_volume: f64,
658
659    pub number_of_trades: i64,
660
661    pub taker_buy_base_asset_volume: f64,
662
663    pub taker_buy_quote_asset_volume: f64,
664}
665
666#[derive(Debug, Serialize, Deserialize, Clone)]
667#[serde(rename_all = "camelCase")]
668pub struct Kline {
669    #[serde(rename = "t")]
670    pub start_time: i64,
671
672    #[serde(rename = "T")]
673    pub end_time: i64,
674
675    #[serde(rename = "s")]
676    pub symbol: String,
677
678    #[serde(rename = "i")]
679    pub interval: String,
680
681    #[serde(rename = "f")]
682    pub first_trade_id: i32,
683
684    #[serde(rename = "L")]
685    pub last_trade_id: i32,
686
687    #[serde(rename = "o")]
688    pub open: String,
689
690    #[serde(rename = "c")]
691    pub close: String,
692
693    #[serde(rename = "h")]
694    pub high: String,
695
696    #[serde(rename = "l")]
697    pub low: String,
698
699    #[serde(rename = "v")]
700    pub volume: String,
701
702    #[serde(rename = "n")]
703    pub number_of_trades: i32,
704
705    #[serde(rename = "x")]
706    pub is_final_bar: bool,
707
708    #[serde(rename = "q")]
709    pub quote_volume: String,
710
711    #[serde(rename = "V")]
712    pub active_buy_volume: String,
713
714    #[serde(rename = "Q")]
715    pub active_volume_buy_quote: String,
716
717    #[serde(skip, rename = "B")]
718    pub ignore_me: String,
719}
720
721#[derive(Debug, Serialize, Deserialize, Clone)]
722#[serde(rename_all = "camelCase")]
723pub struct DepthOrderBookEvent {
724    #[serde(rename = "e")]
725    pub event_type: String,
726
727    #[serde(rename = "E")]
728    pub event_time: u64,
729
730    #[serde(rename = "s")]
731    pub symbol: String,
732
733    #[serde(rename = "U")]
734    pub first_update_id: u64,
735
736    #[serde(rename = "u")]
737    pub final_update_id: u64,
738
739    #[serde(rename = "b")]
740    pub bids: Vec<Bids>,
741
742    #[serde(rename = "a")]
743    pub asks: Vec<Asks>,
744}
745
746pub(crate) mod string_or_float {
747    use std::fmt;
748
749    use serde::{de, Deserialize, Deserializer, Serializer};
750
751    pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
752        where
753            T: fmt::Display,
754            S: Serializer,
755    {
756        serializer.collect_str(value)
757    }
758
759    pub fn deserialize<'de, D>(deserializer: D) -> Result<f64, D::Error>
760        where
761            D: Deserializer<'de>,
762    {
763        #[derive(Deserialize)]
764        #[serde(untagged)]
765        enum StringOrFloat {
766            String(String),
767            Float(f64),
768        }
769
770        match StringOrFloat::deserialize(deserializer)? {
771            StringOrFloat::String(s) => s.parse().map_err(de::Error::custom),
772            StringOrFloat::Float(i) => Ok(i),
773        }
774    }
775}
776