1use rust_decimal::{Decimal, serde::str_option::deserialize as option_decimal};
2use serde::{Deserialize, Serialize};
3use serde_aux::prelude::{
4 deserialize_number_from_string as number,
5 deserialize_option_number_from_string as option_number,
6};
7
8use crate::{
9 ContractType, CopyTrading, CurAuctionPhase, OptionType, Side, Status, Timestamp,
10 enums::{Category, Interval, IntervalTime},
11 serde::{empty_string_as_none, int_to_bool, string_to_bool},
12};
13
14#[derive(Debug, Serialize, Clone)]
15pub struct GetKLinesParams {
16 pub category: Category,
17 pub symbol: String,
18 pub interval: Interval,
19 pub start: Option<Timestamp>,
20 pub end: Option<Timestamp>,
21 pub limit: Option<u64>,
22}
23
24impl GetKLinesParams {
25 pub fn new(category: Category, symbol: impl Into<String>, interval: Interval) -> Self {
26 Self {
27 category,
28 symbol: symbol.into(),
29 interval,
30 start: None,
31 end: None,
32 limit: None,
33 }
34 }
35
36 pub fn with_start(mut self, v: Timestamp) -> Self {
37 self.start = Some(v);
38 self
39 }
40
41 pub fn with_end(mut self, v: Timestamp) -> Self {
42 self.end = Some(v);
43 self
44 }
45
46 pub fn with_limit(mut self, v: u64) -> Self {
47 self.limit = Some(v);
48 self
49 }
50}
51
52#[derive(Debug, Deserialize, PartialEq)]
53#[serde(tag = "category")]
54pub enum KLine {
55 #[serde(rename = "inverse")]
56 Inverse { symbol: String, list: Vec<KLineRow> },
57 #[serde(rename = "linear")]
58 Linear { symbol: String, list: Vec<KLineRow> },
59 #[serde(rename = "option")]
60 Option { symbol: String, list: Vec<KLineRow> },
61 #[serde(rename = "spot")]
62 Spot { symbol: String, list: Vec<KLineRow> },
63}
64
65#[derive(Debug, Deserialize, PartialEq)]
66pub struct KLineRow {
67 #[serde(rename = "startTime", deserialize_with = "number")]
69 pub start_time: Timestamp,
70 #[serde(rename = "openPrice")]
72 pub open_price: Decimal,
73 #[serde(rename = "highPrice")]
75 pub high_price: Decimal,
76 #[serde(rename = "lowPrice")]
78 pub low_price: Decimal,
79 #[serde(rename = "closePrice")]
81 pub close_price: Decimal,
82 #[serde(rename = "volume")]
84 pub volume: Decimal,
85 #[serde(rename = "turnover")]
87 pub turnover: Decimal,
88}
89
90#[derive(Debug, Serialize, Clone)]
91pub struct GetTickersParams {
92 pub category: Category,
93 pub symbol: Option<String>,
94 pub base_coin: Option<String>,
95 pub exp_date: Option<String>,
96}
97
98impl GetTickersParams {
99 pub fn new(category: Category) -> Self {
100 Self {
101 category,
102 symbol: None,
103 base_coin: None,
104 exp_date: None,
105 }
106 }
107
108 pub fn with_symbol(mut self, v: impl Into<String>) -> Self {
109 self.symbol = Some(v.into());
110 self
111 }
112
113 pub fn with_base_coin(mut self, v: impl Into<String>) -> Self {
114 self.base_coin = Some(v.into());
115 self
116 }
117
118 pub fn with_exp_date(mut self, v: impl Into<String>) -> Self {
119 self.exp_date = Some(v.into());
120 self
121 }
122}
123
124#[derive(Debug, Deserialize, PartialEq)]
125#[serde(tag = "category")]
126pub enum Ticker {
127 #[serde(rename = "inverse")]
128 Inverse { list: Vec<LinearInverseTicker> },
129 #[serde(rename = "linear")]
130 Linear { list: Vec<LinearInverseTicker> },
131 #[serde(rename = "option")]
132 Option { list: Vec<OptionTicker> },
133 #[serde(rename = "spot")]
134 Spot { list: Vec<SpotTicker> },
135}
136
137#[derive(Debug, Deserialize, PartialEq)]
138#[serde(rename_all = "camelCase")]
139pub struct LinearInverseTicker {
140 pub symbol: String,
142 pub last_price: Decimal,
144 pub mark_price: Decimal,
146 pub index_price: Decimal,
148 pub prev_price24h: Decimal,
150 pub price24h_pcnt: Decimal,
152 pub high_price24h: Decimal,
154 pub low_price24h: Decimal,
156 pub prev_price1h: Decimal,
158 pub open_interest: Decimal,
160 pub open_interest_value: Decimal,
162 pub turnover24h: Decimal,
164 pub volume24h: Decimal,
166 #[serde(default, deserialize_with = "option_decimal")]
168 pub funding_rate: Option<Decimal>,
169 #[serde(deserialize_with = "number")]
171 pub next_funding_time: Timestamp,
172 #[serde(default, deserialize_with = "option_decimal")]
174 pub predicted_delivery_price: Option<Decimal>,
175 #[serde(default, deserialize_with = "option_decimal")]
177 pub basis_rate: Option<Decimal>,
178 #[serde(default, deserialize_with = "option_decimal")]
180 pub basis: Option<Decimal>,
181 #[serde(default, deserialize_with = "option_decimal")]
183 pub delivery_fee_rate: Option<Decimal>,
184 #[serde(deserialize_with = "option_number")]
186 pub delivery_time: Option<Timestamp>,
187 pub bid1_price: Decimal,
189 pub bid1_size: Decimal,
191 pub ask1_price: Decimal,
193 pub ask1_size: Decimal,
195 #[serde(default, deserialize_with = "option_decimal")]
197 pub pre_open_price: Option<Decimal>,
198 #[serde(default, deserialize_with = "option_decimal")]
200 pub pre_qty: Option<Decimal>,
201 #[serde(default, deserialize_with = "empty_string_as_none")]
203 pub cur_pre_listing_phase: Option<CurAuctionPhase>,
204}
205
206#[derive(Debug, Deserialize, PartialEq)]
207#[serde(rename_all = "camelCase")]
208pub struct OptionTicker {
209 pub symbol: String,
211 pub bid1_price: Decimal,
213 pub bid1_size: Decimal,
215 pub bid1_iv: Decimal,
217 pub ask1_price: Decimal,
219 pub ask1_size: Decimal,
221 pub ask1_iv: Decimal,
223 pub last_price: Decimal,
225 pub high_price24h: Decimal,
227 pub low_price24h: Decimal,
229 pub mark_price: Decimal,
231 pub index_price: Decimal,
233 pub mark_iv: Decimal,
235 pub underlying_price: Decimal,
237 pub open_interest: Decimal,
239 pub turnover24h: Decimal,
241 pub volume24h: Decimal,
243 pub total_volume: Decimal,
245 pub total_turnover: Decimal,
247 pub delta: Decimal,
249 pub gamma: Decimal,
251 pub vega: Decimal,
253 pub theta: Decimal,
255 pub predicted_delivery_price: Decimal,
257 pub change24h: Decimal,
259}
260
261#[derive(Debug, Deserialize, PartialEq)]
262#[serde(rename_all = "camelCase")]
263pub struct SpotTicker {
264 pub symbol: String,
266 pub bid1_price: Decimal,
268 pub bid1_size: Decimal,
270 pub ask1_price: Decimal,
272 pub ask1_size: Decimal,
274 pub last_price: Decimal,
276 pub prev_price24h: Decimal,
278 pub price24h_pcnt: Decimal,
280 pub high_price24h: Decimal,
282 pub low_price24h: Decimal,
284 pub turnover24h: Decimal,
286 pub volume24h: Decimal,
288 #[serde(default, deserialize_with = "option_decimal")]
293 pub usd_index_price: Option<Decimal>,
294}
295
296#[derive(Debug, Serialize, Clone)]
297pub struct GetOrderbookParams {
298 pub category: Category,
299 pub symbol: String,
300 pub limit: Option<u64>,
305}
306
307impl GetOrderbookParams {
308 pub fn new(category: Category, symbol: impl Into<String>) -> Self {
309 Self {
310 category,
311 symbol: symbol.into(),
312 limit: None,
313 }
314 }
315
316 pub fn with_limit(mut self, v: u64) -> Self {
317 self.limit = Some(v);
318 self
319 }
320}
321
322#[derive(Debug, Deserialize, PartialEq)]
323pub struct Orderbook {
324 #[serde(rename = "s")]
326 pub symbol: String,
327 #[serde(rename = "b")]
329 pub bids: Vec<OrderbookLevel>,
330 #[serde(rename = "a")]
332 pub asks: Vec<OrderbookLevel>,
333 pub ts: Timestamp,
335 #[serde(rename = "u")]
338 pub update_id: i64,
339 pub seq: i64,
342 #[serde(default)]
344 pub cts: Option<Timestamp>,
345}
346
347#[derive(Debug, Deserialize, PartialEq)]
348pub struct OrderbookLevel {
349 pub price: Decimal,
351 pub size: Decimal,
353}
354
355#[derive(Debug, Serialize, Clone)]
356#[serde(rename_all = "camelCase")]
357pub struct GetTradesParams {
358 pub category: Category,
359 pub symbol: Option<String>,
362 pub base_coin: Option<String>,
365 pub option_type: Option<OptionType>,
367 pub limit: Option<u64>,
370}
371
372impl GetTradesParams {
373 pub fn new(category: Category) -> Self {
374 Self {
375 category,
376 symbol: None,
377 base_coin: None,
378 option_type: None,
379 limit: None,
380 }
381 }
382
383 pub fn with_symbol(mut self, v: impl Into<String>) -> Self {
384 self.symbol = Some(v.into());
385 self
386 }
387
388 pub fn with_base_coin(mut self, v: impl Into<String>) -> Self {
389 self.base_coin = Some(v.into());
390 self
391 }
392
393 pub fn with_option_type(mut self, v: OptionType) -> Self {
394 self.option_type = Some(v);
395 self
396 }
397
398 pub fn with_limit(mut self, v: u64) -> Self {
399 self.limit = Some(v);
400 self
401 }
402}
403
404#[derive(Debug, Deserialize, PartialEq)]
405#[serde(tag = "category")]
406pub enum Trade {
407 #[serde(rename = "inverse")]
408 Inverse { list: Vec<InverseLinearSpotTrade> },
409 #[serde(rename = "linear")]
410 Linear { list: Vec<InverseLinearSpotTrade> },
411 #[serde(rename = "option")]
412 Option { list: Vec<OptionTrade> },
413 #[serde(rename = "spot")]
414 Spot { list: Vec<InverseLinearSpotTrade> },
415}
416
417#[derive(Debug, Deserialize, PartialEq)]
418#[serde(rename_all = "camelCase")]
419pub struct InverseLinearSpotTrade {
420 pub exec_id: String,
422 pub symbol: String,
424 pub price: Decimal,
426 pub size: Decimal,
428 pub side: Side,
430 #[serde(deserialize_with = "number")]
432 pub time: Timestamp,
433 pub is_block_trade: bool,
435 #[serde(rename = "isRPITrade")]
437 pub is_rpi_trade: bool,
438}
439
440#[derive(Debug, Deserialize, PartialEq)]
441#[serde(rename_all = "camelCase")]
442pub struct OptionTrade {
443 pub exec_id: String,
445 pub symbol: String,
447 pub price: Decimal,
449 pub size: Decimal,
451 pub side: Side,
453 #[serde(deserialize_with = "number")]
455 pub time: Timestamp,
456 pub is_block_trade: bool,
458 #[serde(rename = "isRPITrade")]
460 pub is_rpi_trade: bool,
461 #[serde(rename = "mP")]
463 pub mark_price: Decimal,
464 #[serde(rename = "iP")]
466 pub index_price: Decimal,
467 #[serde(rename = "mIv")]
469 pub mark_iv: Decimal,
470 #[serde(rename = "iv")]
472 pub iv: Decimal,
473}
474
475#[derive(Debug, Deserialize, PartialEq)]
476#[serde(rename_all = "camelCase")]
477pub struct ServerTime {
478 #[serde(deserialize_with = "number")]
480 pub time_second: u64,
481 #[serde(deserialize_with = "number")]
483 pub time_nano: u64,
484}
485
486#[derive(Debug, Serialize, Clone)]
487pub struct GetInstrumentsInfoParams {
488 pub category: Category,
489 pub symbol: Option<String>,
490 pub status: Option<Status>,
491 pub base_coin: Option<String>,
492 pub limit: Option<i64>,
493 pub cursor: Option<String>,
494}
495
496impl GetInstrumentsInfoParams {
497 pub fn new(category: Category) -> Self {
498 Self {
499 category,
500 symbol: None,
501 status: None,
502 base_coin: None,
503 limit: None,
504 cursor: None,
505 }
506 }
507
508 pub fn with_symbol(mut self, v: impl Into<String>) -> Self {
509 self.symbol = Some(v.into());
510 self
511 }
512
513 pub fn with_status(mut self, v: Status) -> Self {
514 self.status = Some(v);
515 self
516 }
517
518 pub fn with_base_coin(mut self, v: impl Into<String>) -> Self {
519 self.base_coin = Some(v.into());
520 self
521 }
522
523 pub fn with_limit(mut self, v: i64) -> Self {
524 self.limit = Some(v);
525 self
526 }
527
528 pub fn with_cursor(mut self, v: impl Into<String>) -> Self {
529 self.cursor = Some(v.into());
530 self
531 }
532}
533
534#[derive(Debug, Deserialize, PartialEq)]
535#[serde(tag = "category")]
536pub enum InstrumentsInfo {
537 #[serde(rename = "inverse", rename_all = "camelCase")]
538 Inverse {
539 next_page_cursor: String,
540 list: Vec<InverseLinearInstrumentsInfo>,
541 },
542 #[serde(rename = "linear", rename_all = "camelCase")]
543 Linear {
544 next_page_cursor: String,
545 list: Vec<InverseLinearInstrumentsInfo>,
546 },
547 #[serde(rename = "option", rename_all = "camelCase")]
548 Option {
549 next_page_cursor: String,
550 list: Vec<OptionInstrumentsInfo>,
551 },
552 #[serde(rename = "spot", rename_all = "camelCase")]
553 Spot {
554 #[serde(default, deserialize_with = "empty_string_as_none")]
555 next_page_cursor: Option<String>,
556 list: Vec<SpotInstrumentsInfo>,
557 },
558}
559
560#[derive(Debug, Deserialize, PartialEq)]
561#[serde(rename_all = "camelCase")]
562pub struct InverseLinearInstrumentsInfo {
563 pub symbol: String,
564 pub contract_type: ContractType,
565 pub status: Status,
566 pub base_coin: String,
567 pub quote_coin: String,
568 #[serde(deserialize_with = "number")]
569 pub launch_time: Timestamp,
570 #[serde(deserialize_with = "number")]
571 pub delivery_time: Timestamp,
572 #[serde(deserialize_with = "option_decimal")]
573 pub delivery_fee_rate: Option<Decimal>,
574 #[serde(deserialize_with = "number")]
575 pub price_scale: i64,
576 pub leverage_filter: LeverageFilter,
577 pub price_filter: PriceFilter,
578 pub lot_size_filter: LotSizeFilter,
579 pub unified_margin_trade: bool,
580 pub funding_interval: i64,
581 pub settle_coin: String,
582 pub copy_trading: CopyTrading,
583 pub upper_funding_rate: Decimal,
584 pub lower_funding_rate: Decimal,
585 pub risk_parameters: RiskParameters,
586 pub is_pre_listing: bool,
587 pub pre_listing_info: Option<PreListingInfo>,
588}
589
590#[derive(Debug, Deserialize, PartialEq)]
591#[serde(rename_all = "camelCase")]
592pub struct OptionInstrumentsInfo {
593 pub symbol: String,
594 pub contract_type: ContractType,
595 pub status: Status,
596 pub base_coin: String,
597 pub quote_coin: String,
598 #[serde(deserialize_with = "number")]
599 pub launch_time: i64,
600 #[serde(deserialize_with = "number")]
601 pub delivery_time: i64,
602 #[serde(deserialize_with = "option_decimal")]
603 pub delivery_fee_rate: Option<Decimal>,
604 #[serde(deserialize_with = "number")]
605 pub price_scale: i64,
606 pub leverage_filter: LeverageFilter,
607 pub price_filter: PriceFilter,
608 pub lot_size_filter: LotSizeFilter,
609 pub unified_margin_trade: bool,
610 pub funding_interval: i64,
611 pub settle_coin: String,
612 pub copy_trading: CopyTrading,
613 pub upper_funding_rate: Decimal,
614 pub lower_funding_rate: Decimal,
615 pub risk_parameters: RiskParameters,
616 pub is_pre_listing: bool,
617 pub pre_listing_info: Option<PreListingInfo>,
618}
619
620#[derive(Debug, Deserialize, PartialEq)]
621#[serde(rename_all = "camelCase")]
622pub struct SpotInstrumentsInfo {
623 pub symbol: String,
625 pub base_coin: String,
627 pub quote_coin: String,
629 #[serde(deserialize_with = "string_to_bool")]
631 pub innovation: bool,
632 pub status: Status,
634 pub margin_trading: String,
638 #[serde(deserialize_with = "string_to_bool")]
640 pub st_tag: bool,
641 pub lot_size_filter: SpotLotSizeFilter,
643 pub price_filter: SpotPriceFilter,
645 pub risk_parameters: RiskParameters,
647}
648
649#[derive(Debug, Deserialize, PartialEq)]
650#[serde(rename_all = "camelCase")]
651pub struct LeverageFilter {
652 pub min_leverage: Decimal,
653 pub max_leverage: Decimal,
654 pub leverage_step: Decimal,
655}
656
657#[derive(Debug, Deserialize, PartialEq)]
658#[serde(rename_all = "camelCase")]
659pub struct PriceFilter {
660 pub min_price: Decimal,
661 pub max_price: Decimal,
662 pub tick_size: Decimal,
663}
664
665#[derive(Debug, Deserialize, PartialEq)]
666#[serde(rename_all = "camelCase")]
667pub struct SpotPriceFilter {
668 pub tick_size: Decimal,
670}
671
672#[derive(Debug, Deserialize, PartialEq)]
673#[serde(rename_all = "camelCase")]
674pub struct LotSizeFilter {
675 pub min_notional_value: Decimal,
676 pub max_order_qty: Decimal,
677 pub max_mkt_order_qty: Decimal,
678 pub min_order_qty: Decimal,
679 pub qty_step: Decimal,
680 pub post_only_max_order_qty: Decimal,
681}
682
683#[derive(Debug, Deserialize, PartialEq)]
684#[serde(rename_all = "camelCase")]
685pub struct SpotLotSizeFilter {
686 pub base_precision: Decimal,
688 pub quote_precision: Decimal,
690 pub min_order_qty: Decimal,
692 pub max_order_qty: Decimal,
694 pub min_order_amt: Decimal,
696 pub max_order_amt: Decimal,
698}
699
700#[derive(Debug, Deserialize, PartialEq)]
701#[serde(rename_all = "camelCase")]
702pub struct RiskParameters {
703 pub price_limit_ratio_x: Decimal,
704 pub price_limit_ratio_y: Decimal,
705}
706
707#[derive(Debug, Deserialize, PartialEq)]
708#[serde(rename_all = "camelCase")]
709pub struct PreListingInfo {
710 pub cur_auction_phase: CurAuctionPhase,
711 pub phases: Vec<Phase>,
712 pub auction_fee_info: AuctionFeeInfo,
713}
714
715#[derive(Debug, Deserialize, PartialEq)]
716#[serde(rename_all = "camelCase")]
717pub struct Phase {
718 pub phase: CurAuctionPhase,
719 #[serde(deserialize_with = "option_number")]
720 pub start_time: Option<Timestamp>,
721 #[serde(deserialize_with = "option_number")]
722 pub end_time: Option<Timestamp>,
723}
724
725#[derive(Debug, Deserialize, PartialEq)]
726#[serde(rename_all = "camelCase")]
727pub struct AuctionFeeInfo {
728 pub auction_fee_rate: Decimal,
729 pub taker_fee_rate: Decimal,
730 pub maker_fee_rate: Decimal,
731}
732
733#[derive(Debug, Serialize, Clone)]
739#[serde(rename_all = "camelCase")]
740pub struct GetFundingRateHistoryParams {
741 pub category: Category,
742 pub symbol: String,
743 pub start_time: Option<Timestamp>,
744 pub end_time: Option<Timestamp>,
745 pub limit: Option<u64>,
747}
748
749impl GetFundingRateHistoryParams {
750 pub fn new(category: Category, symbol: impl Into<String>) -> Self {
751 Self {
752 category,
753 symbol: symbol.into(),
754 start_time: None,
755 end_time: None,
756 limit: None,
757 }
758 }
759
760 pub fn with_start_time(mut self, v: Timestamp) -> Self {
761 self.start_time = Some(v);
762 self
763 }
764
765 pub fn with_end_time(mut self, v: Timestamp) -> Self {
766 self.end_time = Some(v);
767 self
768 }
769
770 pub fn with_limit(mut self, v: u64) -> Self {
771 self.limit = Some(v);
772 self
773 }
774}
775
776#[derive(Debug, Deserialize, PartialEq)]
778#[serde(tag = "category")]
779pub enum FundingRateHistory {
780 #[serde(rename = "linear")]
781 Linear { list: Vec<FundingRateEntry> },
782 #[serde(rename = "inverse")]
783 Inverse { list: Vec<FundingRateEntry> },
784}
785
786#[derive(Debug, Deserialize, PartialEq)]
787#[serde(rename_all = "camelCase")]
788pub struct FundingRateEntry {
789 pub symbol: String,
790 pub funding_rate: Decimal,
791 #[serde(deserialize_with = "number")]
792 pub funding_rate_timestamp: Timestamp,
793}
794
795#[derive(Debug, Serialize, Clone)]
801#[serde(rename_all = "camelCase")]
802pub struct GetOpenInterestParams {
803 pub category: Category,
804 pub symbol: String,
805 pub interval_time: IntervalTime,
806 pub start_time: Option<Timestamp>,
807 pub end_time: Option<Timestamp>,
808 pub limit: Option<u64>,
810 pub cursor: Option<String>,
811}
812
813impl GetOpenInterestParams {
814 pub fn new(category: Category, symbol: impl Into<String>, interval_time: IntervalTime) -> Self {
815 Self {
816 category,
817 symbol: symbol.into(),
818 interval_time,
819 start_time: None,
820 end_time: None,
821 limit: None,
822 cursor: None,
823 }
824 }
825
826 pub fn with_start_time(mut self, v: Timestamp) -> Self {
827 self.start_time = Some(v);
828 self
829 }
830
831 pub fn with_end_time(mut self, v: Timestamp) -> Self {
832 self.end_time = Some(v);
833 self
834 }
835
836 pub fn with_limit(mut self, v: u64) -> Self {
837 self.limit = Some(v);
838 self
839 }
840
841 pub fn with_cursor(mut self, v: impl Into<String>) -> Self {
842 self.cursor = Some(v.into());
843 self
844 }
845}
846
847#[derive(Debug, Deserialize, PartialEq)]
849#[serde(rename_all = "camelCase")]
850pub struct OpenInterest {
851 pub symbol: String,
852 pub category: String,
853 pub list: Vec<OpenInterestEntry>,
854 #[serde(default, deserialize_with = "empty_string_as_none")]
855 pub next_page_cursor: Option<String>,
856}
857
858#[derive(Debug, Deserialize, PartialEq)]
859#[serde(rename_all = "camelCase")]
860pub struct OpenInterestEntry {
861 pub open_interest: Decimal,
862 #[serde(deserialize_with = "number")]
863 pub timestamp: Timestamp,
864}
865
866#[derive(Debug, Serialize, Clone)]
872#[serde(rename_all = "camelCase")]
873pub struct GetHistoricalVolatilityParams {
874 pub category: Category,
875 pub base_coin: Option<String>,
877 pub period: Option<u16>,
879 pub start_time: Option<Timestamp>,
880 pub end_time: Option<Timestamp>,
881}
882
883impl GetHistoricalVolatilityParams {
884 pub fn new(category: Category) -> Self {
885 Self {
886 category,
887 base_coin: None,
888 period: None,
889 start_time: None,
890 end_time: None,
891 }
892 }
893
894 pub fn with_base_coin(mut self, v: impl Into<String>) -> Self {
895 self.base_coin = Some(v.into());
896 self
897 }
898
899 pub fn with_period(mut self, v: u16) -> Self {
900 self.period = Some(v);
901 self
902 }
903
904 pub fn with_start_time(mut self, v: Timestamp) -> Self {
905 self.start_time = Some(v);
906 self
907 }
908
909 pub fn with_end_time(mut self, v: Timestamp) -> Self {
910 self.end_time = Some(v);
911 self
912 }
913}
914
915#[derive(Debug, Deserialize, PartialEq)]
921pub struct HistoricalVolatilityEntry {
922 pub period: u16,
923 pub value: Decimal,
924 #[serde(deserialize_with = "number")]
925 pub time: Timestamp,
926}
927
928#[derive(Debug, Serialize, Clone, Default)]
932pub struct GetInsuranceParams {
933 pub coin: Option<String>,
934}
935
936impl GetInsuranceParams {
937 pub fn new() -> Self {
938 Self { coin: None }
939 }
940
941 pub fn with_coin(mut self, v: impl Into<String>) -> Self {
942 self.coin = Some(v.into());
943 self
944 }
945}
946
947#[derive(Debug, Deserialize, PartialEq)]
949#[serde(rename_all = "camelCase")]
950pub struct Insurance {
951 #[serde(deserialize_with = "number")]
952 pub updated_time: Timestamp,
953 pub list: Vec<InsuranceEntry>,
954}
955
956#[derive(Debug, Deserialize, PartialEq)]
957#[serde(rename_all = "camelCase")]
958pub struct InsuranceEntry {
959 pub coin: String,
960 pub balance: Decimal,
961 pub value: Decimal,
962}
963
964#[derive(Debug, Serialize, Clone)]
970pub struct GetRiskLimitParams {
971 pub category: Category,
972 pub symbol: Option<String>,
973 pub cursor: Option<String>,
974}
975
976impl GetRiskLimitParams {
977 pub fn new(category: Category) -> Self {
978 Self {
979 category,
980 symbol: None,
981 cursor: None,
982 }
983 }
984
985 pub fn with_symbol(mut self, v: impl Into<String>) -> Self {
986 self.symbol = Some(v.into());
987 self
988 }
989
990 pub fn with_cursor(mut self, v: impl Into<String>) -> Self {
991 self.cursor = Some(v.into());
992 self
993 }
994}
995
996#[derive(Debug, Deserialize, PartialEq)]
998#[serde(rename_all = "camelCase")]
999pub struct RiskLimit {
1000 pub category: String,
1001 pub list: Vec<RiskLimitEntry>,
1002}
1003
1004#[derive(Debug, Deserialize, PartialEq)]
1005#[serde(rename_all = "camelCase")]
1006pub struct RiskLimitEntry {
1007 pub id: u32,
1008 pub symbol: String,
1009 pub risk_limit_value: Decimal,
1010 pub maintenance_margin: Decimal,
1011 pub initial_margin: Decimal,
1012 #[serde(deserialize_with = "int_to_bool")]
1013 pub is_lowest_risk: bool,
1014 pub max_leverage: Decimal,
1015}
1016
1017#[derive(Debug, Serialize, Clone)]
1023#[serde(rename_all = "camelCase")]
1024pub struct GetDeliveryPriceParams {
1025 pub category: Category,
1026 pub symbol: Option<String>,
1027 pub base_coin: Option<String>,
1028 pub limit: Option<u64>,
1030 pub cursor: Option<String>,
1031}
1032
1033impl GetDeliveryPriceParams {
1034 pub fn new(category: Category) -> Self {
1035 Self {
1036 category,
1037 symbol: None,
1038 base_coin: None,
1039 limit: None,
1040 cursor: None,
1041 }
1042 }
1043
1044 pub fn with_symbol(mut self, v: impl Into<String>) -> Self {
1045 self.symbol = Some(v.into());
1046 self
1047 }
1048
1049 pub fn with_base_coin(mut self, v: impl Into<String>) -> Self {
1050 self.base_coin = Some(v.into());
1051 self
1052 }
1053
1054 pub fn with_limit(mut self, v: u64) -> Self {
1055 self.limit = Some(v);
1056 self
1057 }
1058
1059 pub fn with_cursor(mut self, v: impl Into<String>) -> Self {
1060 self.cursor = Some(v.into());
1061 self
1062 }
1063}
1064
1065#[derive(Debug, Deserialize, PartialEq)]
1067#[serde(rename_all = "camelCase")]
1068pub struct DeliveryPrice {
1069 pub category: String,
1070 #[serde(default, deserialize_with = "empty_string_as_none")]
1071 pub next_page_cursor: Option<String>,
1072 pub list: Vec<DeliveryPriceEntry>,
1073}
1074
1075#[derive(Debug, Deserialize, PartialEq)]
1076#[serde(rename_all = "camelCase")]
1077pub struct DeliveryPriceEntry {
1078 pub symbol: String,
1079 pub delivery_price: Decimal,
1080 #[serde(deserialize_with = "number")]
1081 pub delivery_time: Timestamp,
1082}
1083
1084#[cfg(test)]
1085mod tests {
1086 use super::*;
1087 use crate::{Category, serde::serialize_query};
1088
1089 #[test]
1090 fn trades_params_serialize_option_type_as_call_or_put() {
1091 let params = GetTradesParams {
1092 category: Category::Option,
1093 symbol: None,
1094 base_coin: Some(String::from("BTC")),
1095 option_type: Some(OptionType::Put),
1096 limit: None,
1097 };
1098
1099 let query = serialize_query(¶ms).unwrap();
1100
1101 assert_eq!(query, "category=option&baseCoin=BTC&optionType=Put");
1102 }
1103}