binance_async/models/
mod.rs

1mod order;
2
3pub use self::order::*;
4use crate::parser::string_or_decimal;
5use rust_decimal::Decimal;
6use serde::{Deserialize, Serialize};
7
8#[derive(Copy, Clone, Debug)]
9pub enum Product {
10    Spot,
11    UsdMFutures,
12    CoinMFutures,
13    EuropeanOptions,
14}
15
16#[derive(Serialize, Deserialize, Clone)]
17#[serde(rename_all = "camelCase")]
18pub struct ServerTime {
19    pub server_time: u64,
20}
21
22#[derive(Debug, Serialize, Deserialize, Clone)]
23#[serde(rename_all = "camelCase")]
24pub struct ExchangeInformation {
25    pub timezone: String,
26    pub server_time: u64,
27    pub rate_limits: Vec<RateLimit>,
28    pub symbols: Vec<Symbol>,
29}
30
31#[derive(Debug, Serialize, Deserialize, Clone)]
32#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
33pub enum AccountType {
34    Spot,
35}
36
37#[derive(Debug, Serialize, Deserialize, Clone)]
38#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
39pub enum Permission {
40    Spot,
41}
42
43#[derive(Debug, Serialize, Deserialize, Clone)]
44#[serde(rename_all = "camelCase")]
45pub struct AccountInformation {
46    pub maker_commission: f32,
47    pub taker_commission: f32,
48    pub buyer_commission: f32,
49    pub seller_commission: f32,
50    pub can_trade: bool,
51    pub can_withdraw: bool,
52    pub can_deposit: bool,
53    pub brokered: bool,
54    pub require_self_trade_prevention: bool,
55    pub update_time: u64,
56    pub account_type: AccountType,
57    pub permissions: Vec<Permission>,
58    pub balances: Vec<Balance>,
59}
60
61#[derive(Debug, Serialize, Deserialize, Clone)]
62#[serde(rename_all = "camelCase")]
63pub struct Balance {
64    pub asset: String,
65    #[serde(with = "string_or_decimal")]
66    pub free: Decimal,
67    #[serde(with = "string_or_decimal")]
68    pub locked: Decimal,
69}
70
71#[derive(Debug, Serialize, Deserialize, Clone)]
72pub struct Bids {
73    #[serde(with = "string_or_decimal")]
74    pub price: Decimal,
75    #[serde(with = "string_or_decimal")]
76    pub qty: Decimal,
77
78    // Never serialized.
79    #[serde(skip_serializing, rename = "ignore")]
80    _ignore: Vec<String>,
81}
82
83#[derive(Debug, Serialize, Deserialize, Clone)]
84pub struct Asks {
85    #[serde(with = "string_or_decimal")]
86    pub price: Decimal,
87    #[serde(with = "string_or_decimal")]
88    pub qty: Decimal,
89
90    // Never serialized.
91    #[serde(skip_serializing, rename = "ignore")]
92    _ignore: Vec<String>,
93}
94
95#[derive(Debug, Serialize, Deserialize, Clone)]
96#[serde(rename_all = "camelCase")]
97pub struct UserDataStream {
98    pub listen_key: String,
99}
100
101#[derive(Debug, Serialize, Deserialize, Clone)]
102pub struct Success {}
103
104#[derive(Debug, Serialize, Deserialize, Clone)]
105#[serde(rename_all = "camelCase")]
106#[serde(untagged)]
107pub enum Prices {
108    AllPrices(Vec<SymbolPrice>),
109}
110
111#[derive(Debug, Serialize, Deserialize, Clone)]
112pub struct SymbolPrice {
113    pub symbol: String,
114    #[serde(with = "string_or_decimal")]
115    pub price: Decimal,
116}
117
118#[derive(Debug, Serialize, Deserialize, Clone)]
119#[serde(rename_all = "camelCase")]
120#[serde(untagged)]
121pub enum BookTickers {
122    AllBookTickers(Vec<Ticker>),
123}
124
125#[derive(Debug, Clone)]
126pub enum KlineSummaries {
127    AllKlineSummaries(Vec<KlineSummary>),
128}
129
130#[derive(Debug, Serialize, Deserialize, Clone)]
131#[serde(rename_all = "camelCase")]
132pub struct Ticker {
133    pub symbol: String,
134    #[serde(with = "string_or_decimal")]
135    pub bid_price: Decimal,
136    #[serde(with = "string_or_decimal")]
137    pub bid_qty: Decimal,
138    #[serde(with = "string_or_decimal")]
139    pub ask_price: Decimal,
140    #[serde(with = "string_or_decimal")]
141    pub ask_qty: Decimal,
142}
143
144#[derive(Debug, Serialize, Deserialize, Clone)]
145#[serde(rename_all = "camelCase")]
146pub struct TradeHistory {
147    pub symbol: String,
148    pub id: u64,
149    pub order_id: u64,
150    #[serde(with = "string_or_decimal")]
151    pub price: Decimal,
152    #[serde(with = "string_or_decimal")]
153    pub qty: Decimal,
154    #[serde(with = "string_or_decimal")]
155    pub commission: Decimal,
156    pub commission_asset: String,
157    pub time: u64,
158    pub is_buyer: bool,
159    pub is_maker: bool,
160    pub is_best_match: bool,
161}
162
163#[derive(Debug, Serialize, Deserialize, Clone)]
164#[serde(rename_all = "camelCase")]
165pub struct PriceStats {
166    pub symbol: String,
167    #[serde(with = "string_or_decimal")]
168    pub price_change: Decimal,
169    #[serde(with = "string_or_decimal")]
170    pub price_change_percent: Decimal,
171    #[serde(with = "string_or_decimal")]
172    pub weighted_avg_price: Decimal,
173    #[serde(with = "string_or_decimal")]
174    pub prev_close_price: Decimal,
175    #[serde(with = "string_or_decimal")]
176    pub last_price: Decimal,
177    #[serde(with = "string_or_decimal")]
178    pub bid_price: Decimal,
179    #[serde(with = "string_or_decimal")]
180    pub ask_price: Decimal,
181    #[serde(with = "string_or_decimal")]
182    pub open_price: Decimal,
183    #[serde(with = "string_or_decimal")]
184    pub high_price: Decimal,
185    #[serde(with = "string_or_decimal")]
186    pub low_price: Decimal,
187    #[serde(with = "string_or_decimal")]
188    pub volume: Decimal,
189    pub open_time: u64,
190    pub close_time: u64,
191    pub first_id: i64, // For dummy symbol "123456", it is -1
192    pub last_id: i64,  // Same as above
193    pub count: u64,
194}
195
196#[derive(Debug, Clone)]
197pub struct KlineSummary {
198    pub open_time: i64,
199
200    pub open: Decimal,
201
202    pub high: Decimal,
203
204    pub low: Decimal,
205
206    pub close: Decimal,
207
208    pub volume: Decimal,
209
210    pub close_time: i64,
211
212    pub quote_asset_volume: Decimal,
213
214    pub number_of_trades: i64,
215
216    pub taker_buy_base_asset_volume: Decimal,
217
218    pub taker_buy_quote_asset_volume: Decimal,
219}
220
221#[derive(Debug, Serialize, Deserialize, Clone)]
222#[serde(rename_all = "camelCase")]
223pub struct Kline {
224    #[serde(rename = "t")]
225    pub start_time: i64,
226    #[serde(rename = "T")]
227    pub end_time: i64,
228    #[serde(rename = "s")]
229    pub symbol: String,
230    #[serde(rename = "i")]
231    pub interval: String,
232    #[serde(rename = "f")]
233    pub first_trade_id: i32,
234    #[serde(rename = "L")]
235    pub last_trade_id: i32,
236    #[serde(rename = "o")]
237    pub open: String,
238    #[serde(rename = "c")]
239    pub close: String,
240    #[serde(rename = "h")]
241    pub high: String,
242    #[serde(rename = "l")]
243    pub low: String,
244    #[serde(rename = "v")]
245    pub volume: String,
246    #[serde(rename = "n")]
247    pub number_of_trades: i32,
248    #[serde(rename = "x")]
249    pub is_final_bar: bool,
250    #[serde(rename = "q")]
251    pub quote_volume: String,
252    #[serde(rename = "V")]
253    pub active_buy_volume: String,
254    #[serde(rename = "Q")]
255    pub active_volume_buy_quote: String,
256    #[serde(skip_serializing, rename = "B")]
257    pub ignore_me: String,
258}
259//  "timezone": "UTC",
260//   "serverTime": 1508631584636,
261//   "rateLimits": [{
262//       "rateLimitType": "REQUESTS",
263//       "interval": "MINUTE",
264//       "limit": 1200
265//     },
266//     {
267//       "rateLimitType": "ORDERS",
268//       "interval": "SECOND",
269//       "limit": 10
270//     },
271//     {
272//       "rateLimitType": "ORDERS",
273//       "interval": "DAY",
274//       "limit": 100000
275//     }
276//   ],
277//   "exchangeFilters": [],
278//   "symbols": [{
279//     "symbol": "ETHBTC",
280//     "status": "TRADING",
281//     "baseAsset": "ETH",
282//     "baseAssetPrecision": 8,
283//     "quoteAsset": "BTC",
284//     "quotePrecision": 8,
285//     "orderTypes": ["LIMIT", "MARKET"],
286//     "icebergAllowed": false,
287//     "filters": [{
288//       "filterType": "PRICE_FILTER",
289//       "minPrice": "0.00000100",
290//       "maxPrice": "100000.00000000",
291//       "tickSize": "0.00000100"
292//     }, {
293//       "filterType": "LOT_SIZE",
294//       "minQty": "0.00100000",
295//       "maxQty": "100000.00000000",
296//       "stepSize": "0.00100000"
297//     }, {
298//       "filterType": "MIN_NOTIONAL",
299//       "minNotional": "0.00100000"
300//     }]
301//   }]
302// }
303
304#[derive(Debug, Serialize, Deserialize, Clone)]
305#[serde(rename_all = "camelCase")]
306pub struct ExchangeInfo {
307    pub timezone: String,
308    pub server_time: u64,
309    pub rate_limits: Vec<RateLimit>,
310    pub exchange_filters: Vec<ExchangeFilter>,
311    pub symbols: Vec<Symbol>,
312}
313
314// {
315//       "rateLimitType": "ORDERS",
316//       "interval": "DAY",
317//       "limit": 100000
318//     }
319#[derive(Debug, Serialize, Deserialize, Clone)]
320#[serde(rename_all = "camelCase")]
321pub struct RateLimit {
322    rate_limit_type: RateLimitType,
323    interval: Interval,
324    limit: u64,
325}
326
327#[derive(Debug, Serialize, Deserialize, Clone)]
328#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
329pub enum RateLimitType {
330    Orders,
331    RequestWeight,
332}
333
334#[derive(Debug, Serialize, Deserialize, Clone)]
335#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
336pub enum Interval {
337    Second,
338    Minute,
339    Day,
340}
341
342// {
343//       "filterType": "LOT_SIZE",
344//       "minQty": "0.00100000",
345//       "maxQty": "100000.00000000",
346//       "stepSize": "0.00100000"
347//     }
348#[derive(Debug, Serialize, Deserialize, Clone)]
349#[serde(tag = "filterType", rename_all = "SCREAMING_SNAKE_CASE")]
350pub enum SymbolFilter {
351    #[serde(rename_all = "camelCase")]
352    LotSize {
353        min_qty: String,
354        max_qty: String,
355        step_size: String,
356    },
357    #[serde(rename_all = "camelCase")]
358    PriceFilter {
359        min_price: String,
360        max_price: String,
361        tick_size: String,
362    },
363    #[serde(rename_all = "camelCase")]
364    MinNotional { min_notional: String },
365    #[serde(rename_all = "camelCase")]
366    MaxNumAlgoOrders { max_num_algo_orders: u64 },
367    #[serde(rename_all = "camelCase")]
368    MaxNumOrders { limit: u64 },
369    #[serde(rename_all = "camelCase")]
370    IcebergParts { limit: u64 },
371}
372
373// {
374//     "symbol": "ETHBTC",
375//     "status": "TRADING",
376//     "baseAsset": "ETH",
377//     "baseAssetPrecision": 8,
378//     "quoteAsset": "BTC",
379//     "quotePrecision": 8,
380//     "orderTypes": ["LIMIT", "MARKET"],
381//     "icebergAllowed": false,
382//     "filters": [{
383//       "filterType": "PRICE_FILTER",
384//       "minPrice": "0.00000100",
385//       "maxPrice": "100000.00000000",
386//       "tickSize": "0.00000100"
387//     }, {
388//       "filterType": "LOT_SIZE",
389//       "minQty": "0.00100000",
390//       "maxQty": "100000.00000000",
391//       "stepSize": "0.00100000"
392//     }, {
393//       "filterType": "MIN_NOTIONAL",
394//       "minNotional": "0.00100000"
395//     }]
396//   }
397#[derive(Debug, Serialize, Deserialize, Clone)]
398#[serde(tag = "filterType", rename_all = "SCREAMING_SNAKE_CASE")]
399pub enum ExchangeFilter {
400    ExchangeMaxNumOrders { limit: u64 },
401    ExchangeMaxAlgoOrders { limit: u64 },
402}
403
404#[derive(Debug, Serialize, Deserialize, Clone)]
405#[serde(rename_all = "camelCase")]
406pub struct Symbol {
407    pub symbol: String,
408    pub status: String,
409    pub base_asset: String,
410    pub base_asset_precision: u64,
411    pub quote_asset: String,
412    pub quote_precision: u64,
413    pub order_types: Vec<String>,
414    pub iceberg_allowed: bool,
415    pub filters: Vec<SymbolFilter>,
416}
417
418#[derive(Debug, Serialize, Deserialize, Clone)]
419#[serde(rename_all = "camelCase")]
420pub struct OrderBook {
421    pub last_update_id: u64,
422    pub bids: Vec<Bids>,
423    pub asks: Vec<Asks>,
424}
425
426#[derive(Serialize, Deserialize, Clone, Debug)]
427#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
428pub enum Side {
429    Buy,
430    Sell,
431}
432
433#[derive(Serialize, Deserialize, Clone, Debug)]
434#[serde(rename_all = "UPPERCASE")]
435pub enum TimeInForce {
436    GTC,
437    IOC,
438    FOK,
439    GTX,
440}
441
442impl Default for TimeInForce {
443    fn default() -> Self {
444        Self::GTC
445    }
446}
447
448#[derive(Serialize, Deserialize, Clone, Debug)]
449#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
450pub enum NewOrderResponseType {
451    Ack,
452    Result,
453}
454
455#[derive(Serialize, Deserialize, Clone, Debug)]
456#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
457pub enum OrderExecType {
458    New,
459}
460
461#[derive(Serialize, Deserialize, Clone, Debug)]
462#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
463pub enum OrderStatus {
464    New,
465    PartiallyFilled,
466    Filled,
467    Canceled,
468    PendingCancel,
469    Rejected,
470    Expired,
471}
472
473#[derive(Serialize, Deserialize, Clone, Debug)]
474#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
475pub enum OrderRejectReason {
476    None,
477}
478
479#[derive(Serialize, Deserialize, Clone, Debug)]
480#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
481pub enum ExecutionType {
482    /// The order has been accepted into the engine.
483    New,
484    /// The order has been canceled by the user.
485    Canceled,
486    /// Liquidation Execution (Futures only)
487    Calculated,
488    /// (currently unused)
489    Replaced,
490    /// The order has been rejected and was not processed (This message appears only with Cancel Replace Orders wherein the new order placement is rejected but the request to cancel request succeeds.)
491    Rejected,
492    /// Part of the order or all of the order's quantity has filled.
493    Trade,
494    /// The order was canceled according to the order type's rules (e.g. LIMIT FOK orders with no fill, LIMIT IOC or MARKET orders that partially fill) or by the exchange, (e.g. orders canceled during liquidation, orders canceled during maintenance).
495    Expired,
496    /// The order has expired due to STP trigger.
497    TradePrevention,
498}