1#![allow(unused_imports)]
2use crate::errors::BybitError;
3use serde::{Deserialize, Serialize};
4use serde_json::{from_value, Value};
5use std::{borrow::Cow, collections::BTreeMap};
6use thiserror::Error;
7
8#[derive(Serialize, Default, Deserialize, Clone, Debug)]
9pub struct Empty {}
10
11#[derive(Serialize, Deserialize, Clone, Debug)]
16#[serde(rename_all = "camelCase")]
17pub struct ServerTimeResponse {
18 #[serde(rename = "retCode")]
19 pub ret_code: i16,
20 #[serde(rename = "retMsg")]
21 pub ret_msg: String,
22 pub result: ServerTime,
23 #[serde(rename = "retExtInfo")]
24 pub ret_ext_info: Empty,
25 pub time: u64,
26}
27
28#[derive(Serialize, Deserialize, Clone, Debug)]
29#[serde(rename_all = "camelCase")]
30pub struct ServerTime {
31 #[serde(with = "string_to_u64")]
32 pub time_second: u64,
33 #[serde(with = "string_to_u64")]
34 pub time_nano: u64,
35}
36
37#[derive(Clone, Default)]
38pub struct KlineRequest<'a> {
39 pub category: Option<Category>,
40 pub symbol: Cow<'a, str>,
41 pub interval: Cow<'a, str>,
42 pub start: Option<Cow<'a, str>>,
43 pub end: Option<Cow<'a, str>>,
44 pub limit: Option<u64>,
45}
46
47impl<'a> KlineRequest<'a> {
48 pub fn default() -> KlineRequest<'a> {
49 KlineRequest::new(None, "BTCUSDT", "", None, None, None)
50 }
51 pub fn new(
52 category: Option<Category>,
53 symbol: &'a str,
54 interval: &'a str,
55 start: Option<&'a str>,
56 end: Option<&'a str>,
57 limit: Option<u64>,
58 ) -> KlineRequest<'a> {
59 KlineRequest {
60 category: category,
61 symbol: Cow::Borrowed(symbol),
62 interval: Cow::Borrowed(interval),
63 start: start.map(|s| Cow::Borrowed(s)),
64 end: end.map(|s| Cow::Borrowed(s)),
65 limit,
66 }
67 }
68}
69#[derive(Serialize, Deserialize, Clone, Debug)]
70#[serde(rename_all = "camelCase")]
71pub struct KlineResponse {
72 #[serde(rename = "retCode")]
73 pub ret_code: i16,
74 #[serde(rename = "retMsg")]
75 pub ret_msg: String,
76 pub result: KlineSummary,
77 #[serde(rename = "retExtInfo")]
78 pub ret_ext_info: Empty,
79 pub time: u64,
80}
81
82#[derive(Serialize, Deserialize, Clone, Debug)]
83#[serde(rename_all = "camelCase")]
84pub struct KlineSummary {
85 pub symbol: String,
86 pub category: String,
87 pub list: Vec<Kline>,
88}
89
90#[derive(Serialize, Deserialize, Clone, Debug)]
91#[serde(rename_all = "camelCase")]
92pub struct Kline {
93 #[serde(with = "string_to_u64")]
94 pub start_time: u64,
95 pub open_price: String,
96 pub high_price: String,
97 pub low_price: String,
98 pub close_price: String,
99 pub volume: String,
100 pub quote_asset_volume: String,
101}
102
103#[derive(Serialize, Deserialize, Clone, Debug)]
104#[serde(rename_all = "camelCase")]
105pub struct MarkPriceKlineResponse {
106 #[serde(rename = "retCode")]
107 pub ret_code: i16,
108 #[serde(rename = "retMsg")]
109 pub ret_msg: String,
110 pub result: MarkPriceKlineSummary,
111 #[serde(rename = "retExtInfo")]
112 pub ret_ext_info: Empty,
113 pub time: u64,
114}
115
116#[derive(Serialize, Deserialize, Clone, Debug)]
117#[serde(rename_all = "camelCase")]
118pub struct MarkPriceKlineSummary {
119 pub symbol: String,
120 pub category: String,
121 pub list: Vec<MarkPriceKline>,
122}
123
124#[derive(Serialize, Deserialize, Clone, Debug)]
125#[serde(rename_all = "camelCase")]
126pub struct MarkPriceKline {
127 #[serde(with = "string_to_u64")]
128 pub start_time: u64,
129 pub open_price: String,
130 pub high_price: String,
131 pub low_price: String,
132 pub close_price: String,
133}
134
135#[derive(Serialize, Deserialize, Clone, Debug)]
136#[serde(rename_all = "camelCase")]
137pub struct IndexPriceKlineResponse {
138 #[serde(rename = "retCode")]
139 pub ret_code: i16,
140 #[serde(rename = "retMsg")]
141 pub ret_msg: String,
142 pub result: IndexPriceKlineSummary,
143 #[serde(rename = "retExtInfo")]
144 pub ret_ext_info: Empty,
145 pub time: u64,
146}
147
148#[derive(Serialize, Deserialize, Clone, Debug)]
149#[serde(rename_all = "camelCase")]
150pub struct IndexPriceKlineSummary {
151 pub symbol: String,
152 pub category: String,
153 pub list: Vec<IndexPriceKline>,
154}
155
156#[derive(Serialize, Deserialize, Clone, Debug)]
157#[serde(rename_all = "camelCase")]
158pub struct IndexPriceKline {
159 #[serde(with = "string_to_u64")]
160 pub start_time: u64,
161 pub open_price: String,
162 pub high_price: String,
163 pub low_price: String,
164 pub close_price: String,
165}
166
167#[derive(Serialize, Deserialize, Clone, Debug)]
168#[serde(rename_all = "camelCase")]
169pub struct PremiumIndexPriceKlineResponse {
170 #[serde(rename = "retCode")]
171 pub ret_code: i16,
172 #[serde(rename = "retMsg")]
173 pub ret_msg: String,
174 pub result: PremiumIndexPriceKlineSummary,
175 #[serde(rename = "retExtInfo")]
176 pub ret_ext_info: Empty,
177 pub time: u64,
178}
179
180#[derive(Serialize, Deserialize, Clone, Debug)]
181#[serde(rename_all = "camelCase")]
182pub struct PremiumIndexPriceKlineSummary {
183 pub symbol: String,
184 pub category: String,
185 pub list: Vec<PremiumIndexPriceKline>,
186}
187
188#[derive(Serialize, Deserialize, Clone, Debug)]
189#[serde(rename_all = "camelCase")]
190pub struct PremiumIndexPriceKline {
191 #[serde(with = "string_to_u64")]
192 pub start_time: u64,
193 pub open_price: String,
194 pub high_price: String,
195 pub low_price: String,
196 pub close_price: String,
197}
198
199#[derive(Clone, Default)]
200pub struct InstrumentRequest<'a> {
201 pub category: Category,
202 pub symbol: Option<Cow<'a, str>>,
203 pub status: Option<bool>,
204 pub base_coin: Option<Cow<'a, str>>,
205 pub limit: Option<u64>,
206}
207impl<'a> InstrumentRequest<'a> {
208 pub fn default() -> InstrumentRequest<'a> {
209 InstrumentRequest::new(Category::Linear, Some("BTCUSDT"), None, None, None)
210 }
211 pub fn new(
212 category: Category,
213 symbol: Option<&'a str>,
214 status: Option<bool>,
215 base_coin: Option<&'a str>,
216 limit: Option<u64>,
217 ) -> InstrumentRequest<'a> {
218 InstrumentRequest {
219 category: category,
220 symbol: symbol.map(|s| Cow::Borrowed(s)),
221 status: status,
222 base_coin: base_coin.map(|s| Cow::Borrowed(s)),
223 limit,
224 }
225 }
226}
227
228#[derive(Serialize, Deserialize, Clone, Debug)]
229#[serde(rename_all = "camelCase")]
230pub struct FuturesInstrumentsInfoResponse {
231 #[serde(rename = "retCode")]
232 pub ret_code: i16,
233 #[serde(rename = "retMsg")]
234 pub ret_msg: String,
235 pub result: FuturesInstrumentsInfo,
236 #[serde(rename = "retExtInfo")]
237 pub ret_ext_info: Empty,
238 pub time: u64,
239}
240
241#[derive(Serialize, Deserialize, Clone, Debug)]
242#[serde(rename_all = "camelCase")]
243pub struct FuturesInstrumentsInfo {
244 pub category: String,
245 pub list: Vec<FuturesInstrument>,
246 #[serde(rename = "nextPageCursor", skip_serializing_if = "String::is_empty")]
247 pub next_page_cursor: String,
248}
249
250#[derive(Serialize, Deserialize, Clone, Debug)]
251#[serde(rename_all = "camelCase")]
252pub struct FuturesInstrument {
253 pub symbol: String,
254 #[serde(rename = "contractType")]
255 pub contract_type: String,
256 pub status: String,
257 #[serde(rename = "baseCoin")]
258 pub base_coin: String,
259 #[serde(rename = "quoteCoin")]
260 pub quote_coin: String,
261 #[serde(rename = "launchTime", with = "string_to_u64")]
262 pub launch_time: u64,
263 #[serde(rename = "deliveryTime", skip_serializing_if = "String::is_empty")]
264 pub delivery_time: String,
265 #[serde(rename = "deliveryFeeRate")]
266 pub delivery_fee_rate: String,
267 #[serde(rename = "priceScale")]
268 pub price_scale: String,
269 #[serde(rename = "leverageFilter")]
270 pub leverage_filter: LeverageFilter,
271 #[serde(rename = "priceFilter")]
272 pub price_filter: PriceFilter,
273 #[serde(rename = "lotSizeFilter")]
274 pub lot_size_filter: LotSizeFilter,
275 #[serde(rename = "unifiedMarginTrade")]
276 pub unified_margin_trade: bool,
277 #[serde(rename = "fundingInterval")]
278 pub funding_interval: u64,
279 #[serde(rename = "settleCoin")]
280 pub settle_coin: String,
281 #[serde(rename = "copyTrading")]
282 pub copy_trading: String,
283 #[serde(rename = "upperFundingRate")]
284 pub upper_funding_rate: String,
285 #[serde(rename = "lowerFundingRate")]
286 pub lower_funding_rate: String,
287 }
292
293#[derive(Serialize, Deserialize, Clone, Debug)]
294#[serde(rename_all = "camelCase")]
295pub struct SpotInstrumentsInfoResponse {
296 #[serde(rename = "retCode")]
297 pub ret_code: i16,
298 #[serde(rename = "retMsg")]
299 pub ret_msg: String,
300 pub result: SpotInstrumentsInfo,
301 #[serde(rename = "retExtInfo")]
302 pub ret_ext_info: Empty,
303 pub time: u64,
304}
305
306#[derive(Serialize, Deserialize, Clone, Debug)]
307#[serde(rename_all = "camelCase")]
308pub struct SpotInstrumentsInfo {
309 pub category: String,
310 pub list: Vec<SpotInstrument>,
311 #[serde(rename = "nextPageCursor", skip_serializing_if = "String::is_empty")]
312 pub next_page_cursor: String,
313}
314#[derive(Serialize, Deserialize, Clone, Debug)]
315#[serde(rename_all = "camelCase")]
316pub struct SpotInstrument {
317 pub symbol: String,
318 #[serde(rename = "baseCoin")]
319 pub base_coin: String,
320 #[serde(rename = "quoteCoin")]
321 pub quote_coin: String,
322 pub innovation: String,
323 pub status: String,
324 #[serde(rename = "marginTrading")]
325 pub margin_trading: String,
326 #[serde(rename = "lotSizeFilter")]
327 pub lot_size_filter: LotSizeFilter,
328 #[serde(rename = "priceFilter")]
329 pub price_filter: PriceFilter,
330 #[serde(rename = "riskParameters")]
331 pub risk_parameters: RiskParameters,
332}
333
334#[derive(Serialize, Deserialize, Clone, Debug)]
335#[serde(rename_all = "camelCase")]
336pub struct OptionsInstrument {
337 pub symbol: String,
338 pub status: String,
339 #[serde(rename = "baseCoin")]
340 pub base_coin: String,
341 #[serde(rename = "quoteCoin")]
342 pub quote_coin: String,
343 #[serde(rename = "settleCoin")]
344 pub settle_coin: String,
345 #[serde(rename = "optionType")]
346 pub option_type: String,
347 #[serde(rename = "launchTime", with = "string_to_u64")]
348 pub launch_time: u64,
349 #[serde(rename = "deliveryTime", with = "string_to_u64")]
350 pub delivery_time: u64,
351 #[serde(rename = "deliveryFeeRate")]
352 pub delivery_fee_rate: String,
353 #[serde(rename = "priceFilter")]
354 pub price_filter: PriceFilter,
355 #[serde(rename = "lotSizeFilter")]
356 pub lot_size_filter: LotSizeFilter,
357}
358
359#[derive(Serialize, Deserialize, Clone, Debug)]
360#[serde(rename_all = "camelCase")]
361pub struct PreListingInfo {
362 pub cur_auction_phase: String,
363 pub phases: Vec<PreListingPhase>,
364 pub auction_fee_info: AuctionFeeInfo,
365}
366
367#[derive(Serialize, Deserialize, Clone, Debug)]
368#[serde(rename_all = "camelCase")]
369pub struct PreListingPhase {
370 pub phase: String,
371 #[serde(rename = "startTime", with = "string_to_u64")]
372 pub start_time: u64,
373 #[serde(rename = "endTime", with = "string_to_u64")]
374 pub end_time: u64,
375}
376
377#[derive(Serialize, Deserialize, Clone, Debug)]
378#[serde(rename_all = "camelCase")]
379pub struct AuctionFeeInfo {
380 pub auction_fee_rate: String,
381 pub taker_fee_rate: String,
382 pub maker_fee_rate: String,
383}
384
385#[derive(Debug, Serialize, Deserialize, Clone)]
386#[serde(rename_all = "camelCase")]
387pub struct RiskParameters {
388 #[serde(rename = "limitParameter")]
389 pub limit_parameter: String,
390 #[serde(rename = "marketParameter")]
391 pub market_parameter: String,
392}
393
394#[derive(Debug, Serialize, Deserialize, Clone)]
395#[serde(rename_all = "camelCase")]
396pub struct LeverageFilter {
397 #[serde(rename = "minLeverage")]
398 pub min_leverage: String,
399 #[serde(rename = "maxLeverage")]
400 pub max_leverage: String,
401 #[serde(rename = "leverageStep")]
402 pub leverage_step: String,
403}
404
405#[derive(Debug, Serialize, Deserialize, Clone)]
406#[serde(rename_all = "camelCase")]
407pub struct PriceFilter {
408 #[serde(rename = "minPrice")]
409 pub min_price: Option<String>,
410 #[serde(rename = "maxPrice")]
411 pub max_price: Option<String>,
412 #[serde(rename = "tickSize", with = "string_to_float")]
413 pub tick_size: f64,
414}
415
416#[derive(Debug, Serialize, Deserialize, Clone)]
417#[serde(rename_all = "camelCase")]
418pub struct LotSizeFilter {
419 #[serde(rename = "basePrecision", skip_serializing_if = "Option::is_none", default)]
420 pub base_precision: Option<String>,
421 #[serde(rename = "quotePrecision", skip_serializing_if = "Option::is_none")]
422 pub quote_precision: Option<String>,
423 #[serde(rename = "maxMktOrderQty", skip_serializing_if = "Option::is_none")]
424 pub max_mkt_order_qty: Option<String>,
425 #[serde(rename = "minOrderQty", with = "string_to_float")]
426 pub min_order_qty: f64,
427 #[serde(rename = "maxOrderQty", with = "string_to_float")]
428 pub max_order_qty: f64,
429 #[serde(rename = "minOrderAmt", skip_serializing_if = "Option::is_none")]
430 pub min_order_amt: Option<String>,
431 #[serde(rename = "maxOrderAmt", skip_serializing_if = "Option::is_none")]
432 pub max_order_amt: Option<String>,
433 #[serde(rename = "qtyStep", skip_serializing_if = "Option::is_none")]
434 pub qty_step: Option<String>,
435 #[serde(
436 rename = "postOnlyMaxOrderQty",
437 skip_serializing_if = "Option::is_none"
438 )]
439 pub post_only_max_order_qty: Option<String>,
440 #[serde(rename = "minNotionalValue", skip_serializing_if = "Option::is_none")]
441 pub min_notional_value: Option<String>,
442}
443
444#[derive(Clone, Default)]
445pub struct OrderbookRequest<'a> {
446 pub symbol: Cow<'a, str>,
447 pub category: Category,
448 pub limit: Option<u64>,
449}
450
451impl<'a> OrderbookRequest<'a> {
452 pub fn default() -> OrderbookRequest<'a> {
453 OrderbookRequest::new("BTCUSDT", Category::Linear, None)
454 }
455
456 pub fn new(symbol: &'a str, category: Category, limit: Option<u64>) -> OrderbookRequest<'a> {
457 OrderbookRequest {
458 symbol: Cow::Borrowed(symbol),
459 category,
460 limit,
461 }
462 }
463}
464#[derive(Serialize, Deserialize, Clone, Debug)]
465#[serde(rename_all = "camelCase")]
466pub struct OrderBookResponse {
467 #[serde(rename = "retCode")]
468 pub ret_code: i16,
469 #[serde(rename = "retMsg")]
470 pub ret_msg: String,
471 pub result: OrderBook,
472 #[serde(rename = "retExtInfo")]
473 pub ret_ext_info: Empty,
474 pub time: u64,
475}
476
477#[derive(Serialize, Deserialize, Clone, Debug)]
478#[serde(rename_all = "camelCase")]
479pub struct OrderBook {
480 #[serde(rename = "s")]
481 pub symbol: String,
482 #[serde(rename = "a")]
483 pub asks: Vec<Ask>,
484 #[serde(rename = "b")]
485 pub bids: Vec<Bid>,
486 #[serde(rename = "ts")]
487 pub timestamp: u64,
488 #[serde(rename = "u")]
489 pub update_id: u64,
490}
491
492#[derive(Serialize, Deserialize, Clone, Debug)]
493#[serde(rename_all = "camelCase")]
494pub struct Ask {
495 #[serde(with = "string_to_float")]
496 pub price: f64,
497 #[serde(with = "string_to_float")]
498 pub qty: f64,
499}
500
501#[derive(Serialize, Deserialize, Clone, Debug)]
502#[serde(rename_all = "camelCase")]
503pub struct Bid {
504 #[serde(with = "string_to_float")]
505 pub price: f64,
506 #[serde(with = "string_to_float")]
507 pub qty: f64,
508}
509
510impl Bid {
511 pub fn new(price: f64, qty: f64) -> Bid {
512 Bid { price, qty }
513 }
514}
515impl Ask {
516 pub fn new(price: f64, qty: f64) -> Ask {
517 Ask { price, qty }
518 }
519}
520
521#[derive(Serialize, Deserialize, Clone, Debug)]
522#[serde(rename_all = "camelCase")]
523pub struct FuturesTickersResponse {
524 #[serde(rename = "retCode")]
525 pub ret_code: i16,
526 #[serde(rename = "retMsg")]
527 pub ret_msg: String,
528 pub result: FuturesTickers,
529 #[serde(rename = "retExtInfo")]
530 pub ret_ext_info: Empty,
531 pub time: u64,
532}
533#[derive(Serialize, Deserialize, Clone, Debug)]
534#[serde(rename_all = "camelCase")]
535pub struct SpotTickersResponse {
536 #[serde(rename = "retCode")]
537 pub ret_code: i16,
538 #[serde(rename = "retMsg")]
539 pub ret_msg: String,
540 pub result: SpotTickers,
541 #[serde(rename = "retExtInfo")]
542 pub ret_ext_info: Empty,
543 pub time: u64,
544}
545
546#[derive(Serialize, Deserialize, Clone, Debug)]
547#[serde(rename_all = "camelCase")]
548pub struct FuturesTickers {
549 pub category: String,
550 pub list: Vec<FuturesTicker>,
551}
552
553#[derive(Serialize, Deserialize, Clone, Debug)]
554#[serde(rename_all = "camelCase")]
555pub struct SpotTickers {
556 pub category: String,
557 pub list: Vec<SpotTicker>,
558}
559
560#[derive(Serialize, Deserialize, Clone, Debug)]
561#[serde(rename_all = "camelCase")]
562pub struct FuturesTicker {
563 pub symbol: String,
564 #[serde(with = "string_to_float")]
565 pub last_price: f64,
566 #[serde(with = "string_to_float")]
567 pub index_price: f64,
568 #[serde(with = "string_to_float")]
569 pub mark_price: f64,
570 #[serde(rename = "prevPrice24h", with = "string_to_float")]
571 pub prev_price_24h: f64,
572 #[serde(rename = "price24hPcnt", with = "string_to_float")]
573 pub daily_change_percentage: f64,
574 #[serde(rename = "highPrice24h", with = "string_to_float")]
575 pub high_24h: f64,
576 #[serde(rename = "lowPrice24h", with = "string_to_float")]
577 pub low_24h: f64,
578 #[serde(rename = "prevPrice1h", with = "string_to_float")]
579 pub prev_price_1h: f64,
580 #[serde(with = "string_to_float")]
581 pub open_interest: f64,
582 #[serde(with = "string_to_float")]
583 pub open_interest_value: f64,
584 #[serde(rename = "turnover24h")]
585 pub turnover_24h: String,
586 #[serde(rename = "volume24h")]
587 pub volume_24h: String,
588 pub funding_rate: String,
589 #[serde(rename = "nextFundingTime", with = "string_to_u64")]
590 pub next_funding_time: u64,
591 #[serde(skip_serializing_if = "String::is_empty")]
592 pub predicted_delivery_price: String,
593 #[serde(skip_serializing_if = "String::is_empty")]
594 pub basis_rate: String,
595 pub delivery_fee_rate: String,
596 #[serde(rename = "deliveryTime", with = "string_to_u64")]
597 pub delivery_time: u64,
598 #[serde(rename = "ask1Size", with = "string_to_float")]
599 pub ask_size: f64,
600 #[serde(rename = "bid1Price", with = "string_to_float")]
601 pub bid_price: f64,
602 #[serde(rename = "ask1Price", with = "string_to_float")]
603 pub ask_price: f64,
604 #[serde(rename = "bid1Size", with = "string_to_float")]
605 pub bid_size: f64,
606 #[serde(skip_serializing_if = "String::is_empty")]
607 pub basis: String,
608}
609
610#[derive(Serialize, Deserialize, Clone, Debug)]
611#[serde(rename_all = "camelCase")]
612pub struct SpotTicker {
613 pub symbol: String,
614 #[serde(rename = "bid1Price", with = "string_to_float")]
615 pub bid_price: f64,
616 #[serde(rename = "bid1Size", with = "string_to_float")]
617 pub bid_size: f64,
618 #[serde(rename = "ask1Price", with = "string_to_float")]
619 pub ask_price: f64,
620 #[serde(rename = "ask1Size", with = "string_to_float")]
621 pub ask_size: f64,
622 #[serde(with = "string_to_float")]
623 pub last_price: f64,
624 #[serde(rename = "prevPrice24h", with = "string_to_float")]
625 pub prev_price_24h: f64,
626 #[serde(rename = "price24hPcnt", with = "string_to_float")]
627 pub daily_change_percentage: f64,
628 #[serde(rename = "highPrice24h", with = "string_to_float")]
629 pub high_24h: f64,
630 #[serde(rename = "lowPrice24h", with = "string_to_float")]
631 pub low_24h: f64,
632 #[serde(rename = "turnover24h")]
633 pub turnover_24h: String,
634 #[serde(rename = "volume24h")]
635 pub volume_24h: String,
636 #[serde(rename = "usdIndexPrice")]
637 pub usd_index_price: String,
638}
639
640#[derive(Clone, Default)]
641pub struct FundingHistoryRequest<'a> {
642 pub category: Category,
643 pub symbol: Cow<'a, str>,
644 pub start_time: Option<Cow<'a, str>>,
645 pub end_time: Option<Cow<'a, str>>,
646 pub limit: Option<u64>,
647}
648impl<'a> FundingHistoryRequest<'a> {
649 pub fn default() -> FundingHistoryRequest<'a> {
650 FundingHistoryRequest::new(Category::Linear, "BTCUSDT", None, None, None)
651 }
652 pub fn new(
653 category: Category,
654 symbol: &'a str,
655 start_time: Option<&'a str>,
656 end_time: Option<&'a str>,
657 limit: Option<u64>,
658 ) -> FundingHistoryRequest<'a> {
659 FundingHistoryRequest {
660 category,
661 symbol: Cow::Borrowed(symbol),
662 start_time: start_time.map(|s| Cow::Borrowed(s)),
663 end_time: end_time.map(|s| Cow::Borrowed(s)),
664 limit,
665 }
666 }
667}
668
669#[derive(Serialize, Deserialize, Clone, Debug)]
670#[serde(rename_all = "camelCase")]
671pub struct FundingRateResponse {
672 #[serde(rename = "retCode")]
673 pub ret_code: i16,
674 #[serde(rename = "retMsg")]
675 pub ret_msg: String,
676 pub result: FundingRateSummary,
677 #[serde(rename = "retExtInfo")]
678 pub ret_ext_info: Empty,
679 pub time: u64,
680}
681
682#[derive(Serialize, Deserialize, Clone, Debug)]
683#[serde(rename_all = "camelCase")]
684pub struct FundingRateSummary {
685 pub category: String,
686 pub list: Vec<FundingRate>,
687}
688
689#[derive(Serialize, Deserialize, Clone, Debug)]
690#[serde(rename_all = "camelCase")]
691pub struct FundingRate {
692 pub symbol: String,
693 #[serde(rename = "fundingRate", with = "string_to_float")]
694 pub funding_rate: f64,
695 #[serde(rename = "fundingRateTimestamp", with = "string_to_u64")]
696 pub funding_rate_timestamp: u64,
697}
698
699#[derive(Clone, Default)]
700pub struct RecentTradesRequest<'a> {
701 pub category: Category,
702 pub symbol: Option<Cow<'a, str>>,
703 pub base_coin: Option<Cow<'a, str>>,
704 pub limit: Option<u64>,
705}
706impl<'a> RecentTradesRequest<'a> {
707 pub fn default() -> RecentTradesRequest<'a> {
708 RecentTradesRequest::new(Category::Linear, Some("BTCUSDT"), None, None)
709 }
710 pub fn new(
711 category: Category,
712 symbol: Option<&'a str>,
713 base_coin: Option<&'a str>,
714 limit: Option<u64>,
715 ) -> RecentTradesRequest<'a> {
716 RecentTradesRequest {
717 category,
718 symbol: symbol.map(|s| Cow::Borrowed(s)),
719 base_coin: base_coin.map(|s| Cow::Borrowed(s)),
720 limit,
721 }
722 }
723}
724
725#[derive(Serialize, Deserialize, Clone, Debug)]
726#[serde(rename_all = "camelCase")]
727pub struct RecentTradesResponse {
728 #[serde(rename = "retCode")]
729 pub ret_code: i16,
730 #[serde(rename = "retMsg")]
731 pub ret_msg: String,
732 pub result: RecentTrades,
733 #[serde(rename = "retExtInfo")]
734 pub ret_ext_info: Empty,
735 pub time: u64,
736}
737
738#[derive(Serialize, Deserialize, Clone, Debug)]
739#[serde(rename_all = "camelCase")]
740pub struct RecentTrades {
741 pub category: String,
742 pub list: Vec<RecentTrade>,
743}
744
745#[derive(Serialize, Deserialize, Clone, Debug)]
746#[serde(rename_all = "camelCase")]
747pub struct RecentTrade {
748 #[serde(rename = "execId")]
749 pub exec_id: String,
750 pub symbol: String,
751 #[serde(with = "string_to_float")]
752 pub price: f64,
753 #[serde(rename = "size", with = "string_to_float")]
754 pub qty: f64,
755 pub side: String,
756 #[serde(rename = "time")]
757 pub timestamp: String,
758 #[serde(rename = "isBlockTrade")]
759 pub is_block_trade: bool,
760}
761
762#[derive(Clone, Default)]
763pub struct OpenInterestRequest<'a> {
764 pub category: Category,
765 pub symbol: Cow<'a, str>,
766 pub interval: Cow<'a, str>,
767 pub start: Option<Cow<'a, str>>,
768 pub end: Option<Cow<'a, str>>,
769 pub limit: Option<u64>,
770}
771
772impl<'a> OpenInterestRequest<'a> {
773 pub fn default() -> OpenInterestRequest<'a> {
774 OpenInterestRequest::new(Category::Linear, "BTCUSDT", "4h", None, None, None)
775 }
776 pub fn new(
777 category: Category,
778 symbol: &'a str,
779 interval: &'a str,
780 start: Option<&'a str>,
781 end: Option<&'a str>,
782 limit: Option<u64>,
783 ) -> OpenInterestRequest<'a> {
784 OpenInterestRequest {
785 category,
786 symbol: Cow::Borrowed(symbol),
787 interval: Cow::Borrowed(interval),
788 start: start.map(|s| Cow::Borrowed(s)),
789 end: end.map(|s| Cow::Borrowed(s)),
790 limit,
791 }
792 }
793}
794#[derive(Serialize, Deserialize, Clone, Debug)]
795#[serde(rename_all = "camelCase")]
796pub struct OpeninterestResponse {
797 #[serde(rename = "retCode")]
798 pub ret_code: i16,
799 #[serde(rename = "retMsg")]
800 pub ret_msg: String,
801 pub result: OpenInterestSummary,
802 #[serde(rename = "retExtInfo")]
803 pub ret_ext_info: Empty,
804 pub time: u64,
805}
806
807#[derive(Serialize, Deserialize, Clone, Debug)]
808#[serde(rename_all = "camelCase")]
809pub struct OpenInterestSummary {
810 pub symbol: String,
811 pub category: String,
812 pub list: Vec<OpenInterest>,
813 #[serde(rename = "nextPageCursor", skip_serializing_if = "String::is_empty")]
814 pub next_page_cursor: String,
815}
816
817#[derive(Serialize, Deserialize, Clone, Debug)]
818#[serde(rename_all = "camelCase")]
819pub struct OpenInterest {
820 #[serde(rename = "openInterest", with = "string_to_float")]
821 pub open_interest: f64,
822 #[serde(with = "string_to_u64")]
823 pub timestamp: u64,
824}
825
826#[derive(Clone, Default)]
827pub struct HistoricalVolatilityRequest<'a> {
828 pub base_coin: Option<Cow<'a, str>>,
829 pub period: Option<Cow<'a, str>>,
830 pub start: Option<Cow<'a, str>>,
831 pub end: Option<Cow<'a, str>>,
832}
833
834impl<'a> HistoricalVolatilityRequest<'a> {
835 pub fn default() -> HistoricalVolatilityRequest<'a> {
836 HistoricalVolatilityRequest::new(Some("BTC"), None, None, None)
837 }
838 pub fn new(
839 base_coin: Option<&'a str>,
840 period: Option<&'a str>,
841 start: Option<&'a str>,
842 end: Option<&'a str>,
843 ) -> HistoricalVolatilityRequest<'a> {
844 HistoricalVolatilityRequest {
845 base_coin: base_coin.map(|s| Cow::Borrowed(s)),
846 period: period.map(|s| Cow::Borrowed(s)),
847 start: start.map(|s| Cow::Borrowed(s)),
848 end: end.map(|s| Cow::Borrowed(s)),
849 }
850 }
851}
852
853#[derive(Serialize, Deserialize, Clone, Debug)]
854#[serde(rename_all = "camelCase")]
855pub struct HistoricalVolatilityResponse {
856 #[serde(rename = "retCode")]
857 pub ret_code: i16,
858 #[serde(rename = "retMsg")]
859 pub ret_msg: String,
860 pub category: String,
861 #[serde(rename = "result")]
862 pub result: Vec<HistoricalVolatility>,
863}
864
865#[derive(Serialize, Deserialize, Clone, Debug)]
866#[serde(rename_all = "camelCase")]
867pub struct HistoricalVolatility {
868 pub period: u64,
869 #[serde(with = "string_to_float")]
870 pub value: f64,
871 #[serde(rename = "time", with = "string_to_u64")]
872 pub timestamp: u64,
873}
874
875#[derive(Serialize, Deserialize, Clone, Debug)]
876#[serde(rename_all = "camelCase")]
877pub struct InsuranceResponse {
878 #[serde(rename = "retCode")]
879 pub ret_code: i16,
880 #[serde(rename = "retMsg")]
881 pub ret_msg: String,
882 pub result: InsuranceSummary,
883 #[serde(rename = "retExtInfo")]
884 pub ret_ext_info: Empty,
885 pub time: u64,
886}
887
888#[derive(Serialize, Deserialize, Clone, Debug)]
889#[serde(rename_all = "camelCase")]
890pub struct InsuranceSummary {
891 #[serde(rename = "updatedTime", with = "string_to_u64")]
892 pub updated_time: u64,
893 pub list: Vec<Insurance>,
894}
895
896#[derive(Serialize, Deserialize, Clone, Debug)]
897#[serde(rename_all = "camelCase")]
898pub struct Insurance {
899 pub coin: String,
900 #[serde(with = "string_to_float")]
901 pub balance: f64,
902 pub value: String,
903}
904
905#[derive(Clone, Default)]
906pub struct RiskLimitRequest<'a> {
907 pub category: Category,
908 pub symbol: Option<Cow<'a, str>>,
909}
910
911impl<'a> RiskLimitRequest<'a> {
912 pub fn default() -> RiskLimitRequest<'a> {
913 RiskLimitRequest::new(Category::Linear, None)
914 }
915 pub fn new(category: Category, symbol: Option<&'a str>) -> RiskLimitRequest<'a> {
916 RiskLimitRequest {
917 category,
918 symbol: symbol.map(|s| Cow::Borrowed(s)),
919 }
920 }
921}
922
923#[derive(Serialize, Deserialize, Clone, Debug)]
924pub struct RiskLimitResponse {
925 #[serde(rename = "retCode")]
926 pub ret_code: i16,
927 #[serde(rename = "retMsg")]
928 pub ret_msg: String,
929 pub result: RiskLimitSummary,
930 #[serde(rename = "retExtInfo")]
931 pub ret_ext_info: Empty,
932 pub time: u64,
933}
934
935#[derive(Serialize, Deserialize, Clone, Debug)]
936pub struct RiskLimitSummary {
937 pub category: String,
938 pub list: Vec<RiskLimit>,
939}
940
941#[derive(Serialize, Deserialize, Clone, Debug)]
942pub struct RiskLimit {
943 pub id: u64,
944 pub symbol: String,
945 #[serde(rename = "riskLimitValue", with = "string_to_float")]
946 pub risk_limit_value: f64,
947 #[serde(rename = "maintenanceMargin", with = "string_to_float")]
948 pub maintainence_margin: f64,
949 #[serde(rename = "initialMargin", with = "string_to_float")]
950 pub initial_margin: f64,
951 #[serde(rename = "isLowestRisk")]
952 pub is_lowest_risk: u8,
953 #[serde(rename = "maxLeverage")]
954 pub max_leverage: String,
955}
956
957#[derive(Serialize, Deserialize, Clone, Debug)]
958#[serde(rename_all = "camelCase")]
959pub struct DeliveryPriceResponse {
960 pub ret_code: i16,
961 pub ret_msg: String,
962 pub result: DeliveryPriceSummary,
963 pub ret_ext_info: Empty,
964 pub time: u64,
965}
966
967#[derive(Serialize, Deserialize, Clone, Debug)]
968#[serde(rename_all = "camelCase")]
969pub struct DeliveryPriceSummary {
970 pub category: String,
971 #[serde(rename = "nextPageCursor", skip_serializing_if = "Option::is_none")]
972 pub next_page_cursor: Option<String>,
973 pub list: Vec<DeliveryPrice>,
974}
975
976#[derive(Serialize, Deserialize, Clone, Debug)]
977#[serde(rename_all = "camelCase")]
978pub struct DeliveryPrice {
979 pub symbol: String,
980 pub delivery_price: String,
981 #[serde(with = "string_to_u64")]
982 pub delivery_time: u64,
983}
984
985#[derive(Serialize, Deserialize, Clone, Debug)]
986#[serde(rename_all = "camelCase")]
987pub struct LongShortRatioResponse {
988 #[serde(rename = "retCode")]
989 pub ret_code: i16,
990 #[serde(rename = "retMsg")]
991 pub ret_msg: String,
992 pub result: LongShortRatioSummary,
993 #[serde(rename = "retExtInfo")]
994 pub ret_ext_info: Empty,
995 pub time: u64,
996}
997
998#[derive(Serialize, Deserialize, Clone, Debug)]
999#[serde(rename_all = "camelCase")]
1000pub struct LongShortRatioSummary {
1001 pub list: Vec<LongShortRatio>,
1002}
1003
1004#[derive(Serialize, Deserialize, Clone, Debug)]
1005#[serde(rename_all = "camelCase")]
1006pub struct LongShortRatio {
1007 #[serde(rename = "symbol")]
1008 pub symbol: String,
1009 #[serde(rename = "buyRatio", with = "string_to_float")]
1010 pub buy_ratio: f64,
1011 #[serde(rename = "sellRatio", with = "string_to_float")]
1012 pub sell_ratio: f64,
1013 #[serde(rename = "timestamp", with = "string_to_u64")]
1014 pub timestamp: u64,
1015}
1016
1017#[derive(Clone, Copy, Default, Serialize)]
1021pub enum Category {
1022 Spot,
1023 #[default]
1024 Linear,
1025 Inverse,
1026 Option,
1027}
1028impl Category {
1029 pub fn as_str(&self) -> &str {
1030 match self {
1031 Category::Spot => "spot",
1032 Category::Linear => "linear",
1033 Category::Inverse => "inverse",
1034 Category::Option => "option",
1035 }
1036 }
1037}
1038
1039#[derive(Serialize, Deserialize, Clone, Debug, Default)]
1040pub enum Side {
1041 #[default]
1042 Buy,
1043 Sell,
1044}
1045
1046impl Side {
1047 pub fn as_str(&self) -> &str {
1048 match self {
1049 Side::Buy => "Buy",
1050 Side::Sell => "Sell",
1051 }
1052 }
1053}
1054
1055#[derive(Serialize, Deserialize, Clone, Debug, Default)]
1056pub enum OrderType {
1057 Limit,
1058 #[default]
1059 Market,
1060}
1061
1062impl OrderType {
1063 pub fn as_str(&self) -> &str {
1064 match self {
1065 OrderType::Limit => "Limit",
1066 OrderType::Market => "Market",
1067 }
1068 }
1069}
1070
1071#[derive(Serialize, Deserialize, Clone, Debug, Default)]
1072pub enum TimeInForce {
1073 #[default]
1074 GTC,
1075 IOC,
1076 FOK,
1077 PostOnly,
1078}
1079
1080impl TimeInForce {
1081 pub fn as_str(&self) -> &str {
1082 match self {
1083 TimeInForce::GTC => "GTC",
1084 TimeInForce::IOC => "IOC",
1085 TimeInForce::FOK => "FOK",
1086 TimeInForce::PostOnly => "PostOnly",
1087 }
1088 }
1089}
1090#[derive(Clone, Default, Serialize)]
1091pub struct OrderRequest<'a> {
1092 pub category: Category, pub symbol: Cow<'a, str>, pub is_leverage: Option<bool>, pub side: Side, pub order_type: OrderType, pub qty: f64, pub market_unit: Option<f64>, pub price: Option<f64>, pub trigger_direction: Option<bool>, pub order_filter: Option<Cow<'a, str>>, pub trigger_price: Option<f64>,
1103 pub trigger_by: Option<Cow<'a, str>>, pub order_iv: Option<f64>, pub time_in_force: Option<Cow<'a, str>>, pub position_idx: Option<u8>,
1107 pub order_link_id: Option<Cow<'a, str>>,
1108 pub take_profit: Option<f64>,
1109 pub stop_loss: Option<f64>,
1110 pub tp_trigger_by: Option<Cow<'a, str>>,
1111 pub sl_trigger_by: Option<Cow<'a, str>>,
1112 pub reduce_only: Option<bool>,
1113 pub close_on_trigger: Option<bool>,
1114 pub smp_type: Option<Cow<'a, str>>,
1115 pub mmp: Option<bool>,
1116 pub tpsl_mode: Option<Cow<'a, str>>,
1117 pub tp_limit_price: Option<f64>,
1118 pub sl_limit_price: Option<f64>,
1119 pub tp_order_type: Option<Cow<'a, str>>,
1120 pub sl_order_type: Option<Cow<'a, str>>,
1121}
1122
1123impl<'a> OrderRequest<'a> {
1124 pub fn default() -> Self {
1125 Self {
1126 category: Category::Linear,
1127 symbol: Cow::Borrowed("BTCUSDT"),
1128 is_leverage: None,
1129 side: Side::default(),
1130 order_type: OrderType::Market,
1131 qty: 0.00,
1132 market_unit: None,
1133 price: None,
1134 trigger_direction: None,
1135 order_filter: None,
1136 trigger_price: None,
1137 trigger_by: None,
1138 order_iv: None,
1139 time_in_force: None,
1140 position_idx: None,
1141 order_link_id: None,
1142 take_profit: None,
1143 stop_loss: None,
1144 tp_trigger_by: None,
1145 sl_trigger_by: None,
1146 reduce_only: None,
1147 close_on_trigger: None,
1148 smp_type: None,
1149 mmp: None,
1150 tpsl_mode: None,
1151 tp_limit_price: None,
1152 sl_limit_price: None,
1153 tp_order_type: None,
1154 sl_order_type: None,
1155 }
1156 }
1157 pub fn custom(
1158 category: Category,
1159 symbol: &'a str,
1160 leverage: Option<bool>,
1161 side: Side,
1162 order_type: OrderType,
1163 qty: f64,
1164 market_unit: Option<f64>,
1165 price: Option<f64>,
1166 trigger_direction: Option<bool>,
1167 order_filter: Option<&'a str>,
1168 trigger_price: Option<f64>,
1169 trigger_by: Option<&'a str>,
1170 order_iv: Option<f64>,
1171 time_in_force: Option<&'a str>,
1172 position_idx: Option<u8>,
1173 order_link_id: Option<&'a str>,
1174 take_profit: Option<f64>,
1175 stop_loss: Option<f64>,
1176 tp_trigger_by: Option<&'a str>,
1177 sl_trigger_by: Option<&'a str>,
1178 reduce_only: Option<bool>,
1179 close_on_trigger: Option<bool>,
1180 smp_type: Option<&'a str>,
1181 mmp: Option<bool>,
1182 tpsl_mode: Option<&'a str>,
1183 tp_limit_price: Option<f64>,
1184 sl_limit_price: Option<f64>,
1185 tp_order_type: Option<&'a str>,
1186 sl_order_type: Option<&'a str>,
1187 ) -> Self {
1188 Self {
1189 category,
1190 symbol: Cow::Borrowed(symbol),
1191 is_leverage: leverage,
1192 side,
1193 order_type,
1194 qty,
1195 market_unit,
1196 price,
1197 trigger_direction,
1198 order_filter: order_filter.map(Cow::Borrowed),
1199 trigger_price,
1200 trigger_by: trigger_by.map(Cow::Borrowed),
1201 order_iv,
1202 time_in_force: time_in_force.map(Cow::Borrowed),
1203 position_idx,
1204 order_link_id: order_link_id.map(Cow::Borrowed),
1205 take_profit,
1206 stop_loss,
1207 tp_trigger_by: tp_trigger_by.map(Cow::Borrowed),
1208 sl_trigger_by: sl_trigger_by.map(Cow::Borrowed),
1209 reduce_only,
1210 close_on_trigger,
1211 smp_type: smp_type.map(Cow::Borrowed),
1212 mmp,
1213 tpsl_mode: tpsl_mode.map(Cow::Borrowed),
1214 tp_limit_price,
1215 sl_limit_price,
1216 tp_order_type: tp_order_type.map(Cow::Borrowed),
1217 sl_order_type: sl_order_type.map(Cow::Borrowed),
1218 }
1219 }
1220 pub fn spot_limit_with_market_tpsl(
1221 symbol: &'a str,
1222 side: Side,
1223 qty: f64,
1224 price: f64,
1225 tp: f64,
1226 sl: f64,
1227 ) -> Self {
1228 Self {
1229 category: Category::Spot,
1230 symbol: Cow::Borrowed(symbol),
1231 side,
1232 order_type: OrderType::Limit,
1233 qty,
1234 price: Some(price),
1235 time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
1236 take_profit: Some(tp),
1237 stop_loss: Some(sl),
1238 tp_order_type: Some(Cow::Borrowed("Market")),
1239 sl_order_type: Some(Cow::Borrowed("Market")),
1240 ..Self::default()
1241 }
1242 }
1243 pub fn spot_limit_with_limit_tpsl(
1244 symbol: &'a str,
1245 side: Side,
1246 qty: f64,
1247 price: f64,
1248 tp: f64,
1249 sl: f64,
1250 ) -> Self {
1251 Self {
1252 category: Category::Spot,
1253 symbol: Cow::Borrowed(symbol),
1254 side,
1255 order_type: OrderType::Limit,
1256 qty,
1257 price: Some(price),
1258 time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
1259 take_profit: Some(tp),
1260 stop_loss: Some(sl),
1261 tp_limit_price: Some(tp),
1262 sl_limit_price: Some(sl),
1263 tp_order_type: Some(Cow::Borrowed("Limit")),
1264 sl_order_type: Some(Cow::Borrowed("Limit")),
1265 ..Self::default()
1266 }
1267 }
1268 pub fn spot_postonly(symbol: &'a str, side: Side, qty: f64, price: f64) -> Self {
1269 Self {
1270 category: Category::Spot,
1271 symbol: Cow::Borrowed(symbol),
1272 side,
1273 order_type: OrderType::Limit,
1274 qty,
1275 price: Some(price),
1276 time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
1277 ..Self::default()
1278 }
1279 }
1280 pub fn spot_tpsl(
1281 symbol: &'a str,
1282 side: Side,
1283 price: f64,
1284 qty: f64,
1285 order_link_id: Option<&'a str>,
1286 ) -> Self {
1287 Self {
1288 category: Category::Spot,
1289 symbol: Cow::Borrowed(symbol),
1290 side,
1291 order_type: OrderType::Limit,
1292 qty,
1293 price: Some(price),
1294 time_in_force: Some(Cow::Borrowed(TimeInForce::GTC.as_str())),
1295 order_link_id: order_link_id.map(Cow::Borrowed),
1296 order_filter: Some(Cow::Borrowed("tpslOrder")),
1297 ..Self::default()
1298 }
1299 }
1300 pub fn spot_margin(symbol: &'a str, side: Side, qty: f64, price: f64) -> Self {
1301 Self {
1302 category: Category::Spot,
1303 symbol: Cow::Borrowed(symbol),
1304 side,
1305 order_type: OrderType::Market,
1306 qty,
1307 price: Some(price),
1308 time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
1309 is_leverage: Some(true),
1310 ..Self::default()
1311 }
1312 }
1313
1314 pub fn spot_market(symbol: &'a str, side: Side, qty: f64) -> Self {
1315 Self {
1316 category: Category::Spot,
1317 symbol: Cow::Borrowed(symbol),
1318 side,
1319 order_type: OrderType::Market,
1320 qty,
1321 time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
1322 ..Self::default()
1323 }
1324 }
1325
1326 pub fn futures_limit_with_market_tpsl(
1327 symbol: &'a str,
1328 side: Side,
1329 qty: f64,
1330 price: f64,
1331 tp: f64,
1332 sl: f64,
1333 ) -> Self {
1334 Self {
1335 category: Category::Linear,
1336 symbol: Cow::Borrowed(symbol),
1337 side,
1338 order_type: OrderType::Limit,
1339 qty,
1340 price: Some(price),
1341 time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
1342 reduce_only: Some(false),
1343 take_profit: Some(tp),
1344 stop_loss: Some(sl),
1345 tpsl_mode: Some(Cow::Borrowed("Full")),
1346 tp_order_type: Some(Cow::Borrowed("Market")),
1347 sl_order_type: Some(Cow::Borrowed("Market")),
1348 ..Self::default()
1349 }
1350 }
1351
1352 pub fn futures_limit_with_limit_tpsl(
1353 symbol: &'a str,
1354 side: Side,
1355 qty: f64,
1356 price: f64,
1357 tp: f64,
1358 sl: f64,
1359 ) -> Self {
1360 Self {
1361 category: Category::Linear,
1362 symbol: Cow::Borrowed(symbol),
1363 side,
1364 order_type: OrderType::Limit,
1365 qty,
1366 price: Some(price),
1367 time_in_force: Some(Cow::Borrowed(TimeInForce::PostOnly.as_str())),
1368 reduce_only: Some(false),
1369 take_profit: Some(tp),
1370 stop_loss: Some(sl),
1371 tpsl_mode: Some(Cow::Borrowed("Partial")),
1372 tp_order_type: Some(Cow::Borrowed("Limit")),
1373 sl_order_type: Some(Cow::Borrowed("Limit")),
1374 tp_limit_price: Some(tp),
1375 sl_limit_price: Some(sl),
1376 ..Self::default()
1377 }
1378 }
1379
1380 pub fn futures_market(symbol: &'a str, side: Side, qty: f64) -> Self {
1381 Self {
1382 category: Category::Linear,
1383 symbol: Cow::Borrowed(symbol),
1384 side,
1385 order_type: OrderType::Market,
1386 qty,
1387 time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
1388 reduce_only: Some(false),
1389 ..Self::default()
1390 }
1391 }
1392
1393 pub fn futures_close_limit(
1394 symbol: &'a str,
1395 side: Side,
1396 qty: f64,
1397 price: f64,
1398 order_link_id: &'a str,
1399 ) -> Self {
1400 Self {
1401 category: Category::Linear,
1402 symbol: Cow::Borrowed(symbol),
1403 side,
1404 order_type: OrderType::Limit,
1405 qty,
1406 price: Some(price),
1407 time_in_force: Some(Cow::Borrowed(TimeInForce::GTC.as_str())),
1408 order_link_id: Some(Cow::Borrowed(order_link_id)),
1409 reduce_only: Some(true),
1410 ..Self::default()
1411 }
1412 }
1413
1414 pub fn futures_market_close(symbol: &'a str, side: Side, qty: f64) -> Self {
1415 Self {
1416 category: Category::Linear,
1417 symbol: Cow::Borrowed(symbol),
1418 side,
1419 order_type: OrderType::Market,
1420 qty,
1421 time_in_force: Some(Cow::Borrowed(TimeInForce::IOC.as_str())),
1422 reduce_only: Some(true),
1423 ..Self::default()
1424 }
1425 }
1426}
1427#[derive(Serialize, Deserialize, Clone, Debug)]
1428#[serde(rename_all = "camelCase")]
1429pub struct AmendOrderResponse {
1430 pub ret_code: i16,
1431 pub ret_msg: String,
1432 pub result: OrderStatus,
1433 pub ret_ext_info: Empty,
1434 pub time: u64,
1435}
1436
1437#[derive(Clone, Default, Serialize)]
1438pub struct AmendOrderRequest<'a> {
1439 pub category: Category, pub symbol: Cow<'a, str>, pub order_id: Option<Cow<'a, str>>,
1442 pub order_link_id: Option<Cow<'a, str>>,
1443 pub order_iv: Option<f64>, pub trigger_price: Option<f64>,
1445 pub qty: f64, pub price: Option<f64>, pub tpsl_mode: Option<Cow<'a, str>>,
1448 pub take_profit: Option<f64>,
1449 pub stop_loss: Option<f64>,
1450 pub tp_trigger_by: Option<Cow<'a, str>>,
1451 pub sl_trigger_by: Option<Cow<'a, str>>,
1452 pub trigger_by: Option<Cow<'a, str>>, pub tp_limit_price: Option<f64>,
1454 pub sl_limit_price: Option<f64>,
1455}
1456
1457impl<'a> AmendOrderRequest<'a> {
1458 pub fn default() -> Self {
1459 Self {
1460 category: Category::Linear,
1461 symbol: Cow::Borrowed("BTCUSDT"),
1462 order_id: None,
1463 order_link_id: None,
1464 order_iv: None,
1465 trigger_price: None,
1466 qty: 0.00,
1467 price: None,
1468 tpsl_mode: None,
1469 take_profit: None,
1470 stop_loss: None,
1471 tp_trigger_by: None,
1472 sl_trigger_by: None,
1473 trigger_by: None,
1474 tp_limit_price: None,
1475 sl_limit_price: None,
1476 }
1477 }
1478 pub fn custom(
1479 category: Category,
1480 symbol: &'a str,
1481 order_id: Option<&'a str>,
1482 order_link_id: Option<&'a str>,
1483 order_iv: Option<f64>,
1484 trigger_price: Option<f64>,
1485 qty: f64,
1486 price: Option<f64>,
1487 tpsl_mode: Option<&'a str>,
1488 take_profit: Option<f64>,
1489 stop_loss: Option<f64>,
1490 tp_trigger_by: Option<&'a str>,
1491 sl_trigger_by: Option<&'a str>,
1492 trigger_by: Option<&'a str>,
1493 tp_limit_price: Option<f64>,
1494 sl_limit_price: Option<f64>,
1495 ) -> Self {
1496 Self {
1497 category,
1498 symbol: Cow::Borrowed(symbol),
1499 order_id: order_id.map(Cow::Borrowed),
1500 order_link_id: order_link_id.map(Cow::Borrowed),
1501 order_iv,
1502 trigger_price,
1503 qty,
1504 price,
1505 tpsl_mode: tpsl_mode.map(Cow::Borrowed),
1506 take_profit,
1507 stop_loss,
1508 tp_trigger_by: tp_trigger_by.map(Cow::Borrowed),
1509 sl_trigger_by: sl_trigger_by.map(Cow::Borrowed),
1510 trigger_by: trigger_by.map(Cow::Borrowed),
1511 tp_limit_price,
1512 sl_limit_price,
1513 }
1514 }
1515}
1516
1517#[derive(Clone, Serialize)]
1518pub struct CancelOrderRequest<'a> {
1519 pub category: Category,
1520 pub symbol: Cow<'a, str>,
1521 pub order_id: Option<Cow<'a, str>>,
1522 pub order_link_id: Option<Cow<'a, str>>,
1523 pub order_filter: Option<Cow<'a, str>>,
1524}
1525
1526#[derive(Debug, Serialize, Deserialize, Clone)]
1527#[serde(rename_all = "camelCase")]
1528pub struct CancelOrderResponse {
1529 pub ret_code: i16,
1530 pub ret_msg: String,
1531 pub result: OrderStatus,
1532 pub ret_ext_info: Empty,
1533 pub time: u64,
1534}
1535
1536#[derive(Clone, Default)]
1537pub struct OpenOrdersRequest<'a> {
1538 pub category: Category,
1539 pub symbol: Cow<'a, str>,
1540 pub base_coin: Option<Cow<'a, str>>,
1541 pub settle_coin: Option<Cow<'a, str>>,
1542 pub order_id: Option<Cow<'a, str>>,
1543 pub order_link_id: Option<Cow<'a, str>>,
1544 pub open_only: Option<usize>,
1545 pub order_filter: Option<Cow<'a, str>>,
1546 pub limit: Option<usize>,
1547}
1548
1549impl<'a> OpenOrdersRequest<'a> {
1550 pub fn default() -> Self {
1551 Self {
1552 category: Category::Linear,
1553 symbol: Cow::Borrowed("BTCUSDT"),
1554 base_coin: None,
1555 settle_coin: None,
1556 order_id: None,
1557 order_link_id: None,
1558 open_only: None,
1559 order_filter: None,
1560 limit: None,
1561 }
1562 }
1563
1564 pub fn custom(
1565 category: Category,
1566 symbol: &'a str,
1567 base_coin: Option<&'a str>,
1568 settle_coin: Option<&'a str>,
1569 order_id: Option<&'a str>,
1570 order_link_id: Option<&'a str>,
1571 open_only: usize,
1572 order_filter: Option<&'a str>,
1573 limit: Option<usize>,
1574 ) -> Self {
1575 Self {
1576 category,
1577 symbol: Cow::Borrowed(symbol),
1578 base_coin: base_coin.map(Cow::Borrowed),
1579 settle_coin: settle_coin.map(Cow::Borrowed),
1580 order_id: order_id.map(Cow::Borrowed),
1581 order_link_id: order_link_id.map(Cow::Borrowed),
1582 open_only: match open_only {
1583 0 | 1 | 2 => Some(open_only),
1584 _ => None,
1585 },
1586 order_filter: order_filter.map(Cow::Borrowed),
1587 limit,
1588 }
1589 }
1590}
1591
1592#[derive(Debug, Serialize, Deserialize, Clone)]
1593#[serde(rename_all = "camelCase")]
1594pub struct OpenOrdersResponse {
1595 pub ret_code: i16,
1596 pub ret_msg: String,
1597 pub result: OrderHistory,
1598 pub ret_ext_info: Empty,
1599 pub time: u64,
1600}
1601
1602#[derive(Serialize, Deserialize, Clone, Debug)]
1603#[serde(rename_all = "camelCase")]
1604pub struct OrderStatus {
1605 #[serde(rename = "orderId")]
1606 pub order_id: String,
1607 #[serde(rename = "orderLinkId")]
1608 pub order_link_id: String,
1609}
1610
1611#[derive(Serialize, Deserialize, Clone, Debug)]
1612#[serde(rename_all = "camelCase")]
1613pub struct OrderResponse {
1614 #[serde(rename = "retCode")]
1615 pub ret_code: i16,
1616 #[serde(rename = "retMsg")]
1617 pub ret_msg: String,
1618 pub result: OrderStatus,
1619 #[serde(rename = "retExtInfo")]
1620 pub ret_ext_info: Empty,
1621 pub time: u64,
1622}
1623
1624#[derive(Clone, Default)]
1625pub struct OrderHistoryRequest<'a> {
1626 pub category: Category,
1627 pub symbol: Option<Cow<'a, str>>,
1628 pub base_coin: Option<Cow<'a, str>>,
1629 pub settle_coin: Option<Cow<'a, str>>,
1630 pub order_id: Option<Cow<'a, str>>,
1631 pub order_link_id: Option<Cow<'a, str>>,
1632 pub order_filter: Option<Cow<'a, str>>,
1633 pub order_status: Option<Cow<'a, str>>,
1634 pub start_time: Option<Cow<'a, str>>,
1635 pub end_time: Option<Cow<'a, str>>,
1636 pub limit: Option<u64>,
1637}
1638
1639impl<'a> OrderHistoryRequest<'a> {
1640 pub fn default() -> Self {
1641 Self {
1642 category: Category::Linear,
1643 symbol: None,
1644 base_coin: None,
1645 settle_coin: None,
1646 order_id: None,
1647 order_link_id: None,
1648 order_filter: None,
1649 order_status: None,
1650 start_time: None,
1651 end_time: None,
1652 limit: None,
1653 }
1654 }
1655 pub fn new(
1656 category: Category,
1657 symbol: Option<&'a str>,
1658 base_coin: Option<&'a str>,
1659 settle_coin: Option<&'a str>,
1660 order_id: Option<&'a str>,
1661 order_link_id: Option<&'a str>,
1662 order_filter: Option<&'a str>,
1663 order_status: Option<&'a str>,
1664 start_time: Option<&'a str>,
1665 end_time: Option<&'a str>,
1666 limit: Option<u64>,
1667 ) -> Self {
1668 Self {
1669 category,
1670 symbol: symbol.map(Cow::Borrowed),
1671 base_coin: base_coin.map(Cow::Borrowed),
1672 settle_coin: settle_coin.map(Cow::Borrowed),
1673 order_id: order_id.map(Cow::Borrowed),
1674 order_link_id: order_link_id.map(Cow::Borrowed),
1675 order_filter: order_filter.map(Cow::Borrowed),
1676 order_status: order_status.map(Cow::Borrowed),
1677 start_time: start_time.map(Cow::Borrowed),
1678 end_time: end_time.map(Cow::Borrowed),
1679 limit,
1680 }
1681 }
1682}
1683
1684#[derive(Serialize, Deserialize, Clone, Debug)]
1685#[serde(rename_all = "camelCase")]
1686pub struct OrderHistoryResponse {
1687 #[serde(rename = "retCode")]
1688 pub ret_code: i16,
1689 #[serde(rename = "retMsg")]
1690 pub ret_msg: String,
1691 pub result: OrderHistory,
1692 #[serde(rename = "retExtInfo")]
1693 pub ret_ext_info: Empty,
1694 pub time: u64,
1695}
1696
1697#[derive(Serialize, Deserialize, Clone, Debug)]
1698#[serde(rename_all = "camelCase")]
1699pub struct OrderHistory {
1700 pub category: String,
1701 pub list: Vec<Orders>,
1702 #[serde(rename = "nextPageCursor", skip_serializing_if = "String::is_empty")]
1703 pub next_page_cursor: String,
1704}
1705
1706#[derive(Serialize, Deserialize, Clone, Debug)]
1707#[serde(rename_all = "camelCase")]
1708pub struct Orders {
1709 #[serde(rename = "orderId")]
1710 pub order_id: String,
1711 #[serde(rename = "orderLinkId")]
1712 pub order_link_id: String,
1713 #[serde(rename = "blockTradeId")]
1714 pub block_trade_id: String,
1715 pub symbol: String,
1716 #[serde(with = "string_to_float")]
1717 pub price: f64,
1718 #[serde(with = "string_to_float")]
1719 pub qty: f64,
1720 pub side: Side,
1721 #[serde(rename = "isLeverage", skip_serializing_if = "String::is_empty")]
1722 pub is_leverage: String,
1723 #[serde(rename = "positionIdx")]
1724 pub position_idx: i32,
1725 #[serde(rename = "orderStatus")]
1726 pub order_status: String,
1727 #[serde(rename = "cancelType")]
1728 pub cancel_type: String,
1729 #[serde(rename = "rejectReason")]
1730 pub reject_reason: String,
1731 #[serde(rename = "avgPrice", with = "string_to_float")]
1732 pub avg_price: f64,
1733 #[serde(rename = "leavesQty", with = "string_to_float")]
1734 pub leaves_qty: f64,
1735 #[serde(rename = "leavesValue", with = "string_to_float")]
1736 pub leaves_value: f64,
1737 #[serde(rename = "cumExecQty", with = "string_to_float")]
1738 pub cum_exec_qty: f64,
1739 #[serde(rename = "cumExecValue", with = "string_to_float")]
1740 pub cum_exec_value: f64,
1741 #[serde(rename = "cumExecFee", with = "string_to_float")]
1742 pub cum_exec_fee: f64,
1743 #[serde(rename = "timeInForce")]
1744 pub time_in_force: String,
1745 #[serde(rename = "orderType")]
1746 pub order_type: OrderType,
1747 #[serde(rename = "stopOrderType")]
1748 pub stop_order_type: String,
1749 #[serde(rename = "orderIv", skip_serializing_if = "String::is_empty")]
1750 pub order_iv: String,
1751 #[serde(rename = "triggerPrice", with = "string_to_float")]
1752 pub trigger_price: f64,
1753 #[serde(rename = "takeProfit", with = "string_to_float")]
1754 pub take_profit: f64,
1755 #[serde(rename = "stopLoss", with = "string_to_float")]
1756 pub stop_loss: f64,
1757 #[serde(rename = "tpTriggerBy")]
1758 pub tp_trigger_by: String,
1759 #[serde(rename = "slTriggerBy")]
1760 pub sl_trigger_by: String,
1761 #[serde(rename = "triggerDirection")]
1762 pub trigger_direction: i32,
1763 #[serde(rename = "triggerBy")]
1764 pub trigger_by: String,
1765 #[serde(rename = "lastPriceOnCreated", with = "string_to_float")]
1766 pub last_price_on_created: f64,
1767 #[serde(rename = "reduceOnly")]
1768 pub reduce_only: bool,
1769 #[serde(rename = "closeOnTrigger")]
1770 pub close_on_trigger: bool,
1771 #[serde(rename = "smpType")]
1772 pub smp_type: String,
1773 #[serde(rename = "smpGroup")]
1774 pub smp_group: i32,
1775 #[serde(rename = "smpOrderId", skip_serializing_if = "String::is_empty")]
1776 pub smp_order_id: String,
1777 #[serde(rename = "tpslMode", skip_serializing_if = "String::is_empty")]
1778 pub tpsl_mode: String,
1779 #[serde(rename = "tpLimitPrice", with = "string_to_float")]
1780 pub tp_limit_price: f64,
1781 #[serde(rename = "slLimitPrice", with = "string_to_float")]
1782 pub sl_limit_price: f64,
1783 #[serde(rename = "placeType", skip_serializing_if = "String::is_empty")]
1784 pub place_type: String,
1785 #[serde(with = "string_to_u64")]
1786 pub created_time: u64,
1787 #[serde(with = "string_to_u64")]
1788 pub updated_time: u64,
1789}
1790
1791#[derive(Clone, Default)]
1792pub struct CancelallRequest<'a> {
1793 pub category: Category,
1794 pub symbol: &'a str,
1795 pub base_coin: Option<&'a str>,
1796 pub settle_coin: Option<&'a str>,
1797 pub order_filter: Option<&'a str>,
1798 pub stop_order_type: Option<&'a str>,
1799}
1800
1801impl<'a> CancelallRequest<'a> {
1802 pub fn default() -> Self {
1803 Self {
1804 category: Category::Linear,
1805 symbol: "BTCUSDT",
1806 base_coin: None,
1807 settle_coin: None,
1808 order_filter: None,
1809 stop_order_type: None,
1810 }
1811 }
1812 pub fn new(
1813 category: Category,
1814 symbol: &'a str,
1815 base_coin: Option<&'a str>,
1816 settle_coin: Option<&'a str>,
1817 order_filter: Option<&'a str>,
1818 stop_order_type: Option<&'a str>,
1819 ) -> Self {
1820 Self {
1821 category,
1822 symbol,
1823 base_coin,
1824 settle_coin,
1825 order_filter,
1826 stop_order_type,
1827 }
1828 }
1829}
1830
1831#[derive(Serialize, Deserialize, Clone, Debug)]
1832#[serde(rename_all = "camelCase")]
1833pub struct CancelallResponse {
1834 #[serde(rename = "retCode")]
1835 pub ret_code: i16,
1836 #[serde(rename = "retMsg")]
1837 pub ret_msg: String,
1838 pub result: CancelledList,
1839 #[serde(rename = "retExtInfo")]
1840 pub ret_ext_info: Empty,
1841 pub time: u64,
1842}
1843
1844#[derive(Serialize, Deserialize, Clone, Debug)]
1845#[serde(rename_all = "camelCase")]
1846pub struct CancelledList {
1847 pub list: Vec<OrderStatus>,
1848}
1849
1850#[derive(Serialize, Deserialize, Clone, Debug)]
1851#[serde(rename_all = "camelCase")]
1852pub struct TradeHistoryResponse {
1853 pub ret_code: i16,
1854 pub ret_msg: String,
1855 pub result: TradeHistorySummary,
1856 pub ret_ext_info: Empty,
1857 pub time: u64,
1858}
1859
1860#[derive(Serialize, Deserialize, Clone, Debug)]
1861#[serde(rename_all = "camelCase")]
1862pub struct TradeHistorySummary {
1863 #[serde(rename = "nextPageCursor", skip_serializing_if = "String::is_empty")]
1864 pub next_page_cursor: String,
1865 pub category: String,
1866 pub list: Vec<TradeHistory>,
1867}
1868#[derive(Serialize, Deserialize, Clone, Debug)]
1869#[serde(rename_all = "camelCase")]
1870pub struct TradeHistory {
1871 pub symbol: String,
1872 #[serde(rename = "orderType")]
1873 pub order_type: String,
1874 #[serde(
1875 rename = "underlyingPrice",
1876 default,
1877 skip_serializing_if = "String::is_empty"
1878 )]
1879 pub underlying_price: String,
1880 #[serde(
1881 rename = "orderLinkId",
1882 default,
1883 skip_serializing_if = "String::is_empty"
1884 )]
1885 pub order_link_id: String,
1886 pub side: String,
1887 #[serde(
1888 rename = "indexPrice",
1889 default,
1890 skip_serializing_if = "String::is_empty"
1891 )]
1892 pub index_price: String,
1893 #[serde(rename = "orderId")]
1894 pub order_id: String,
1895 #[serde(rename = "stopOrderType")]
1896 pub stop_order_type: String,
1897 #[serde(rename = "leavesQty")]
1898 pub leaves_qty: String,
1899 #[serde(rename = "execTime")]
1900 pub exec_time: String,
1901 #[serde(
1902 rename = "feeCurrency",
1903 default,
1904 skip_serializing_if = "String::is_empty"
1905 )]
1906 pub fee_currency: String,
1907 #[serde(rename = "isMaker")]
1908 pub is_maker: bool,
1909 #[serde(rename = "execFee")]
1910 pub exec_fee: String,
1911 #[serde(rename = "feeRate")]
1912 pub fee_rate: String,
1913 #[serde(rename = "execId")]
1914 pub exec_id: String,
1915 #[serde(rename = "tradeIv", default, skip_serializing_if = "String::is_empty")]
1916 pub trade_iv: String,
1917 #[serde(
1918 rename = "blockTradeId",
1919 default,
1920 skip_serializing_if = "String::is_empty"
1921 )]
1922 pub block_trade_id: String,
1923 #[serde(rename = "markPrice")]
1924 pub mark_price: String,
1925 #[serde(rename = "execPrice")]
1926 pub exec_price: String,
1927 #[serde(rename = "markIv", default, skip_serializing_if = "String::is_empty")]
1928 pub mark_iv: String,
1929 #[serde(rename = "orderQty")]
1930 pub order_qty: String,
1931 #[serde(rename = "orderPrice")]
1932 pub order_price: String,
1933 #[serde(rename = "execValue")]
1934 pub exec_value: String,
1935 #[serde(rename = "execType")]
1936 pub exec_type: String,
1937 #[serde(rename = "execQty")]
1938 pub exec_qty: String,
1939 #[serde(
1940 rename = "closedSize",
1941 default,
1942 skip_serializing_if = "String::is_empty"
1943 )]
1944 pub closed_size: String,
1945 pub seq: u64,
1946}
1947
1948#[derive(Clone, Default)]
1949pub struct TradeHistoryRequest<'a> {
1950 pub category: Category,
1951 pub symbol: Option<Cow<'a, str>>,
1952 pub order_id: Option<Cow<'a, str>>,
1953 pub order_link_id: Option<Cow<'a, str>>,
1954 pub base_coin: Option<Cow<'a, str>>,
1955 pub start_time: Option<Cow<'a, str>>,
1956 pub end_time: Option<Cow<'a, str>>,
1957 pub exec_type: Option<Cow<'a, str>>,
1958 pub limit: Option<u64>,
1959}
1960
1961impl<'a> TradeHistoryRequest<'a> {
1962 pub fn default() -> TradeHistoryRequest<'a> {
1963 TradeHistoryRequest::new(
1964 Category::Linear,
1965 None,
1966 None,
1967 None,
1968 None,
1969 None,
1970 None,
1971 None,
1972 None,
1973 )
1974 }
1975 pub fn new(
1976 category: Category,
1977 symbol: Option<&'a str>,
1978 order_id: Option<&'a str>,
1979 order_link_id: Option<&'a str>,
1980 base_coin: Option<&'a str>,
1981 start_time: Option<&'a str>,
1982 end_time: Option<&'a str>,
1983 exec_type: Option<&'a str>,
1984 limit: Option<u64>,
1985 ) -> TradeHistoryRequest<'a> {
1986 TradeHistoryRequest {
1987 category,
1988 symbol: symbol.map(|s| Cow::Borrowed(s)),
1989 order_id: order_id.map(|s| Cow::Borrowed(s)),
1990 order_link_id: order_link_id.map(|s| Cow::Borrowed(s)),
1991 base_coin: base_coin.map(|s| Cow::Borrowed(s)),
1992 start_time: start_time.map(|s| Cow::Borrowed(s)),
1993 end_time: end_time.map(|s| Cow::Borrowed(s)),
1994 exec_type: exec_type.map(|s| Cow::Borrowed(s)),
1995 limit,
1996 }
1997 }
1998}
1999
2000#[derive(Clone, Default)]
2001pub struct BatchPlaceRequest<'a> {
2002 pub category: Category,
2003 pub requests: Vec<OrderRequest<'a>>,
2004}
2005impl<'a> BatchPlaceRequest<'a> {
2006 pub fn new(category: Category, requests: Vec<OrderRequest<'a>>) -> BatchPlaceRequest<'a> {
2007 BatchPlaceRequest { category, requests }
2008 }
2009}
2010#[derive(Serialize, Deserialize, Clone, Debug)]
2011#[serde(rename_all = "camelCase")]
2012pub struct BatchPlaceResponse {
2013 #[serde(rename = "retCode")]
2014 pub ret_code: i16,
2015 #[serde(rename = "retMsg")]
2016 pub ret_msg: String,
2017 pub result: BatchedOrderList,
2018 #[serde(rename = "retExtInfo")]
2019 pub ret_ext_info: OrderConfirmationList,
2020 pub time: u64,
2021}
2022
2023#[derive(Serialize, Deserialize, Clone, Debug)]
2024#[serde(rename_all = "camelCase")]
2025pub struct BatchedOrderList {
2026 pub list: Vec<BatchedOrder>,
2027}
2028
2029#[derive(Serialize, Deserialize, Clone, Debug)]
2030#[serde(rename_all = "camelCase")]
2031pub struct BatchedOrder {
2032 pub category: String,
2033 pub symbol: String,
2034 #[serde(rename = "orderId")]
2035 pub order_id: String,
2036 #[serde(rename = "orderLinkId")]
2037 pub order_link_id: String,
2038 #[serde(rename = "createAt")]
2039 pub create_at: String,
2040}
2041
2042#[derive(Serialize, Deserialize, Clone, Debug)]
2043#[serde(rename_all = "camelCase")]
2044pub struct OrderConfirmationList {
2045 pub list: Vec<OrderConfirmation>,
2046}
2047
2048#[derive(Serialize, Deserialize, Clone, Debug)]
2049#[serde(rename_all = "camelCase")]
2050pub struct OrderConfirmation {
2051 pub code: i16,
2052 pub msg: String,
2053}
2054
2055#[derive(Clone, Default)]
2056pub struct BatchAmendRequest<'a> {
2057 pub category: Category,
2058 pub requests: Vec<AmendOrderRequest<'a>>,
2059}
2060
2061impl<'a> BatchAmendRequest<'a> {
2062 pub fn new(category: Category, requests: Vec<AmendOrderRequest<'a>>) -> BatchAmendRequest<'a> {
2063 BatchAmendRequest { category, requests }
2064 }
2065}
2066
2067#[derive(Serialize, Deserialize, Clone, Debug)]
2068#[serde(rename_all = "camelCase")]
2069pub struct BatchAmendResponse {
2070 #[serde(rename = "retCode")]
2071 pub ret_code: i16,
2072 #[serde(rename = "retMsg")]
2073 pub ret_msg: String,
2074 pub result: AmendedOrderList,
2075 #[serde(rename = "retExtInfo")]
2076 pub ret_ext_info: OrderConfirmationList,
2077 pub time: u64,
2078}
2079
2080#[derive(Serialize, Deserialize, Clone, Debug)]
2081#[serde(rename_all = "camelCase")]
2082pub struct AmendedOrderList {
2083 pub list: Vec<AmendedOrder>,
2084}
2085
2086#[derive(Serialize, Deserialize, Clone, Debug)]
2087#[serde(rename_all = "camelCase")]
2088pub struct AmendedOrder {
2089 pub category: String,
2090 pub symbol: String,
2091 #[serde(rename = "orderId")]
2092 pub order_id: String,
2093 #[serde(rename = "orderLinkId")]
2094 pub order_link_id: String,
2095}
2096
2097#[derive(Clone, Default)]
2098pub struct BatchCancelRequest<'a> {
2099 pub category: Category,
2100 pub requests: Vec<CancelOrderRequest<'a>>,
2101}
2102
2103impl<'a> BatchCancelRequest<'a> {
2104 pub fn new(
2105 category: Category,
2106 requests: Vec<CancelOrderRequest<'a>>,
2107 ) -> BatchCancelRequest<'a> {
2108 BatchCancelRequest { category, requests }
2109 }
2110}
2111
2112#[derive(Serialize, Deserialize, Clone, Debug)]
2113#[serde(rename_all = "camelCase")]
2114pub struct BatchCancelResponse {
2115 #[serde(rename = "retCode")]
2116 pub ret_code: i16,
2117 #[serde(rename = "retMsg")]
2118 pub ret_msg: String,
2119 pub result: CanceledOrderList,
2120 #[serde(rename = "retExtInfo")]
2121 pub ret_ext_info: OrderConfirmationList,
2122 pub time: u64,
2123}
2124
2125#[derive(Serialize, Deserialize, Clone, Debug)]
2126#[serde(rename_all = "camelCase")]
2127pub struct CanceledOrderList {
2128 pub list: Vec<CanceledOrder>,
2129}
2130
2131#[derive(Serialize, Deserialize, Clone, Debug)]
2132#[serde(rename_all = "camelCase")]
2133pub struct CanceledOrder {
2134 pub category: String,
2135 pub symbol: String,
2136 #[serde(rename = "orderId")]
2137 pub order_id: String,
2138 #[serde(rename = "orderLinkId")]
2139 pub order_link_id: String,
2140}
2141
2142
2143#[derive(Clone)]
2144pub enum RequestType<'a> {
2145 Create(BatchPlaceRequest<'a>),
2146 Amend(BatchAmendRequest<'a>),
2147 Cancel(BatchCancelRequest<'a>),
2148}
2149
2150#[derive(Clone, Default)]
2155pub struct PositionRequest<'a> {
2156 pub category: Category,
2157 pub symbol: Option<Cow<'a, str>>,
2158 pub base_coin: Option<Cow<'a, str>>,
2159 pub settle_coin: Option<Cow<'a, str>>,
2160 pub limit: Option<usize>,
2161}
2162
2163impl<'a> PositionRequest<'a> {
2164 pub fn default() -> Self {
2165 Self::new(Category::Linear, None, None, None, None)
2166 }
2167 pub fn new(
2168 category: Category,
2169 symbol: Option<&'a str>,
2170 base_coin: Option<&'a str>,
2171 settle_coin: Option<&'a str>,
2172 limit: Option<usize>,
2173 ) -> Self {
2174 Self {
2175 category,
2176 symbol: symbol.map(Cow::Borrowed),
2177 base_coin: base_coin.map(Cow::Borrowed),
2178 settle_coin: settle_coin.map(Cow::Borrowed),
2179 limit,
2180 }
2181 }
2182}
2183
2184#[derive(Debug, Serialize, Deserialize, Clone)]
2185pub struct InfoResponse {
2186 pub ret_code: i32,
2187 pub ret_msg: String,
2188 pub result: InfoResult,
2189 pub ret_ext_info: Empty,
2190 pub time: u64,
2191}
2192
2193#[derive(Debug, Serialize, Deserialize, Clone)]
2194pub struct InfoResult {
2195 pub list: Vec<PositionInfo>,
2196 #[serde(rename = "nextPageCursor", skip_serializing_if = "Option::is_none")]
2197 pub next_page_cursor: Option<String>,
2198 pub category: String,
2199}
2200
2201#[derive(Debug, Serialize, Deserialize, Clone)]
2202#[serde(rename_all = "camelCase")]
2203pub struct PositionInfo {
2204 #[serde(rename = "positionIdx")]
2205 pub position_idx: i32,
2206 pub risk_id: i32,
2207 #[serde(rename = "riskLimitValue", with = "string_to_float")]
2208 pub risk_limit_value: f64,
2209 pub symbol: String,
2210 pub side: String,
2211 #[serde(with = "string_to_float")]
2212 pub size: f64,
2213 #[serde(with = "string_to_float")]
2214 pub avg_price: f64,
2215 #[serde(rename = "positionValue", with = "string_to_float")]
2216 pub position_value: f64,
2217 #[serde(rename = "tradeMode")]
2218 pub trade_mode: i32,
2219 #[serde(rename = "positionStatus")]
2220 pub position_status: String,
2221 #[serde(rename = "autoAddMargin")]
2222 pub auto_add_margin: i32,
2223 #[serde(rename = "adlRankIndicator")]
2224 pub adl_rank_indicator: i32,
2225 #[serde(with = "string_to_float")]
2226 pub leverage: f64,
2227 #[serde(rename = "positionBalance", with = "string_to_float")]
2228 pub position_balance: f64,
2229 #[serde(rename = "markPrice")]
2230 pub mark_price: String,
2231 #[serde(rename = "liqPrice")]
2232 pub liq_price: String,
2233 #[serde(rename = "bustPrice")]
2234 pub bust_price: String,
2235 #[serde(rename = "positionMM", with = "string_to_float")]
2236 pub position_mm: f64,
2237 #[serde(rename = "positionIM", with = "string_to_float")]
2238 pub position_im: f64,
2239 #[serde(rename = "tpslMode")]
2240 pub tpsl_mode: String,
2241 pub take_profit: String,
2242 pub stop_loss: String,
2243 pub trailing_stop: String,
2244 #[serde(rename = "unrealisedPnl", with = "string_to_float")]
2245 pub unrealised_pnl: f64,
2246 #[serde(rename = "cumRealisedPnl", with = "string_to_float")]
2247 pub cum_realised_pnl: f64,
2248 pub seq: u64,
2249 #[serde(rename = "isReduceOnly")]
2250 pub is_reduce_only: bool,
2251 #[serde(rename = "mmrSysUpdateTime")]
2252 pub mmr_sys_update_time: String,
2253 #[serde(rename = "leverageSysUpdatedTime")]
2254 pub leverage_sys_updated_time: String,
2255 #[serde(rename = "createdTime")]
2256 pub created_time: String,
2257 #[serde(rename = "updatedTime")]
2258 pub updated_time: String,
2259}
2260
2261#[derive(Clone, Default)]
2262pub struct LeverageRequest<'a> {
2263 pub category: Category,
2264 pub symbol: Cow<'a, str>,
2265 pub leverage: i8,
2266}
2267
2268impl<'a> LeverageRequest<'a> {
2269 pub fn new(category: Category, symbol: &'a str, leverage: i8) -> Self {
2270 Self {
2271 category,
2272 symbol: Cow::Borrowed(symbol),
2273 leverage,
2274 }
2275 }
2276 pub fn default() -> LeverageRequest<'a> {
2277 LeverageRequest::new(Category::Linear, "BTCUSDT", 10)
2278 }
2279}
2280
2281#[derive(Serialize, Deserialize, Clone, Debug)]
2282#[serde(rename_all = "camelCase")]
2283pub struct LeverageResponse {
2284 #[serde(rename = "retCode")]
2285 pub ret_code: i32,
2286 #[serde(rename = "retMsg")]
2287 pub ret_msg: String,
2288 pub result: Empty, #[serde(rename = "retExtInfo")]
2290 pub ret_ext_info: Empty, pub time: u64,
2292}
2293
2294#[derive(Default, Clone)]
2295pub struct ChangeMarginRequest<'a> {
2296 pub category: Category,
2297 pub symbol: Cow<'a, str>,
2298 pub trade_mode: i8,
2299 pub leverage: i8,
2300}
2301
2302impl<'a> ChangeMarginRequest<'a> {
2303 pub fn new(category: Category, symbol: &'a str, trade_mode: i8, leverage: i8) -> Self {
2304 Self {
2305 category,
2306 symbol: Cow::Borrowed(symbol),
2307 trade_mode: match trade_mode {
2308 1 => 1,
2309 0 => 0,
2310 _ => 0,
2311 },
2312 leverage,
2313 }
2314 }
2315 pub fn default() -> ChangeMarginRequest<'a> {
2316 ChangeMarginRequest::new(Category::Linear, "BTCUSDT", 0, 10)
2317 }
2318}
2319
2320#[derive(Serialize, Deserialize, Clone, Debug)]
2321#[serde(rename_all = "camelCase")]
2322pub struct ChangeMarginResponse {
2323 #[serde(rename = "retCode")]
2324 pub ret_code: i32,
2325 #[serde(rename = "retMsg")]
2326 pub ret_msg: String,
2327 pub result: Empty, #[serde(rename = "retExtInfo")]
2329 pub ret_ext_info: Empty, pub time: u64,
2331}
2332
2333#[derive(Clone, Default)]
2334pub struct MarginModeRequest<'a> {
2335 pub category: Category,
2336 pub mode: i8,
2337 pub symbol: Option<Cow<'a, str>>,
2338 pub coin: Option<Cow<'a, str>>,
2339}
2340
2341impl<'a> MarginModeRequest<'a> {
2342 pub fn new(
2343 category: Category,
2344 mode: i8,
2345 symbol: Option<&'a str>,
2346 coin: Option<&'a str>,
2347 ) -> Self {
2348 Self {
2349 category,
2350 mode,
2351 symbol: symbol.map(|s| Cow::Borrowed(s)),
2352 coin: coin.map(|s| Cow::Borrowed(s)),
2353 }
2354 }
2355 pub fn default() -> MarginModeRequest<'a> {
2356 MarginModeRequest::new(Category::Linear, 1, None, None)
2357 }
2358}
2359
2360#[derive(Serialize, Deserialize, Clone, Debug)]
2361#[serde(rename_all = "camelCase")]
2362pub struct MarginModeResponse {
2363 #[serde(rename = "retCode")]
2364 pub ret_code: i32,
2365 #[serde(rename = "retMsg")]
2366 pub ret_msg: String,
2367 pub result: Empty, #[serde(rename = "retExtInfo")]
2369 pub ret_ext_info: Empty, pub time: u64,
2371}
2372
2373#[derive(Clone, Default)]
2374pub struct SetRiskLimit<'a> {
2375 pub category: Category,
2376 pub symbol: Cow<'a, str>,
2377 pub risk_id: i8,
2378 pub position_idx: Option<i32>,
2379}
2380
2381impl<'a> SetRiskLimit<'a> {
2382 pub fn new(
2383 category: Category,
2384 symbol: &'a str,
2385 risk_id: i8,
2386 position_idx: Option<i32>,
2387 ) -> Self {
2388 Self {
2389 category,
2390 symbol: Cow::Borrowed(symbol),
2391 risk_id,
2392 position_idx,
2393 }
2394 }
2395 pub fn default() -> SetRiskLimit<'a> {
2396 SetRiskLimit::new(Category::Linear, "BTCUSDT", 1, None)
2397 }
2398}
2399
2400#[derive(Serialize, Deserialize, Clone, Debug)]
2401#[serde(rename_all = "camelCase")]
2402pub struct SetRiskLimitResponse {
2403 #[serde(rename = "retCode")]
2404 pub ret_code: i32,
2405 #[serde(rename = "retMsg")]
2406 pub ret_msg: String,
2407 pub result: SetRiskLimitResult,
2408 #[serde(rename = "retExtInfo")]
2409 pub ret_ext_info: Empty, pub time: u64,
2411}
2412
2413#[derive(Serialize, Deserialize, Clone, Debug)]
2414pub struct SetRiskLimitResult {
2415 #[serde(rename = "riskId")]
2416 pub risk_id: i32,
2417 #[serde(rename = "riskLimitValue", with = "string_to_u64")]
2418 pub risk_limit_value: u64,
2419 pub category: String,
2420}
2421
2422#[derive(Clone, Default)]
2423pub struct TradingStopRequest<'a> {
2424 pub category: Category,
2425 pub symbol: Cow<'a, str>,
2426 pub take_profit: Option<f64>,
2427 pub stop_loss: Option<f64>,
2428 pub tp_trigger_by: Option<Cow<'a, str>>,
2429 pub sl_trigger_by: Option<Cow<'a, str>>,
2430 pub tpsl_mode: Option<Cow<'a, str>>,
2431 pub tp_order_type: Option<OrderType>,
2432 pub sl_order_type: Option<OrderType>,
2433 pub tp_size: Option<f64>,
2434 pub sl_size: Option<f64>,
2435 pub tp_limit_price: Option<f64>,
2436 pub sl_limit_price: Option<f64>,
2437 pub position_idx: i32,
2438}
2439
2440impl<'a> TradingStopRequest<'a> {
2441 pub fn new(
2442 category: Category,
2443 symbol: &'a str,
2444 take_profit: Option<f64>,
2445 stop_loss: Option<f64>,
2446 tp_trigger_by: Option<&'a str>,
2447 sl_trigger_by: Option<&'a str>,
2448 tpsl_mode: Option<&'a str>,
2449 tp_order_type: Option<OrderType>,
2450 sl_order_type: Option<OrderType>,
2451 tp_size: Option<f64>,
2452 sl_size: Option<f64>,
2453 tp_limit_price: Option<f64>,
2454 sl_limit_price: Option<f64>,
2455 position_idx: i32,
2456 ) -> Self {
2457 Self {
2458 category,
2459 symbol: Cow::Borrowed(symbol),
2460 take_profit,
2461 stop_loss,
2462 tp_trigger_by: tp_trigger_by.map(|s| Cow::Borrowed(s)),
2463 sl_trigger_by: sl_trigger_by.map(|s| Cow::Borrowed(s)),
2464 tpsl_mode: tpsl_mode.map(|s| Cow::Borrowed(s)),
2465 tp_order_type,
2466 sl_order_type,
2467 tp_size,
2468 sl_size,
2469 tp_limit_price,
2470 sl_limit_price,
2471 position_idx,
2472 }
2473 }
2474
2475 pub fn default() -> TradingStopRequest<'a> {
2476 TradingStopRequest::new(
2477 Category::Linear,
2478 "BTCUSDT",
2479 None,
2480 None,
2481 None,
2482 None,
2483 None,
2484 None,
2485 None,
2486 None,
2487 None,
2488 None,
2489 None,
2490 1,
2491 )
2492 }
2493}
2494
2495#[derive(Serialize, Deserialize, Clone, Debug)]
2496#[serde(rename_all = "camelCase")]
2497pub struct TradingStopResponse {
2498 #[serde(rename = "retCode")]
2499 pub ret_code: i32,
2500 #[serde(rename = "retMsg")]
2501 pub ret_msg: String,
2502 pub result: Empty, #[serde(rename = "retExtInfo")]
2504 pub ret_ext_info: Empty, pub time: u64,
2506}
2507
2508#[derive(Clone, Default)]
2509pub struct AddMarginRequest<'a> {
2510 pub category: Category,
2511 pub symbol: Cow<'a, str>,
2512 pub auto_add: bool,
2513 pub position_idx: Option<i32>,
2514}
2515
2516impl<'a> AddMarginRequest<'a> {
2517 pub fn new(
2518 category: Category,
2519 symbol: &'a str,
2520 auto_add: bool,
2521 position_idx: Option<i32>,
2522 ) -> Self {
2523 Self {
2524 category,
2525 symbol: Cow::Borrowed(symbol),
2526 auto_add,
2527 position_idx,
2528 }
2529 }
2530 pub fn default() -> AddMarginRequest<'a> {
2531 AddMarginRequest::new(Category::Linear, "BTCUSDT", false, None)
2532 }
2533}
2534
2535#[derive(Serialize, Deserialize, Clone, Debug)]
2536#[serde(rename_all = "camelCase")]
2537pub struct AddMarginResponse {
2538 #[serde(rename = "retCode")]
2539 pub ret_code: i32,
2540 #[serde(rename = "retMsg")]
2541 pub ret_msg: String,
2542 pub result: Empty, #[serde(rename = "retExtInfo")]
2544 pub ret_ext_info: Empty, pub time: u64,
2546}
2547
2548#[derive(Clone, Default)]
2549pub struct AddReduceMarginRequest<'a> {
2550 pub category: Category,
2551 pub symbol: Cow<'a, str>,
2552 pub margin: f64,
2553 pub position_idx: Option<i32>,
2554}
2555
2556impl<'a> AddReduceMarginRequest<'a> {
2557 pub fn new(
2558 category: Category,
2559 symbol: &'a str,
2560 margin: f64,
2561 position_idx: Option<i32>,
2562 ) -> Self {
2563 Self {
2564 category,
2565 symbol: Cow::Borrowed(symbol),
2566 margin,
2567 position_idx,
2568 }
2569 }
2570 pub fn default() -> AddReduceMarginRequest<'a> {
2571 AddReduceMarginRequest::new(Category::Linear, "BTCUSDT", 1.0, None)
2572 }
2573}
2574
2575#[derive(Serialize, Deserialize, Clone, Debug)]
2576#[serde(rename_all = "camelCase")]
2577pub struct AddReduceMarginResponse {
2578 #[serde(rename = "retCode")]
2579 pub ret_code: i32,
2580 #[serde(rename = "retMsg")]
2581 pub ret_msg: String,
2582 pub result: AddReduceMarginResult,
2583 #[serde(rename = "retExtInfo")]
2584 pub ret_ext_info: Empty, pub time: u64,
2586}
2587
2588#[derive(Serialize, Deserialize, Clone, Debug)]
2589#[serde(rename_all = "camelCase")]
2590pub struct AddReduceMarginResult {
2591 pub category: String,
2592 pub symbol: String,
2593 pub position_idx: i32,
2594 #[serde(rename = "riskId")]
2595 pub risk_id: i32,
2596 #[serde(rename = "riskLimitValue")]
2597 pub risk_limit_value: String,
2598 pub size: String,
2599 #[serde(rename = "positionValue")]
2600 pub position_value: String,
2601 #[serde(rename = "avgPrice")]
2602 pub avg_price: String,
2603 #[serde(rename = "liqPrice")]
2604 pub liq_price: String,
2605 #[serde(rename = "bustPrice")]
2606 pub bust_price: String,
2607 #[serde(rename = "markPrice")]
2608 pub mark_price: String,
2609 pub leverage: String,
2610 #[serde(rename = "autoAddMargin")]
2611 pub auto_add_margin: i32,
2612 #[serde(rename = "positionStatus")]
2613 pub position_status: String,
2614 #[serde(rename = "positionIM")]
2615 pub position_im: String,
2616 #[serde(rename = "positionMM")]
2617 pub position_mm: String,
2618 #[serde(rename = "unrealisedPnl")]
2619 pub unrealised_pnl: String,
2620 #[serde(rename = "cumRealisedPnl")]
2621 pub cum_realised_pnl: String,
2622 #[serde(rename = "stopLoss")]
2623 pub stop_loss: String,
2624 #[serde(rename = "takeProfit")]
2625 pub take_profit: String,
2626 #[serde(rename = "trailingStop")]
2627 pub trailing_stop: String,
2628 #[serde(rename = "createdTime")]
2629 pub created_time: String,
2630 #[serde(rename = "updatedTime")]
2631 pub updated_time: String,
2632}
2633
2634#[derive(Clone, Default)]
2635pub struct ClosedPnlRequest<'a> {
2636 pub category: Category,
2637 pub symbol: Option<Cow<'a, str>>,
2638 pub start_time: Option<Cow<'a, str>>,
2639 pub end_time: Option<Cow<'a, str>>,
2640 pub limit: Option<u64>,
2641}
2642
2643impl<'a> ClosedPnlRequest<'a> {
2644 pub fn new(
2645 category: Category,
2646 symbol: Option<&'a str>,
2647 start_time: Option<&'a str>,
2648 end_time: Option<&'a str>,
2649 limit: Option<u64>,
2650 ) -> Self {
2651 Self {
2652 category,
2653 symbol: symbol.map(|s| Cow::Borrowed(s)),
2654 start_time: start_time.map(|s| Cow::Borrowed(s)),
2655 end_time: end_time.map(|s| Cow::Borrowed(s)),
2656 limit,
2657 }
2658 }
2659 pub fn default() -> ClosedPnlRequest<'a> {
2660 ClosedPnlRequest::new(Category::Linear, None, None, None, None)
2661 }
2662}
2663
2664#[derive(Serialize, Deserialize, Clone, Debug)]
2665#[serde(rename_all = "camelCase")]
2666pub struct ClosedPnlResponse {
2667 pub ret_code: i32,
2668 pub ret_msg: String,
2669 pub result: ClosedPnlResult,
2670 pub ret_ext_info: Empty,
2671 pub time: u64,
2672}
2673
2674#[derive(Serialize, Deserialize, Clone, Debug)]
2675#[serde(rename_all = "camelCase")]
2676pub struct ClosedPnlResult {
2677 #[serde(skip_serializing_if = "Option::is_none")]
2678 pub next_page_cursor: Option<String>,
2679 pub category: String,
2680 pub list: Vec<ClosedPnlItem>,
2681}
2682
2683#[derive(Serialize, Deserialize, Clone, Debug)]
2684#[serde(rename_all = "camelCase")]
2685pub struct ClosedPnlItem {
2686 pub symbol: String,
2687 pub order_type: String,
2688 pub leverage: String,
2689 pub updated_time: String,
2690 pub side: String,
2691 pub order_id: String,
2692 #[serde(with = "string_to_float")]
2693 pub closed_pnl: f64,
2694 #[serde(rename = "avgEntryPrice", with = "string_to_float")]
2695 pub avg_entry_price: f64,
2696 pub qty: String,
2697 #[serde(with = "string_to_float")]
2698 pub cum_entry_value: f64,
2699 pub created_time: String,
2700 #[serde(with = "string_to_float")]
2701 pub order_price: f64,
2702 pub closed_size: String,
2703 #[serde(rename = "avgExitPrice", with = "string_to_float")]
2704 pub avg_exit_price: f64,
2705 pub exec_type: String,
2706 pub fill_count: String,
2707 #[serde(with = "string_to_float")]
2708 pub cum_exit_value: f64,
2709}
2710
2711#[derive(Clone, Default, Serialize)]
2712pub struct MovePositionRequest<'a> {
2713 pub from_uid: u64,
2714 pub to_uid: u64,
2715 pub list: Vec<PositionItem<'a>>,
2716}
2717
2718#[derive(Clone, Default, Serialize)]
2719pub struct PositionItem<'a> {
2720 pub category: Category,
2721 pub symbol: Cow<'a, str>,
2722 pub price: f64,
2723 pub side: Side,
2724 pub qty: f64,
2725}
2726
2727impl<'a> MovePositionRequest<'a> {
2728 pub fn new(from_uid: u64, to_uid: u64, list: Vec<PositionItem<'a>>) -> Self {
2729 Self {
2730 from_uid,
2731 to_uid,
2732 list,
2733 }
2734 }
2735 pub fn default() -> MovePositionRequest<'a> {
2736 MovePositionRequest::new(0, 0, vec![])
2737 }
2738}
2739impl<'a> PositionItem<'a> {
2740 pub fn new(category: Category, symbol: &'a str, price: f64, side: Side, qty: f64) -> Self {
2741 Self {
2742 category,
2743 symbol: Cow::Borrowed(symbol),
2744 price,
2745 side,
2746 qty,
2747 }
2748 }
2749 pub fn default() -> PositionItem<'a> {
2750 PositionItem::new(Category::Linear, "BTCUSDT", 0.0, Side::Buy, 0.0)
2751 }
2752}
2753
2754#[derive(Deserialize, Serialize, Clone, Debug)]
2755pub struct MovePositionResponse {
2756 pub ret_code: i32,
2757 pub ret_msg: String,
2758 pub result: MovePositionResult,
2759}
2760
2761#[derive(Deserialize, Serialize, Clone, Debug)]
2762pub struct MovePositionResult {
2763 pub block_trade_id: String,
2764 pub status: String,
2765 pub reject_party: String,
2766}
2767
2768#[derive(Serialize, Clone, Default)]
2769pub struct MoveHistoryRequest<'a> {
2770 pub category: Option<Category>,
2771 pub symbol: Option<Cow<'a, str>>,
2772 pub start_time: Option<Cow<'a, str>>,
2773 pub end_time: Option<Cow<'a, str>>,
2774 pub status: Option<Cow<'a, str>>,
2775 pub block_trade_id: Option<Cow<'a, str>>,
2776 pub limit: Option<Cow<'a, str>>,
2777}
2778
2779impl<'a> MoveHistoryRequest<'a> {
2780 pub fn new(
2781 category: Option<Category>,
2782 symbol: Option<&'a str>,
2783 start_time: Option<&'a str>,
2784 end_time: Option<&'a str>,
2785 status: Option<&'a str>,
2786 block_trade_id: Option<&'a str>,
2787 limit: Option<&'a str>,
2788 ) -> Self {
2789 Self {
2790 category,
2791 symbol: symbol.map(|s| Cow::Borrowed(s)),
2792 start_time: start_time.map(|s| Cow::Borrowed(s)),
2793 end_time: end_time.map(|s| Cow::Borrowed(s)),
2794 status: status.map(|s| Cow::Borrowed(s)),
2795 block_trade_id: block_trade_id.map(|s| Cow::Borrowed(s)),
2796 limit: limit.map(|s| Cow::Borrowed(s)),
2797 }
2798 }
2799 pub fn default() -> MoveHistoryRequest<'a> {
2800 MoveHistoryRequest::new(None, None, None, None, None, None, None)
2801 }
2802}
2803
2804#[derive(Serialize, Deserialize, Clone, Debug)]
2805#[serde(rename_all = "camelCase")]
2806pub struct MoveHistoryResponse {
2807 #[serde(rename = "retCode")]
2808 pub ret_code: i16,
2809 #[serde(rename = "retMsg")]
2810 pub ret_msg: String,
2811 pub result: MoveHistoryResult,
2812 #[serde(rename = "retExtInfo")]
2813 pub ret_ext_info: Empty,
2814 pub time: u64,
2815}
2816
2817#[derive(Serialize, Deserialize, Clone, Debug)]
2818#[serde(rename_all = "camelCase")]
2819pub struct MoveHistoryResult {
2820 pub list: Vec<MoveHistoryEntry>,
2821 #[serde(rename = "nextPageCursor")]
2822 pub next_page_cursor: String,
2823}
2824
2825#[derive(Serialize, Deserialize, Clone, Debug)]
2826#[serde(rename_all = "camelCase")]
2827pub struct MoveHistoryEntry {
2828 #[serde(rename = "blockTradeId")]
2829 pub block_trade_id: String,
2830 pub category: String,
2831 #[serde(rename = "orderId")]
2832 pub order_id: String,
2833 #[serde(rename = "userId")]
2834 pub user_id: u64,
2835 pub symbol: String,
2836 pub side: String,
2837 pub price: String,
2838 pub qty: String,
2839 #[serde(rename = "execFee")]
2840 pub exec_fee: String,
2841 pub status: String,
2842 #[serde(rename = "execId")]
2843 pub exec_id: String,
2844 #[serde(rename = "resultCode")]
2845 pub result_code: i16,
2846 #[serde(rename = "resultMessage")]
2847 pub result_message: String,
2848 #[serde(rename = "createdAt")]
2849 pub created_at: u64,
2850 #[serde(rename = "updatedAt")]
2851 pub updated_at: u64,
2852 #[serde(rename = "rejectParty")]
2853 pub reject_party: String,
2854}
2855
2856#[derive(Deserialize, Serialize, Clone, Debug)]
2863#[serde(rename_all = "camelCase")]
2864pub struct WalletResponse {
2865 #[serde(rename = "retCode")]
2866 pub ret_code: i32,
2867 #[serde(rename = "retMsg")]
2868 pub ret_msg: String,
2869 pub result: WalletList,
2870 #[serde(rename = "retExtInfo")]
2871 pub ret_ext_info: Empty,
2872 pub time: u64,
2873}
2874
2875#[derive(Deserialize, Serialize, Clone, Debug)]
2876pub struct WalletList {
2877 pub list: Vec<WalletData>,
2878}
2879
2880#[derive(Deserialize, Serialize, Clone, Debug)]
2881#[serde(rename_all = "camelCase")]
2882pub struct UTAResponse {
2883 #[serde(rename = "retCode")]
2884 pub ret_code: i32,
2885 #[serde(rename = "retMsg")]
2886 pub ret_msg: String,
2887 pub result: UTAUpdateStatus,
2888 #[serde(rename = "retExtInfo")]
2889 pub ret_ext_info: Empty,
2890 pub time: u64,
2891}
2892
2893#[derive(Deserialize, Serialize, Clone, Debug)]
2894#[serde(rename_all = "camelCase")]
2895pub struct UTAUpdateStatus {
2896 #[serde(rename = "unifiedUpdateStatus")]
2897 pub unified_update_status: String,
2898 #[serde(rename = "unifiedUpdateMsg")]
2899 pub unified_update_msg: UnifiedUpdateMsg,
2900}
2901
2902#[derive(Deserialize, Serialize, Clone, Debug)]
2903pub struct UnifiedUpdateMsg {
2904 pub msg: Vec<String>,
2905}
2906
2907#[derive(Clone, Debug, Default)]
2908pub struct BorrowHistoryRequest<'a> {
2909 pub coin: Option<Cow<'a, str>>,
2910 pub start_time: Option<Cow<'a, str>>,
2911 pub end_time: Option<Cow<'a, str>>,
2912 pub limit: Option<Cow<'a, str>>,
2913}
2914
2915impl<'a> BorrowHistoryRequest<'a> {
2916 pub fn new(
2917 coin: Option<&'a str>,
2918 start_time: Option<&'a str>,
2919 end_time: Option<&'a str>,
2920 limit: Option<&'a str>,
2921 ) -> Self {
2922 Self {
2923 coin: coin.map(|s| Cow::Borrowed(s)),
2924 start_time: start_time.map(|s| Cow::Borrowed(s)),
2925 end_time: end_time.map(|s| Cow::Borrowed(s)),
2926 limit: limit.map(|s| Cow::Borrowed(s)),
2927 }
2928 }
2929 pub fn default() -> BorrowHistoryRequest<'a> {
2930 BorrowHistoryRequest::new(None, None, None, None)
2931 }
2932}
2933
2934#[derive(Debug, Serialize, Deserialize, Clone)]
2935#[serde(rename_all = "camelCase")]
2936pub struct BorrowHistoryResponse {
2937 pub ret_code: i32,
2938 pub ret_msg: String,
2939 pub result: BorrowHistory,
2940 pub ret_ext_info: Empty,
2941 pub time: u64,
2942}
2943
2944#[derive(Debug, Serialize, Deserialize, Clone)]
2945#[serde(rename_all = "camelCase")]
2946pub struct BorrowHistory {
2947 pub next_page_cursor: String,
2948 pub rows: Vec<BorrowHistoryEntry>,
2949}
2950
2951#[derive(Debug, Serialize, Deserialize, Clone)]
2952#[serde(rename_all = "camelCase")]
2953pub struct BorrowHistoryEntry {
2954 #[serde(rename = "borrowAmount")]
2955 pub borrow_amount: String,
2956 #[serde(rename = "costExemption")]
2957 pub cost_exemption: String,
2958 #[serde(rename = "freeBorrowedAmount")]
2959 pub free_borrowed_amount: String,
2960 #[serde(rename = "createdTime")]
2961 pub created_time: u64,
2962 #[serde(rename = "InterestBearingBorrowSize")]
2963 pub interest_bearing_borrow_size: String,
2964 pub currency: String,
2965 #[serde(rename = "unrealisedLoss")]
2966 pub unrealised_loss: String,
2967 #[serde(rename = "hourlyBorrowRate")]
2968 pub hourly_borrow_rate: String,
2969 #[serde(rename = "borrowCost")]
2970 pub borrow_cost: String,
2971}
2972
2973#[derive(Debug, Serialize, Deserialize, Clone)]
2974#[serde(rename_all = "camelCase")]
2975pub struct RepayLiabilityResponse {
2976 pub ret_code: i32,
2977 pub ret_msg: String,
2978 pub result: LiabilityQty,
2979 pub ret_ext_info: Empty,
2980 pub time: u64,
2981}
2982
2983#[derive(Debug, Serialize, Deserialize, Clone)]
2984pub struct LiabilityQty {
2985 pub list: Vec<LiabilityQtyData>,
2986}
2987
2988#[derive(Debug, Serialize, Deserialize, Clone)]
2989#[serde(rename_all = "camelCase")]
2990pub struct LiabilityQtyData {
2991 pub coin: String,
2992 pub repayment_qty: String,
2993}
2994
2995#[derive(Debug, Serialize, Deserialize, Clone)]
2996#[serde(rename_all = "camelCase")]
2997pub struct SetCollateralCoinResponse {
2998 pub ret_code: i32,
2999 pub ret_msg: String,
3000 pub result: Empty,
3001 pub ret_ext_info: Empty,
3002 pub time: u64,
3003}
3004
3005#[derive(Debug, Serialize, Deserialize, Clone)]
3006#[serde(rename_all = "camelCase")]
3007pub struct BatchSetCollateralCoinResponse {
3008 pub ret_code: i32,
3009 pub ret_msg: String,
3010 pub result: SwitchList,
3011 pub ret_ext_info: Empty,
3012 pub time: u64,
3013}
3014
3015#[derive(Debug, Serialize, Deserialize, Clone)]
3016#[serde(rename_all = "camelCase")]
3017pub struct SwitchList {
3018 pub list: Vec<SwitchListData>,
3019}
3020
3021#[derive(Debug, Serialize, Deserialize, Clone)]
3022#[serde(rename_all = "camelCase")]
3023pub struct SwitchListData {
3024 pub coin: String,
3025 pub collateral_switch: String,
3026}
3027
3028#[derive(Debug, Serialize, Deserialize, Clone)]
3029#[serde(rename_all = "camelCase")]
3030pub struct CollateralInfoResponse {
3031 pub ret_code: i32,
3032 pub ret_msg: String,
3033 pub result: CollateralInfoList,
3034 pub ret_ext_info: Empty,
3035 pub time: u64,
3036}
3037
3038#[derive(Debug, Serialize, Deserialize, Clone)]
3039#[serde(rename_all = "camelCase")]
3040pub struct CollateralInfoList {
3041 pub list: Vec<CollateralInfo>,
3042}
3043
3044#[derive(Debug, Serialize, Deserialize, Clone)]
3045#[serde(rename_all = "camelCase")]
3046pub struct CollateralInfo {
3047 #[serde(rename = "availableToBorrow")]
3048 pub available_to_borrow: String,
3049 #[serde(rename = "freeBorrowingAmount")]
3050 pub free_borrowing_amount: String,
3051 #[serde(rename = "freeBorrowAmount")]
3052 pub free_borrow_amount: String,
3053 #[serde(rename = "maxBorrowingAmount")]
3054 pub max_borrowing_amount: String,
3055 #[serde(rename = "hourlyBorrowRate")]
3056 pub hourly_borrow_rate: String,
3057 #[serde(rename = "borrowUsageRate")]
3058 pub borrow_usage_rate: String,
3059 #[serde(rename = "collateralSwitch")]
3060 pub collateral_switch: bool,
3061 #[serde(rename = "borrowAmount")]
3062 pub borrow_amount: String,
3063 #[serde(rename = "borrowable")]
3064 pub borrowable: bool,
3065 pub currency: String,
3066 #[serde(rename = "marginCollateral")]
3067 pub margin_collateral: bool,
3068 #[serde(rename = "freeBorrowingLimit")]
3069 pub free_borrowing_limit: String,
3070 #[serde(rename = "collateralRatio")]
3071 pub collateral_ratio: String,
3072}
3073
3074#[derive(Debug, Serialize, Deserialize, Clone)]
3075#[serde(rename_all = "camelCase")]
3076pub struct FeeRateResponse {
3077 pub ret_code: i32,
3078 pub ret_msg: String,
3079 pub result: FeeRateList,
3080 pub ret_ext_info: Empty,
3081 pub time: u64,
3082}
3083
3084#[derive(Debug, Serialize, Deserialize, Clone)]
3085#[serde(rename_all = "camelCase")]
3086pub struct FeeRateList {
3087 pub list: Vec<FeeRate>,
3088}
3089
3090#[derive(Debug, Serialize, Deserialize, Clone)]
3091#[serde(rename_all = "camelCase")]
3092pub struct FeeRate {
3093 pub symbol: String,
3094 pub maker_fee_rate: String,
3095 pub taker_fee_rate: String,
3096}
3097
3098#[derive(Debug, Serialize, Deserialize, Clone)]
3099#[serde(rename_all = "camelCase")]
3100pub struct AccountInfoResponse {
3101 pub ret_code: i32,
3102 pub ret_msg: String,
3103 pub result: AccountInfo,
3104 #[serde(default)]
3105 pub ret_ext_info: Empty,
3106 #[serde(default)]
3107 pub time: Option<u64>,
3108}
3109
3110#[derive(Debug, Serialize, Deserialize, Clone)]
3111#[serde(rename_all = "camelCase")]
3112pub struct AccountInfo {
3113 pub margin_mode: String,
3114 pub updated_time: String,
3115 pub unified_margin_status: i8,
3116 pub dcp_status: String,
3117 pub time_window: i32,
3118 pub smp_group: i8,
3119 pub is_master_trader: bool,
3120 pub spot_hedging_status: String,
3121}
3122
3123#[derive(Clone, Default)]
3124pub struct TransactionLogRequest<'a> {
3125 pub account_type: Option<Cow<'a, str>>,
3126 pub category: Option<Category>,
3127 pub currency: Option<Cow<'a, str>>,
3128 pub base_coin: Option<Cow<'a, str>>,
3129 pub log_type: Option<Cow<'a, str>>,
3130 pub start_time: Option<Cow<'a, str>>,
3131 pub end_time: Option<Cow<'a, str>>,
3132 pub limit: Option<u32>,
3133}
3134
3135impl<'a> TransactionLogRequest<'a> {
3136 pub fn new(
3137 account_type: Option<&'a str>,
3138 category: Option<Category>,
3139 currency: Option<&'a str>,
3140 base_coin: Option<&'a str>,
3141 log_type: Option<&'a str>,
3142 start_time: Option<&'a str>,
3143 end_time: Option<&'a str>,
3144 limit: Option<u32>,
3145 ) -> Self {
3146 Self {
3147 account_type: account_type.map(|s| Cow::Borrowed(s)),
3148 category,
3149 currency: currency.map(|s| Cow::Borrowed(s)),
3150 base_coin: base_coin.map(|s| Cow::Borrowed(s)),
3151 log_type: log_type.map(|s| Cow::Borrowed(s)),
3152 start_time: start_time.map(|s| Cow::Borrowed(s)),
3153 end_time: end_time.map(|s| Cow::Borrowed(s)),
3154 limit,
3155 }
3156 }
3157 pub fn default() -> Self {
3158 Self::new(None, None, None, None, None, None, None, None)
3159 }
3160}
3161
3162#[derive(Debug, Serialize, Deserialize, Clone)]
3163#[serde(rename_all = "camelCase")]
3164pub struct TransactionLogEntry {
3165 pub id: String,
3166 pub symbol: String,
3167 pub side: String,
3168 pub funding: Option<String>,
3169 pub order_link_id: Option<String>,
3170 pub order_id: String,
3171 pub fee: String,
3172 pub change: String,
3173 pub cash_flow: String,
3174 pub transaction_time: String,
3175 pub type_field: String,
3176 #[serde(rename = "feeRate")]
3177 pub fee_rate: String,
3178 pub bonus_change: Option<String>,
3179 pub size: String,
3180 pub qty: String,
3181 pub cash_balance: String,
3182 pub currency: String,
3183 pub category: String,
3184 pub trade_price: String,
3185 pub trade_id: String,
3186}
3187
3188#[derive(Debug, Serialize, Deserialize, Clone)]
3189#[serde(rename_all = "camelCase")]
3190pub struct TransactionLogResult {
3191 pub next_page_cursor: String,
3192 pub list: Vec<TransactionLogEntry>,
3193}
3194
3195#[derive(Debug, Serialize, Deserialize, Clone)]
3196#[serde(rename_all = "camelCase")]
3197pub struct TransactionLogResponse {
3198 pub ret_code: i32,
3199 pub ret_msg: String,
3200 pub result: TransactionLogResult,
3201 pub ret_ext_info: Empty,
3202 pub time: u64,
3203}
3204
3205#[derive(Debug, Serialize, Deserialize, Clone)]
3206#[serde(rename_all = "camelCase")]
3207pub struct SmpResponse {
3208 pub ret_code: i32,
3209 pub ret_msg: String,
3210 pub result: SmpResult,
3211 pub ret_ext_info: Empty,
3212 pub time: u64,
3213}
3214
3215#[derive(Debug, Serialize, Deserialize, Clone)]
3216#[serde(rename_all = "camelCase")]
3217pub struct SmpResult {
3218 pub smp_group: u8,
3219}
3220
3221#[derive(Debug, Serialize, Deserialize, Clone)]
3222#[serde(rename_all = "camelCase")]
3223pub struct SetMarginModeResponse {
3224 pub ret_code: i32,
3225 pub ret_msg: String,
3226 pub result: MarginModeResult,
3227 pub ret_ext_info: Empty,
3228 pub time: u64,
3229}
3230
3231#[derive(Debug, Serialize, Deserialize, Clone)]
3232#[serde(rename_all = "camelCase")]
3233pub struct MarginModeResult {
3234 pub reason: Vec<ReasonObject>,
3235}
3236
3237#[derive(Debug, Serialize, Deserialize, Clone)]
3238#[serde(rename_all = "camelCase")]
3239pub struct ReasonObject {
3240 pub reason_code: String,
3241 pub reason_msg: String,
3242}
3243
3244#[derive(Debug, Serialize, Deserialize, Clone)]
3245#[serde(rename_all = "camelCase")]
3246pub struct SpotHedgingResponse {
3247 pub ret_code: i32,
3248 pub ret_msg: String,
3249}
3250
3251#[derive(Debug, Serialize, Deserialize, Clone)]
3256pub struct Header {
3257 #[serde(rename = "X-Bapi-Limit")]
3258 pub x_bapi_limit: String,
3259 #[serde(rename = "X-Bapi-Limit-Status")]
3260 pub x_bapi_limit_status: String,
3261 #[serde(rename = "X-Bapi-Limit-Reset-Timestamp")]
3262 pub x_bapi_limit_reset_timestamp: String,
3263 #[serde(rename = "Traceid")]
3264 pub traceid: String,
3265 #[serde(rename = "Timenow")]
3266 pub timenow: String,
3267}
3268
3269#[derive(Clone, Debug, Default)]
3276pub struct Subscription<'a> {
3277 pub op: &'a str,
3278 pub args: Vec<&'a str>,
3279}
3280
3281impl<'a> Subscription<'a> {
3282 pub fn new(op: &'a str, args: Vec<&'a str>) -> Self {
3283 Self { op, args }
3284 }
3285 pub fn default() -> Subscription<'a> {
3286 Subscription::new("subscribe", vec![])
3287 }
3288}
3289
3290#[derive(Debug, Serialize, Deserialize, Clone)]
3291#[serde(untagged)]
3292pub enum WebsocketEvents {
3293 OrderBookEvent(OrderBookUpdate),
3294 TradeEvent(TradeUpdate),
3295 TickerEvent(WsTicker),
3296 LiquidationEvent(Liquidation),
3297 KlineEvent(WsKline),
3298 PositionEvent(PositionEvent),
3299 ExecutionEvent(Execution),
3300 OrderEvent(OrderEvent),
3301 Wallet(WalletEvent),
3302 TradeStream(TradeStreamEvent),
3303 FastExecEvent(FastExecution)
3304}
3305
3306#[derive(Debug, Serialize, Deserialize, Clone)]
3307#[serde(untagged)]
3308pub enum Tickers {
3309 Linear(LinearTickerData),
3310 Spot(SpotTickerData),
3311}
3312
3313#[derive(Debug, Serialize, Deserialize, Clone)]
3314#[serde(untagged)]
3315pub enum PongResponse {
3316 PublicPong(PongData),
3317 PrivatePong(PongData),
3318}
3319
3320#[derive(Debug, Serialize, Deserialize, Clone)]
3321pub struct PongData {
3322 #[serde(skip_serializing_if = "Option::is_none")]
3323 pub ret_code: Option<i32>,
3324 #[serde(skip_serializing_if = "Option::is_none")]
3325 pub success: Option<bool>,
3326 pub ret_msg: String,
3327 pub conn_id: String,
3328 #[serde(skip_serializing_if = "Option::is_none")]
3329 pub req_id: Option<String>,
3330 #[serde(skip_serializing_if = "Option::is_none")]
3331 pub args: Option<Vec<String>>,
3332 #[serde(skip_serializing_if = "Option::is_none")]
3333 pub data: Option<Vec<String>>,
3334 pub op: String,
3335}
3336
3337unsafe impl Send for PongData {}
3338unsafe impl Sync for PongData {}
3339
3340#[derive(Serialize, Deserialize, Debug, Clone)]
3341#[serde(rename_all = "camelCase")]
3342pub struct TradeStreamEvent {
3343 #[serde(skip_serializing_if = "Option::is_none")]
3344 pub req_id: Option<String>,
3345 pub ret_code: i32,
3346 pub ret_msg: String,
3347 pub op: String,
3348 pub data: OrderStatus,
3349 pub header: Header,
3350 pub conn_id: String,
3351}
3352
3353unsafe impl Send for TradeStreamEvent {}
3354unsafe impl Sync for TradeStreamEvent {}
3355
3356#[derive(Serialize, Deserialize, Debug, Clone)]
3357#[serde(rename_all = "camelCase")]
3358pub struct OrderBookUpdate {
3359 #[serde(rename = "topic")]
3360 pub topic: String,
3361 #[serde(rename = "type")]
3362 pub event_type: String,
3363 #[serde(rename = "ts")]
3364 pub timestamp: u64,
3365 pub data: WsOrderBook,
3366 pub cts: u64,
3367}
3368
3369unsafe impl Send for OrderBookUpdate {}
3370unsafe impl Sync for OrderBookUpdate {}
3371
3372#[derive(Serialize, Deserialize, Debug, Clone)]
3373#[serde(rename_all = "camelCase")]
3374pub struct WsOrderBook {
3375 #[serde(rename = "s")]
3376 pub symbol: String,
3377 #[serde(rename = "a")]
3378 pub asks: Vec<Ask>,
3379 #[serde(rename = "b")]
3380 pub bids: Vec<Bid>,
3381 #[serde(rename = "u")]
3382 pub update_id: u64,
3383 pub seq: u64,
3384}
3385
3386unsafe impl Send for WsOrderBook {}
3387unsafe impl Sync for WsOrderBook {}
3388
3389#[derive(Serialize, Deserialize, Debug, Clone)]
3390pub struct TradeUpdate {
3391 #[serde(rename = "topic")]
3392 pub topic: String,
3393 #[serde(rename = "type")]
3394 pub event_type: String,
3395 #[serde(rename = "ts")]
3396 pub timestamp: u64,
3397 pub data: Vec<WsTrade>,
3398}
3399
3400unsafe impl Send for TradeUpdate {}
3401unsafe impl Sync for TradeUpdate {}
3402
3403#[derive(Serialize, Deserialize, Debug, Clone)]
3404pub struct WsTrade {
3405 #[serde(rename = "T")]
3406 pub timestamp: u64,
3407 #[serde(rename = "s")]
3408 pub symbol: String,
3409 #[serde(rename = "S")]
3410 pub side: String,
3411 #[serde(rename = "v", with = "string_to_float")]
3412 pub volume: f64,
3413 #[serde(rename = "p", with = "string_to_float")]
3414 pub price: f64,
3415 #[serde(rename = "L")]
3416 pub tick_direction: String,
3417 #[serde(rename = "i")]
3418 pub id: String,
3419 #[serde(rename = "BT")]
3420 pub buyer_is_maker: bool,
3421}
3422
3423unsafe impl Send for WsTrade {}
3424unsafe impl Sync for WsTrade {}
3425
3426#[derive(Serialize, Deserialize, Debug, Clone)]
3427pub struct WsTicker {
3428 pub topic: String,
3429 #[serde(rename = "type")]
3430 pub event_type: String,
3431 pub data: Tickers,
3432 pub cs: u64,
3433 pub ts: u64,
3434}
3435
3436unsafe impl Send for WsTicker {}
3437unsafe impl Sync for WsTicker {}
3438
3439#[derive(Serialize, Deserialize, Debug, Clone)]
3440pub struct LinearTickerData {
3441 pub symbol: String,
3442 #[serde(rename = "tickDirection")]
3443 pub tick_direction: String,
3444 #[serde(rename = "price24hPcnt")]
3445 pub price_24h_pcnt: String,
3446 #[serde(rename = "lastPrice")]
3447 pub last_price: String,
3448 #[serde(rename = "prevPrice24h")]
3449 pub prev_price_24h: String,
3450 #[serde(rename = "highPrice24h")]
3451 pub high_price_24h: String,
3452 #[serde(rename = "lowPrice24h")]
3453 pub low_price_24h: String,
3454 #[serde(rename = "prevPrice1h")]
3455 pub prev_price_1h: String,
3456 #[serde(rename = "markPrice")]
3457 pub mark_price: String,
3458 #[serde(rename = "indexPrice")]
3459 pub index_price: String,
3460 #[serde(rename = "openInterest")]
3461 pub open_interest: String,
3462 #[serde(rename = "openInterestValue")]
3463 pub open_interest_value: String,
3464 #[serde(rename = "turnover24h")]
3465 pub turnover_24h: String,
3466 #[serde(rename = "volume24h")]
3467 pub volume_24h: String,
3468 #[serde(rename = "nextFundingTime")]
3469 pub next_funding_time: String,
3470 #[serde(rename = "fundingRate")]
3471 pub funding_rate: String,
3472 #[serde(rename = "bid1Price")]
3473 pub bid_price: String,
3474 #[serde(rename = "bid1Size")]
3475 pub bid_size: String,
3476 #[serde(rename = "ask1Price")]
3477 pub ask_price: String,
3478 #[serde(rename = "ask1Size")]
3479 pub ask_size: String,
3480}
3481
3482unsafe impl Send for LinearTickerData {}
3483unsafe impl Sync for LinearTickerData {}
3484
3485#[derive(Serialize, Deserialize, Debug, Clone)]
3486pub struct SpotTickerData {
3487 #[serde(rename = "symbol")]
3488 pub symbol: String,
3489 #[serde(rename = "lastPrice")]
3490 pub last_price: String,
3491 #[serde(rename = "highPrice24h")]
3492 pub high_price_24h: String,
3493 #[serde(rename = "lowPrice24h")]
3494 pub low_price_24h: String,
3495 #[serde(rename = "prevPrice24h")]
3496 pub prev_price_24h: String,
3497 #[serde(rename = "volume24h")]
3498 pub volume_24h: String,
3499 #[serde(rename = "turnover24h")]
3500 pub turnover_24h: String,
3501 #[serde(rename = "price24hPcnt")]
3502 pub price_24h_pcnt: String,
3503 #[serde(rename = "usdIndexPrice")]
3504 pub usd_index_price: String,
3505}
3506
3507unsafe impl Send for SpotTickerData {}
3508unsafe impl Sync for SpotTickerData {}
3509
3510#[derive(Serialize, Deserialize, Debug, Clone)]
3511pub struct Liquidation {
3512 #[serde(rename = "topic")]
3513 pub topic: String,
3514 #[serde(rename = "type")]
3515 pub event_type: String,
3516 #[serde(rename = "ts")]
3517 pub ts: u64,
3518 #[serde(rename = "data")]
3519 pub data: LiquidationData,
3520}
3521
3522unsafe impl Send for Liquidation {}
3523unsafe impl Sync for Liquidation {}
3524
3525#[derive(Serialize, Deserialize, Debug, Clone)]
3526pub struct LiquidationData {
3527 #[serde(rename = "updatedTime")]
3528 pub updated_time: u64,
3529 #[serde(rename = "symbol")]
3530 pub symbol: String,
3531 #[serde(rename = "side")]
3532 pub side: String,
3533 #[serde(with = "string_to_float")]
3534 pub size: f64,
3535 #[serde(with = "string_to_float")]
3536 pub price: f64,
3537}
3538
3539unsafe impl Send for LiquidationData {}
3540unsafe impl Sync for LiquidationData {}
3541
3542#[derive(Serialize, Deserialize, Debug, Clone)]
3543pub struct WsKline {
3544 pub topic: String,
3545 pub data: Vec<KlineData>,
3546 #[serde(rename = "ts")]
3547 pub timestamp: u64,
3548 #[serde(rename = "type")]
3549 pub event_type: String,
3550}
3551
3552unsafe impl Send for WsKline {}
3553unsafe impl Sync for WsKline {}
3554
3555#[derive(Serialize, Deserialize, Debug, Clone)]
3556pub struct KlineData {
3557 pub start: u64,
3558 pub end: u64,
3559 pub interval: String,
3560 pub open: String,
3561 pub close: String,
3562 pub high: String,
3563 pub low: String,
3564 pub volume: String,
3565 pub turnover: String,
3566 pub confirm: bool,
3567 pub timestamp: u64,
3568}
3569
3570unsafe impl Send for KlineData {}
3571unsafe impl Sync for KlineData {}
3572
3573#[derive(Serialize, Deserialize, Debug, Clone)]
3574pub struct PositionEvent {
3575 pub id: String,
3576 pub topic: String,
3577 #[serde(rename = "creationTime")]
3578 pub creation_time: u64,
3579 pub data: Vec<PositionData>,
3580}
3581
3582unsafe impl Send for PositionEvent {}
3583unsafe impl Sync for PositionEvent {}
3584
3585#[derive(Serialize, Deserialize, Debug, Clone)]
3586pub struct PositionData {
3587 #[serde(rename = "positionIdx")]
3588 pub position_idx: u8,
3589 #[serde(rename = "tradeMode")]
3590 pub trade_mode: u8,
3591 #[serde(rename = "riskId")]
3592 pub risk_id: u8,
3593 #[serde(rename = "riskLimitValue")]
3594 pub risk_limit_value: String,
3595 pub symbol: String,
3596 pub side: String,
3597 pub size: String,
3598 #[serde(rename = "entryPrice")]
3599 pub entry_price: String,
3600 pub leverage: String,
3601 #[serde(rename = "positionValue")]
3602 pub position_value: String,
3603 #[serde(rename = "positionBalance")]
3604 pub position_balance: String,
3605 #[serde(rename = "markPrice")]
3606 pub mark_price: String,
3607 #[serde(rename = "positionIM")]
3608 pub position_im: String,
3609 #[serde(rename = "positionMM")]
3610 pub position_mm: String,
3611 #[serde(rename = "takeProfit")]
3612 pub take_profit: String,
3613 #[serde(rename = "stopLoss")]
3614 pub stop_loss: String,
3615 #[serde(rename = "trailingStop")]
3616 pub trailing_stop: String,
3617 #[serde(rename = "unrealisedPnl")]
3618 pub unrealised_pnl: String,
3619 #[serde(rename = "cumRealisedPnl")]
3620 pub cum_realised_pnl: String,
3621 #[serde(rename = "createdTime")]
3622 pub created_time: String,
3623 #[serde(rename = "updatedTime")]
3624 pub updated_time: String,
3625 #[serde(rename = "tpslMode")]
3626 pub tpsl_mode: String,
3627 #[serde(rename = "liqPrice")]
3628 pub liq_price: String,
3629 #[serde(rename = "bustPrice")]
3630 pub bust_price: String,
3631 pub category: String,
3632 #[serde(rename = "positionStatus")]
3633 pub position_status: String,
3634 #[serde(rename = "adlRankIndicator")]
3635 pub adl_rank_indicator: u8,
3636 #[serde(rename = "autoAddMargin")]
3637 pub auto_add_margin: u8,
3638 #[serde(rename = "leverageSysUpdatedTime")]
3639 pub leverage_sys_updated_time: String,
3640 #[serde(rename = "mmrSysUpdatedTime")]
3641 pub mmr_sys_updated_time: String,
3642 pub seq: u64,
3643 #[serde(rename = "isReduceOnly")]
3644 pub is_reduce_only: bool,
3645}
3646
3647unsafe impl Send for PositionData {}
3648unsafe impl Sync for PositionData {}
3649
3650#[derive(Serialize, Deserialize, Debug, Clone)]
3651pub struct Execution {
3652 #[serde(rename = "id")]
3653 pub id: String,
3654 #[serde(rename = "topic")]
3655 pub topic: String,
3656 #[serde(rename = "creationTime")]
3657 pub creation_time: u64,
3658 #[serde(rename = "data")]
3659 pub data: Vec<ExecutionData>,
3660}
3661
3662unsafe impl Send for Execution {}
3663unsafe impl Sync for Execution {}
3664
3665#[derive(Serialize, Deserialize, Debug, Clone)]
3666pub struct ExecutionData {
3667 #[serde(rename = "category")]
3668 pub category: String,
3669 #[serde(rename = "symbol")]
3670 pub symbol: String,
3671 #[serde(rename = "execFee")]
3672 pub exec_fee: String,
3673 #[serde(rename = "execId")]
3674 pub exec_id: String,
3675 #[serde(rename = "execPrice")]
3676 pub exec_price: String,
3677 #[serde(rename = "execQty")]
3678 pub exec_qty: String,
3679 #[serde(rename = "execType")]
3680 pub exec_type: String,
3681 #[serde(rename = "execValue")]
3682 pub exec_value: String,
3683 #[serde(rename = "isMaker")]
3684 pub is_maker: bool,
3685 #[serde(rename = "feeRate")]
3686 pub fee_rate: String,
3687 #[serde(rename = "tradeIv")]
3688 pub trade_iv: String,
3689 #[serde(rename = "markIv")]
3690 pub mark_iv: String,
3691 #[serde(rename = "blockTradeId")]
3692 pub block_trade_id: String,
3693 #[serde(rename = "markPrice")]
3694 pub mark_price: String,
3695 #[serde(rename = "indexPrice")]
3696 pub index_price: String,
3697 #[serde(rename = "underlyingPrice")]
3698 pub underlying_price: String,
3699 #[serde(rename = "leavesQty")]
3700 pub leaves_qty: String,
3701 #[serde(rename = "orderId")]
3702 pub order_id: String,
3703 #[serde(rename = "orderLinkId")]
3704 pub order_link_id: String,
3705 #[serde(rename = "orderPrice")]
3706 pub order_price: String,
3707 #[serde(rename = "orderQty")]
3708 pub order_qty: String,
3709 #[serde(rename = "orderType")]
3710 pub order_type: String,
3711 #[serde(rename = "stopOrderType")]
3712 pub stop_order_type: String,
3713 #[serde(rename = "side")]
3714 pub side: String,
3715 #[serde(rename = "execTime")]
3716 pub exec_time: String,
3717 #[serde(rename = "isLeverage")]
3718 pub is_leverage: String,
3719 #[serde(rename = "closedSize")]
3720 pub closed_size: String,
3721 #[serde(rename = "seq")]
3722 pub seq: u64,
3723}
3724
3725unsafe impl Send for ExecutionData {}
3726unsafe impl Sync for ExecutionData {}
3727
3728
3729#[derive(Serialize, Deserialize, Debug, Clone)]
3730pub struct FastExecution {
3731 pub topic: String,
3732 #[serde(rename = "creationTime")]
3733 pub creation_time: u64,
3734 pub data: Vec<FastExecData>
3735}
3736
3737unsafe impl Send for FastExecution {}
3738unsafe impl Sync for FastExecution {}
3739
3740#[derive(Serialize, Deserialize, Debug, Clone)]
3741pub struct FastExecData {
3742 pub category: String,
3743 pub symbol: String,
3744 #[serde(rename = "execId")]
3745 pub exec_id: String,
3746 #[serde(rename = "execPrice")]
3747 pub exec_price: String,
3748 #[serde(rename = "execQty")]
3749 pub exec_qty: String,
3750 #[serde(rename = "orderId")]
3751 pub order_id: String,
3752 #[serde(rename = "orderLinkId")]
3753 pub order_link_id: String,
3754 pub side: String,
3755 #[serde(rename = "execTime")]
3756 pub exec_time: String,
3757 pub seq: u64,
3758}
3759
3760unsafe impl Send for FastExecData {}
3761unsafe impl Sync for FastExecData {}
3762
3763
3764#[derive(Serialize, Deserialize, Debug, Clone)]
3765pub struct OrderData {
3766 pub symbol: String,
3767 #[serde(rename = "orderId")]
3768 pub order_id: String,
3769 pub side: String,
3770 #[serde(rename = "orderType")]
3771 pub order_type: String,
3772 #[serde(rename = "cancelType")]
3773 pub cancel_type: String,
3774 pub price: String,
3775 pub qty: String,
3776 #[serde(rename = "orderIv")]
3777 pub order_iv: String,
3778 #[serde(rename = "timeInForce")]
3779 pub time_in_force: String,
3780 #[serde(rename = "orderStatus")]
3781 pub order_status: String,
3782 #[serde(rename = "orderLinkId")]
3783 pub order_link_id: String,
3784 #[serde(rename = "lastPriceOnCreated")]
3785 pub last_price_on_created: String,
3786 #[serde(rename = "reduceOnly")]
3787 pub reduce_only: bool,
3788 #[serde(rename = "leavesQty")]
3789 pub leaves_qty: String,
3790 #[serde(rename = "leavesValue")]
3791 pub leaves_value: String,
3792 #[serde(rename = "cumExecQty")]
3793 pub cum_exec_qty: String,
3794 #[serde(rename = "cumExecValue")]
3795 pub cum_exec_value: String,
3796 #[serde(rename = "avgPrice")]
3797 pub avg_price: String,
3798 #[serde(rename = "blockTradeId")]
3799 pub block_trade_id: String,
3800 #[serde(rename = "positionIdx")]
3801 pub position_idx: u8,
3802 #[serde(rename = "cumExecFee")]
3803 pub cum_exec_fee: String,
3804 #[serde(rename = "createdTime")]
3805 pub created_time: String,
3806 #[serde(rename = "updatedTime")]
3807 pub updated_time: String,
3808 #[serde(rename = "rejectReason")]
3809 pub reject_reason: String,
3810 #[serde(rename = "stopOrderType")]
3811 pub stop_order_type: String,
3812 #[serde(rename = "tpslMode")]
3813 pub tpsl_mode: String,
3814 #[serde(rename = "triggerPrice")]
3815 pub trigger_price: String,
3816 #[serde(rename = "takeProfit")]
3817 pub take_profit: String,
3818 #[serde(rename = "stopLoss")]
3819 pub stop_loss: String,
3820 #[serde(rename = "tpTriggerBy")]
3821 pub tp_trigger_by: String,
3822 #[serde(rename = "slTriggerBy")]
3823 pub sl_trigger_by: String,
3824 #[serde(rename = "tpLimitPrice")]
3825 pub tp_limit_price: String,
3826 #[serde(rename = "slLimitPrice")]
3827 pub sl_limit_price: String,
3828 #[serde(rename = "triggerDirection")]
3829 pub trigger_direction: u8,
3830 #[serde(rename = "triggerBy")]
3831 pub trigger_by: String,
3832 #[serde(rename = "closeOnTrigger")]
3833 pub close_on_trigger: bool,
3834 pub category: String,
3835 #[serde(rename = "placeType")]
3836 pub place_type: String,
3837 #[serde(rename = "smpType")]
3838 pub smp_type: String,
3839 #[serde(rename = "smpGroup")]
3840 pub smp_group: u8,
3841 #[serde(rename = "smpOrderId")]
3842 pub smp_order_id: String,
3843 #[serde(rename = "feeCurrency")]
3844 pub fee_currency: String,
3845}
3846
3847unsafe impl Send for OrderData {}
3848unsafe impl Sync for OrderData {}
3849
3850#[derive(Serialize, Deserialize, Debug, Clone)]
3851pub struct OrderEvent {
3852 pub id: String,
3853 pub topic: String,
3854 #[serde(rename = "creationTime")]
3855 pub creation_time: u64,
3856 pub data: Vec<OrderData>,
3857}
3858
3859unsafe impl Send for OrderEvent {}
3860unsafe impl Sync for OrderEvent {}
3861
3862#[derive(Serialize, Deserialize, Debug, Clone)]
3863pub struct WalletEvent {
3864 pub id: String,
3865 pub topic: String,
3866 #[serde(rename = "creationTime")]
3867 pub creation_time: u64,
3868 pub data: Vec<WalletData>,
3869}
3870unsafe impl Send for WalletEvent {}
3871unsafe impl Sync for WalletEvent {}
3872
3873#[derive(Serialize, Deserialize, Debug, Clone)]
3874pub struct WalletData {
3875 #[serde(rename = "accountIMRate")]
3876 pub account_im_rate: String,
3877 #[serde(rename = "accountMMRate")]
3878 pub account_mm_rate: String,
3879 #[serde(rename = "totalEquity")]
3880 pub total_equity: String,
3881 #[serde(rename = "totalWalletBalance")]
3882 pub total_wallet_balance: String,
3883 #[serde(rename = "totalMarginBalance")]
3884 pub total_margin_balance: String,
3885 #[serde(rename = "totalAvailableBalance")]
3886 pub total_available_balance: String,
3887 #[serde(rename = "totalPerpUPL")]
3888 pub total_perp_upl: String,
3889 #[serde(rename = "totalInitialMargin")]
3890 pub total_initial_margin: String,
3891 #[serde(rename = "totalMaintenanceMargin")]
3892 pub total_maintenance_margin: String,
3893 #[serde(rename = "coin")]
3894 pub coin: Vec<CoinData>,
3895 #[serde(rename = "accountLTV")]
3896 pub account_ltv: String,
3897 #[serde(rename = "accountType", skip_serializing_if = "Option::is_none")]
3898 pub account_type: Option<String>,
3899}
3900unsafe impl Send for WalletData {}
3901unsafe impl Sync for WalletData {}
3902#[derive(Serialize, Deserialize, Debug, Clone)]
3903pub struct CoinData {
3904 #[serde(rename = "coin")]
3905 pub coin: String,
3906 #[serde(rename = "equity")]
3907 pub equity: String,
3908 #[serde(rename = "usdValue")]
3909 pub usd_value: String,
3910 #[serde(rename = "walletBalance")]
3911 pub wallet_balance: String,
3912 #[serde(rename = "availableToWithdraw")]
3913 pub available_to_withdraw: String,
3914 #[serde(rename = "availableToBorrow")]
3915 pub available_to_borrow: String,
3916 #[serde(rename = "borrowAmount")]
3917 pub borrow_amount: String,
3918 #[serde(rename = "accruedInterest")]
3919 pub accrued_interest: String,
3920 #[serde(rename = "totalOrderIM")]
3921 pub total_order_im: String,
3922 #[serde(rename = "totalPositionIM")]
3923 pub total_position_im: String,
3924 #[serde(rename = "totalPositionMM")]
3925 pub total_position_mm: String,
3926 #[serde(rename = "unrealisedPnl")]
3927 pub unrealised_pnl: String,
3928 #[serde(rename = "cumRealisedPnl")]
3929 pub cum_realised_pnl: String,
3930 pub bonus: String,
3931 #[serde(rename = "collateralSwitch")]
3932 pub collateral_switch: bool,
3933 #[serde(rename = "marginCollateral")]
3934 pub margin_collateral: bool,
3935 #[serde(rename = "locked")]
3936 pub locked: String,
3937 #[serde(rename = "spotHedgingQty")]
3938 pub spot_hedging_qty: String,
3939}
3940
3941unsafe impl Send for CoinData {}
3942unsafe impl Sync for CoinData {}
3943
3944mod string_to_u64 {
3945 use std::default;
3946
3947 use serde::{self, Deserialize, Deserializer, Serializer};
3948
3949 pub fn serialize<S>(value: &u64, serializer: S) -> Result<S::Ok, S::Error>
3951 where
3952 S: Serializer,
3953 {
3954 let s = value.to_string();
3955 serializer.serialize_str(&s)
3956 }
3957
3958 pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
3960 where
3961 D: Deserializer<'de>,
3962 {
3963 let s = String::deserialize(deserializer)?;
3964 s.parse::<u64>().map_err(serde::de::Error::custom)
3965 }
3966}
3967
3968mod string_to_float {
3969 use serde::{self, Deserialize, Deserializer, Serializer};
3970
3971 pub fn serialize<S>(value: &f64, serializer: S) -> Result<S::Ok, S::Error>
3973 where
3974 S: Serializer,
3975 {
3976 let s = value.to_string();
3977 serializer.serialize_str(&s)
3978 }
3979
3980 pub fn deserialize<'de, D>(deserializer: D) -> Result<f64, D::Error>
3982 where
3983 D: Deserializer<'de>,
3984 {
3985 let s = String::deserialize(deserializer)?;
3986 s.parse::<f64>().map_err(serde::de::Error::custom)
3987 }
3988}