1use crate::clients::errors::ClientError;
3use crate::crypto::secrets::Token;
4use crate::request_types::TriggerType;
5use rust_decimal::Decimal;
6use serde::{Deserialize, Serialize};
7use serde_this_or_that::as_i64;
8use serde_tuple::Deserialize_tuple;
9use serde_with::formats::CommaSeparator;
10use serde_with::serde_as;
11use serde_with::StringWithSeparator;
12use std::collections::HashMap;
13use std::fmt::{Debug, Display, Formatter};
14use std::str::FromStr;
15
16#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
20#[serde(rename_all = "snake_case")]
21pub enum VerificationTier {
22 Intermediate,
23 Pro,
24}
25
26#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
28#[serde(rename_all = "snake_case")]
29pub enum SystemStatus {
30 Online,
31 Maintenance,
32 CancelOnly,
33 PostOnly,
34}
35
36#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
38#[serde(rename_all = "snake_case")]
39pub enum TradableAssetStatus {
40 Online,
41 CancelOnly,
42 PostOnly,
43 LimitOnly,
44 ReduceOnly,
45}
46
47#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
49#[serde(rename_all = "snake_case")]
50pub enum AssetStatus {
51 Enabled,
52 DepositOnly,
53 WithdrawalOnly,
54 FundingTemporarilyDisabled,
55}
56
57#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Copy)]
59#[serde(rename_all = "lowercase")]
60pub enum BuySell {
61 Buy,
62 Sell,
63}
64
65impl Display for BuySell {
66 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
67 match self {
68 BuySell::Buy => write!(f, "buy"),
69 BuySell::Sell => write!(f, "sell"),
70 }
71 }
72}
73
74#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Copy)]
76pub enum OrderFlag {
77 #[serde(rename = "post")]
79 Post,
80 #[serde(rename = "fcib")]
82 FeesInBase,
83 #[serde(rename = "fciq")]
85 FeesInQuote,
86 #[serde(rename = "nompp")]
88 NoMarketPriceProtection,
89 #[serde(rename = "viqc")]
91 OrderVolumeInQuote,
92}
93
94impl Display for OrderFlag {
95 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96 match self {
97 OrderFlag::Post => write!(f, "post"),
98 OrderFlag::FeesInBase => write!(f, "fcib"),
99 OrderFlag::FeesInQuote => write!(f, "fciq"),
100 OrderFlag::NoMarketPriceProtection => write!(f, "nompp"),
101 OrderFlag::OrderVolumeInQuote => write!(f, "viqc"),
102 }
103 }
104}
105
106impl FromStr for OrderFlag {
107 type Err = ClientError;
108
109 fn from_str(s: &str) -> Result<Self, Self::Err> {
110 match s {
111 "post" => Ok(OrderFlag::Post),
112 "fcib" => Ok(OrderFlag::FeesInBase),
113 "fciq" => Ok(OrderFlag::FeesInQuote),
114 "nompp" => Ok(OrderFlag::NoMarketPriceProtection),
115 "viqc" => Ok(OrderFlag::OrderVolumeInQuote),
116 _ => Err(ClientError::Parse("Failed to parse order flag")),
117 }
118 }
119}
120
121#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
123#[serde(rename_all = "lowercase")]
124pub enum BidOrAsk {
125 Bid,
126 Ask,
127}
128
129#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
131pub enum BuySellChar {
132 #[serde(rename(deserialize = "b"))]
133 Buy,
134 #[serde(rename(deserialize = "s"))]
135 Sell,
136}
137
138#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
140pub enum MarketLimitChar {
141 #[serde(rename(deserialize = "m"))]
142 Market,
143 #[serde(rename(deserialize = "l"))]
144 Limit,
145}
146
147#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Copy)]
149#[serde(rename_all = "kebab-case")]
150pub enum OrderType {
151 Limit,
152 Market,
153 Iceberg, StopLoss,
155 StopLossLimit,
156 TakeProfit,
157 TakeProfitLimit,
158 TrailingStop,
159 TrailingStopLimit,
160 SettlePosition,
161}
162
163#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Copy)]
165pub enum TradeType {
166 #[serde(rename = "market")]
167 Market,
168 #[serde(rename = "limit")]
169 Limit,
170 #[serde(rename = "stop loss")]
171 StopLoss,
172 #[serde(rename = "stop limit")]
173 StopLimit,
174 #[serde(rename = "take profit")]
175 TakeProfit,
176 #[serde(rename = "stop loss limit")]
177 StopLossLimit,
178 #[serde(rename = "take profit limit")]
179 TakeProfitLimit,
180 #[serde(rename = "settle position")]
181 SettlePosition,
182}
183
184impl Display for OrderType {
185 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
186 match self {
187 OrderType::Market => write!(f, "market"),
188 OrderType::Limit => write!(f, "limit"),
189 OrderType::StopLoss => write!(f, "stop-loss"),
190 OrderType::TakeProfit => write!(f, "take-profit"),
191 OrderType::StopLossLimit => write!(f, "stop-loss-limit"),
192 OrderType::TakeProfitLimit => write!(f, "take-profit-limit"),
193 OrderType::SettlePosition => write!(f, "settle-position"),
194 OrderType::Iceberg => write!(f, "iceberg"),
195 OrderType::TrailingStop => write!(f, "trailing-stop"),
196 OrderType::TrailingStopLimit => write!(f, "trailing-stop-limit"),
197 }
198 }
199}
200
201#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
203#[serde(rename_all = "lowercase")]
204pub enum OrderStatus {
205 Pending,
206 Open,
207 Closed,
208 Canceled,
209 Expired,
210}
211
212#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
214#[serde(rename_all = "snake_case")]
215pub enum OrderStatusV2 {
216 PendingNew,
217 New,
218 PartiallyFilled,
219 Filled,
220 Canceled,
221 Expired,
222}
223
224#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
226#[serde(rename_all = "lowercase")]
227pub enum PositionStatus {
228 Open,
229 Closed,
230}
231
232#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
234#[serde(rename_all = "lowercase")]
235pub enum PositionStatusV2 {
236 Opened,
237 Closing,
238 Closed,
239}
240
241#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
243#[serde(rename_all = "lowercase")]
244pub enum LedgerEntryType {
245 None,
246 Trade,
247 Credit,
248 Deposit,
249 Withdrawal,
250 Transfer,
251 Margin,
252 Rollover,
253 Spend,
254 Receive,
255 Settled,
256 Adjustment,
257 Staking,
258 Sale,
259 Dividend,
260 NftRebate,
261 NftTrade,
262 NftCreatorFee,
263 CustodyTransfer,
264}
265
266impl Display for LedgerEntryType {
267 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
268 match self {
269 LedgerEntryType::None => write!(f, "none"),
270 LedgerEntryType::Trade => write!(f, "trade"),
271 LedgerEntryType::Credit => write!(f, "credit"),
272 LedgerEntryType::Deposit => write!(f, "deposit"),
273 LedgerEntryType::Withdrawal => write!(f, "withdrawal"),
274 LedgerEntryType::Transfer => write!(f, "transfer"),
275 LedgerEntryType::Margin => write!(f, "margin"),
276 LedgerEntryType::Rollover => write!(f, "rollover"),
277 LedgerEntryType::Spend => write!(f, "spend"),
278 LedgerEntryType::Receive => write!(f, "receive"),
279 LedgerEntryType::Settled => write!(f, "settled"),
280 LedgerEntryType::Adjustment => write!(f, "adjustment"),
281 LedgerEntryType::Staking => write!(f, "staking"),
282 LedgerEntryType::Sale => write!(f, "sale"),
283 LedgerEntryType::Dividend => write!(f, "dividend"),
284 LedgerEntryType::NftRebate => write!(f, "nftrebate"),
285 LedgerEntryType::NftTrade => write!(f, "nfttrade"),
286 LedgerEntryType::NftCreatorFee => write!(f, "nftcreatorfee"),
287 LedgerEntryType::CustodyTransfer => write!(f, "custodytransfer"),
288 }
289 }
290}
291
292#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
294pub enum ExportReportStatusType {
295 Queued,
296 Processing,
297 Processed,
298}
299
300impl Display for ExportReportStatusType {
301 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
302 match self {
303 ExportReportStatusType::Queued => write!(f, "Queued"),
304 ExportReportStatusType::Processing => write!(f, "Processing"),
305 ExportReportStatusType::Processed => write!(f, "Processed"),
306 }
307 }
308}
309
310#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
312#[serde(rename_all = "lowercase")]
313pub enum OrderEditStatus {
314 Ok,
315 Err,
316}
317
318#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
323#[serde(untagged)]
324pub enum BoolOrString {
325 Bool(bool),
326 String(String),
327}
328
329#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)]
331#[serde(rename_all = "kebab-case")]
332pub enum StatusProp {
333 CancelPending,
334 Canceled,
335 CancelDenied,
336 Return,
337 #[serde(rename = "onhold")]
338 OnHold,
339}
340
341#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)]
343pub enum TransferStatus {
344 Initial,
345 Pending,
346 Settled,
347 Success,
348 Failure,
349}
350
351#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)]
353#[serde(rename_all = "lowercase")]
354pub enum AccountTransferStatus {
355 Pending,
356 Complete,
357}
358
359#[derive(Debug, Deserialize, PartialEq, Clone, Copy)]
361#[serde(untagged)]
362pub enum EarnFee {
363 Decimal(Decimal),
364 Integer(i64),
365 Float(f64),
366}
367
368#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Copy)]
370#[serde(rename_all = "snake_case")]
371pub enum YieldSourceType {
372 Staking,
373 OffChain,
374 OptInRewards,
375}
376
377#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Copy)]
379#[serde(rename_all = "lowercase")]
380pub enum AutoCompoundType {
381 Enabled,
382 Disabled,
383 Optional,
384}
385
386#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Copy)]
388#[serde(rename_all = "lowercase")]
389pub enum LockType {
390 Flex,
391 Bonded,
392 Instant,
393}
394
395#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Copy)]
397#[serde(rename_all = "lowercase")]
398pub enum AmendType {
399 Original,
400 User,
401 Restated,
402}
403
404#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
406pub struct SystemTime {
407 #[serde(rename = "unixtime")]
408 pub unix_time: i64,
409 pub rfc1123: String,
410}
411
412#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
414pub struct SystemStatusInfo {
415 pub status: SystemStatus,
416 pub timestamp: String,
417}
418
419#[derive(Debug, Deserialize, PartialEq, Clone)]
421pub struct AssetInfo {
422 #[serde(rename = "aclass")]
423 pub asset_class: String,
424 #[serde(rename = "altname")]
425 pub alt_name: String,
426 pub decimals: i64,
427 pub display_decimals: i64,
428 pub collateral_value: Option<f64>,
429 pub status: AssetStatus,
430}
431
432#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
434pub struct FeeByVolume {
435 pub volume: f64,
436 pub fee: f64,
437}
438
439#[derive(Debug, Deserialize, PartialEq, Clone)]
441pub struct TradableAssetPair {
442 #[serde(rename = "altname")]
443 pub alt_name: String,
444 #[serde(rename = "wsname")]
445 pub ws_name: String,
446 #[serde(rename = "aclass_base")]
447 pub asset_class_base: String,
448 pub base: String,
449 #[serde(rename = "aclass_quote")]
450 pub asset_class_quote: String,
451 pub quote: String,
452 pub lot: String,
453 pub cost_decimals: i64,
454 pub pair_decimals: i64,
455 pub lot_decimals: i64,
456 pub lot_multiplier: i64,
457 pub leverage_buy: Vec<i64>,
458 pub leverage_sell: Vec<i64>,
459 pub fees: Vec<FeeByVolume>,
460 pub fees_maker: Vec<FeeByVolume>,
461 pub fee_volume_currency: String,
462 pub margin_call: i64,
463 pub margin_stop: i64,
464 #[serde(rename = "ordermin")]
465 pub order_min: Decimal,
466 #[serde(rename = "costmin")]
467 pub cost_min: Decimal,
468 pub tick_size: Decimal,
469 pub status: TradableAssetStatus,
470 pub long_position_limit: Option<i64>,
471 pub short_position_limit: Option<i64>,
472}
473
474#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
476pub struct TickerTrades {
477 pub today: i64,
478 pub last_24_h: i64,
479}
480
481#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
483pub struct TickerDecimal {
484 pub today: Decimal,
485 pub last_24_h: Decimal,
486}
487
488#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
492pub struct RestTickerBidAsk {
493 pub price: Decimal,
494 pub whole_lot_volume: Decimal,
495 pub lot_volume: Decimal,
496}
497
498#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
502pub struct TickerBidAsk {
503 pub price: Decimal,
504 #[serde(deserialize_with = "as_i64")]
505 pub whole_lot_volume: i64,
506 pub lot_volume: Decimal,
507}
508
509#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
511pub struct LastTrade {
512 pub price: Decimal,
513 pub volume: Decimal,
514}
515
516#[derive(Debug, Deserialize, PartialEq, Clone)]
518pub struct RestTickerInfo {
519 #[serde(rename(deserialize = "a"))]
520 pub asks: TickerBidAsk,
521 #[serde(rename(deserialize = "b"))]
522 pub bids: TickerBidAsk,
523 #[serde(rename(deserialize = "c"))]
524 pub closed: LastTrade,
525 #[serde(rename(deserialize = "v"))]
526 pub volume: TickerDecimal,
527 #[serde(rename(deserialize = "p"))]
528 pub vwap: TickerDecimal,
529 #[serde(rename(deserialize = "t"))]
530 pub trades: TickerTrades,
531 #[serde(rename(deserialize = "l"))]
532 pub low: TickerDecimal,
533 #[serde(rename(deserialize = "h"))]
534 pub high: TickerDecimal,
535 #[serde(rename(deserialize = "o"))]
536 pub open: Decimal,
537}
538
539#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
541pub struct OHLC {
542 pub time: i64,
543 pub open: Decimal,
544 pub high: Decimal,
545 pub low: Decimal,
546 pub close: Decimal,
547 pub vwap: Decimal,
548 pub volume: Decimal,
549 pub count: i64,
550}
551
552#[derive(Debug, Deserialize, PartialEq, Clone)]
556pub struct OhlcResponse {
557 pub last: i64,
558 #[serde(flatten)]
559 pub ohlc: HashMap<String, Vec<OHLC>>,
560}
561
562#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
566pub struct BidAsk {
567 pub price: Decimal,
568 pub volume: Decimal,
569 pub time: i64,
570}
571
572#[derive(Debug, Deserialize, PartialEq, Clone)]
574pub struct Orderbook {
575 pub asks: Vec<BidAsk>,
576 pub bids: Vec<BidAsk>,
577}
578
579#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
583pub struct RecentTrade {
584 pub price: Decimal,
585 pub volume: Decimal,
586 pub time: f64,
587 pub buy_sell: BuySellChar,
588 pub market_limit: MarketLimitChar,
589 pub misc: String,
590 pub trade_id: i64,
591}
592
593#[serde_as]
597#[derive(Debug, Deserialize, PartialEq, Clone)]
598pub struct RecentTrades {
599 pub last: String,
600 #[serde(flatten)]
601 pub trades: HashMap<String, Vec<RecentTrade>>,
602}
603
604#[derive(Debug, Deserialize_tuple, PartialEq, Clone)]
606pub struct Spread {
607 pub time: i64,
608 pub bid: Decimal,
609 pub ask: Decimal,
610}
611
612#[derive(Debug, Deserialize, PartialEq, Clone)]
616pub struct RecentSpreads {
617 pub last: i64,
618 #[serde(flatten)]
619 pub spreads: HashMap<String, Vec<Spread>>,
620}
621
622pub type AccountBalances = HashMap<String, Decimal>;
624
625pub type ExtendedBalances = HashMap<String, ExtendedBalance>;
627
628#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
630pub struct ExtendedBalance {
631 pub balance: Decimal,
632 pub hold_trade: Decimal,
633 pub credit: Option<Decimal>,
634 pub credit_used: Option<Decimal>,
635}
636
637#[derive(Debug, Deserialize, PartialEq, Clone)]
639pub struct TradeBalances {
640 #[serde(rename(deserialize = "eb"))]
641 pub equivalent_balance: Decimal,
642 #[serde(rename(deserialize = "tb"))]
643 pub trade_balance: Decimal,
644 #[serde(rename(deserialize = "m"))]
645 pub margin: Decimal,
646 #[serde(rename(deserialize = "n"))]
647 pub net_pnl_open: Decimal,
648 #[serde(rename(deserialize = "c"))]
649 pub cost_basis_open: Decimal,
650 #[serde(rename(deserialize = "v"))]
651 pub floating_valuation: Decimal,
652 #[serde(rename(deserialize = "e"))]
653 pub equity: Decimal,
654 #[serde(rename(deserialize = "mf"))]
655 pub free_margin: Decimal,
656 #[serde(rename(deserialize = "ml"))]
657 pub margin_level: Option<Decimal>,
658 #[serde(rename(deserialize = "uv"))]
659 pub unexecuted_value: Option<Decimal>,
660}
661
662#[derive(Debug, Deserialize, PartialEq, Clone)]
664pub struct OrderDescription {
665 pub pair: String,
666 #[serde(rename(deserialize = "type"))]
667 pub side: BuySell,
668 #[serde(rename(deserialize = "ordertype"))]
669 pub order_type: OrderType,
670 pub price: Decimal,
671 pub price2: Decimal,
672 pub leverage: String,
673 pub order: String,
674 pub close: String,
675}
676
677#[derive(Debug, Deserialize, PartialEq, Clone)]
679pub struct OpenOrders {
680 pub open: HashMap<String, Order>,
681}
682
683#[serde_as]
685#[derive(Debug, Deserialize, PartialEq, Clone)]
686pub struct Order {
687 #[serde(rename = "refid")]
688 pub ref_id: Option<String>,
689 pub userref: Option<i64>,
690 #[serde(rename = "cl_ord_id")]
691 pub client_order_id: Option<String>,
692 pub status: OrderStatus,
693 #[serde(rename = "opentm")]
694 pub open_time: f64,
695 #[serde(rename = "starttm")]
696 pub start_time: f64,
697 #[serde(rename = "expiretm")]
698 pub expire_time: f64,
699 #[serde(rename = "closetm")]
700 pub close_time: Option<f64>,
701 pub descr: OrderDescription,
702 #[serde(rename(deserialize = "vol"))]
703 pub volume: Decimal,
704 #[serde(rename(deserialize = "vol_exec"))]
705 pub volume_executed: Decimal,
706 pub cost: Decimal,
707 pub fee: Decimal,
708 pub price: Decimal,
709 #[serde(rename = "stopprice")]
710 pub stop_price: Decimal,
711 #[serde(rename = "limitprice")]
712 pub limit_price: Decimal,
713 pub trigger: Option<TriggerType>,
714 pub margin: Option<bool>,
715 pub misc: String,
716 pub sender_sub_id: Option<String>,
717 #[serde(rename = "oflags")]
718 #[serde_as(as = "StringWithSeparator::<CommaSeparator, OrderFlag>")]
719 pub order_flags: Vec<OrderFlag>,
720 pub trades: Option<Vec<String>>,
721 pub reason: Option<String>,
722}
723
724#[serde_as]
726#[derive(Debug, Deserialize, PartialEq, Clone)]
727pub struct ClosedOrder {
728 #[serde(rename = "refid")]
729 pub ref_id: Option<String>,
730 pub userref: Option<i64>,
731 #[serde(rename = "cl_ord_id")]
732 pub client_order_id: Option<String>,
733 pub status: OrderStatus,
734 #[serde(rename = "opentm")]
735 pub open_time: f64,
736 #[serde(rename = "starttm")]
737 pub start_time: f64,
738 #[serde(rename = "expiretm")]
739 pub expire_time: f64,
740 #[serde(rename = "closetm")]
741 pub close_time: Option<f64>,
742 #[serde(rename(deserialize = "vol"))]
743 pub volume: Decimal,
744 #[serde(rename(deserialize = "vol_exec"))]
745 pub volume_executed: Decimal,
746 pub cost: Decimal,
747 pub fee: Decimal,
748 pub price: Decimal,
749 #[serde(rename = "stopprice")]
750 pub stop_price: Decimal,
751 #[serde(rename = "limitprice")]
752 pub limit_price: Decimal,
753 pub trigger: Option<TriggerType>,
754 pub margin: Option<bool>,
755 pub misc: String,
756 #[serde(rename = "oflags")]
757 #[serde_as(as = "StringWithSeparator::<CommaSeparator, OrderFlag>")]
758 pub order_flags: Vec<OrderFlag>,
759 pub trades: Option<Vec<String>>,
760 pub sender_sub_id: Option<String>,
761 pub reason: Option<String>,
762}
763
764#[derive(Debug, Deserialize, PartialEq, Clone)]
766pub struct ClosedOrders {
767 pub closed: HashMap<String, ClosedOrder>,
768 pub count: i64,
769}
770
771#[derive(Debug, Deserialize, PartialEq, Clone)]
775pub struct Trade {
776 #[serde(rename = "ordertxid")]
777 pub order_tx_id: String,
778 #[serde(rename = "postxid")]
779 pub post_xid: String,
780 pub pair: String,
781 pub time: f64,
782 #[serde(rename(deserialize = "type"))]
783 pub side: BuySell,
784 #[serde(rename = "ordertype")]
785 pub order_type: TradeType,
786 pub price: Decimal,
787 pub cost: Decimal,
788 pub fee: Decimal,
789 #[serde(rename(deserialize = "vol"))]
790 pub volume: Decimal,
791 pub margin: Decimal,
792 pub misc: String,
793 pub ledgers: Option<Vec<String>>,
794 pub maker: bool,
795}
796
797pub type TradesInfo = HashMap<String, Trade>;
799
800#[derive(Debug, Deserialize, PartialEq, Clone)]
802pub struct TradesHistory {
803 pub trades: TradesInfo,
804 pub count: i64,
805}
806
807#[derive(Debug, Deserialize, PartialEq, Clone)]
808pub struct OrderAmends {
809 pub amends: Vec<OrderAmend>,
810 pub count: u32,
811}
812
813#[derive(Debug, Deserialize, PartialEq, Clone)]
814pub struct OrderAmend {
815 pub amend_id: String,
816 pub amend_type: AmendType,
817 #[serde(rename = "order_qty")]
818 pub order_quantity: Decimal,
819 #[serde(rename = "display_qty")]
820 pub display_quantity: Option<Decimal>,
821 #[serde(rename = "remaining_qty")]
822 pub remaining_quantity: Decimal,
823 pub limit_price: Decimal,
824 pub trigger_price: Option<Decimal>,
825 pub reason: Option<String>,
826 pub post_only: bool,
827 pub timestamp: u64,
828}
829
830pub type OpenPositions = HashMap<String, OpenPosition>;
832
833#[serde_as]
835#[derive(Debug, Deserialize, PartialEq, Clone)]
836pub struct OpenPosition {
837 #[serde(rename = "ordertxid")]
838 pub order_tx_id: String,
839 #[serde(rename = "posstatus")]
840 pub pos_status: PositionStatus,
841 pub pair: String,
842 pub time: f64,
843 #[serde(rename(deserialize = "type"))]
844 pub side: BuySell,
845 #[serde(rename = "ordertype")]
846 pub order_type: OrderType,
847 pub cost: Decimal,
848 pub fee: Decimal,
849 #[serde(rename(deserialize = "vol"))]
850 pub volume: Decimal,
851 #[serde(rename(deserialize = "vol_closed"))]
852 pub volume_closed: Decimal,
853 pub margin: Decimal,
854 pub value: Option<Decimal>,
855 pub net: Option<Decimal>,
856 pub terms: String,
857 #[serde(rename = "rollovertm")]
858 pub rollover_time: String,
859 pub misc: String,
860 #[serde(rename = "oflags")]
861 #[serde_as(as = "StringWithSeparator::<CommaSeparator, OrderFlag>")]
862 pub order_flags: Vec<OrderFlag>,
863}
864
865#[derive(Debug, Deserialize, PartialEq, Clone)]
867pub struct LedgerEntry {
868 #[serde(rename = "refid")]
869 pub ref_id: String,
870 pub time: f64,
871 #[serde(rename(deserialize = "type"))]
872 pub entry_type: LedgerEntryType,
873 pub subtype: String,
874 #[serde(rename = "aclass")]
875 pub asset_class: String,
876 pub asset: String,
877 pub amount: Decimal,
878 pub fee: Decimal,
879 pub balance: Decimal,
880}
881
882pub type QueryLedgerInfo = HashMap<String, LedgerEntry>;
884
885#[derive(Debug, Deserialize, PartialEq, Clone)]
887pub struct LedgerInfo {
888 pub ledger: QueryLedgerInfo,
889 pub count: i64,
890}
891
892#[derive(Debug, Deserialize, PartialEq, Clone)]
894pub struct Fees {
895 pub fee: Decimal,
896 #[serde(rename = "minfee")]
897 pub min_fee: Decimal,
898 #[serde(rename = "maxfee")]
899 pub max_fee: Decimal,
900 #[serde(rename = "nextfee")]
901 pub next_fee: Option<Decimal>,
902 #[serde(rename = "nextvolume")]
903 pub next_volume: Option<Decimal>,
904 #[serde(rename = "tiervolume")]
905 pub tier_volume: Option<Decimal>,
906}
907
908#[derive(Debug, Deserialize, PartialEq, Clone)]
913pub struct TradeVolume {
914 pub currency: String,
915 pub volume: Decimal,
916 pub fees: Option<HashMap<String, Fees>>,
917 pub fees_maker: Option<HashMap<String, Fees>>,
918}
919
920#[derive(Debug, Deserialize, PartialEq, Clone)]
922pub struct ExportReport {
923 pub id: String,
924}
925
926#[derive(Debug, Deserialize, PartialEq, Clone)]
928pub struct ExportReportStatus {
929 pub id: String,
930 pub descr: String,
931 pub format: String,
932 pub report: String,
933 pub subtype: String,
934 pub status: ExportReportStatusType,
935 pub fields: String,
936 #[serde(rename = "createdtm")]
937 pub created_time: String,
938 #[serde(rename = "starttm")]
939 pub start_time: String,
940 #[serde(rename = "completedtm")]
941 pub completed_time: String,
942 #[serde(rename = "datastarttm")]
943 pub data_start_time: String,
944 #[serde(rename = "dataendtm")]
945 pub data_end_time: String,
946 pub asset: String,
947}
948
949#[derive(Debug, Deserialize, PartialEq, Clone)]
951pub struct DeleteExportReport {
952 pub delete: Option<bool>,
953 pub cancel: Option<bool>,
954}
955
956#[derive(Debug, Deserialize, PartialEq, Clone)]
960pub struct AddOrderDescription {
961 pub order: String,
962 pub close: Option<String>,
963}
964
965#[derive(Debug, Deserialize, PartialEq, Clone)]
967pub struct AddOrder {
968 #[serde(rename = "txid")]
969 pub tx_id: Vec<String>,
970 pub descr: AddOrderDescription,
971 pub error: Option<String>,
972}
973
974#[derive(Debug, Deserialize, PartialEq, Clone)]
976pub struct BatchedOrder {
977 #[serde(rename = "txid")]
978 pub tx_id: String,
979 pub descr: AddOrderDescription,
980 pub error: Option<String>,
981}
982
983#[derive(Debug, Deserialize, PartialEq, Clone)]
985pub struct AddOrderBatch {
986 pub orders: Vec<BatchedOrder>,
987}
988
989#[derive(Debug, Deserialize, PartialEq, Clone)]
990pub struct AmendOrder {
991 pub amend_id: String,
992}
993
994#[derive(Debug, Deserialize, PartialEq, Clone)]
996pub struct OrderEdit {
997 pub status: OrderEditStatus,
998 #[serde(rename = "txid")]
999 pub tx_id: String,
1000 #[serde(rename = "originaltxid")]
1001 pub original_tx_id: String,
1002 pub volume: Decimal,
1003 pub price: Decimal,
1004 pub price2: Option<Decimal>,
1005 pub orders_cancelled: i64,
1006 pub descr: AddOrderDescription,
1007}
1008
1009#[derive(Debug, Deserialize, PartialEq, Clone)]
1011pub struct CancelOrder {
1012 pub count: i64,
1013 pub pending: Option<bool>,
1014}
1015
1016#[derive(Debug, Deserialize, PartialEq, Clone)]
1018#[serde(rename_all = "camelCase")]
1019pub struct CancelAllOrdersAfter {
1020 pub current_time: String,
1021 pub trigger_time: String,
1022}
1023
1024#[derive(Debug, Deserialize, PartialEq, Clone)]
1026#[serde(rename_all = "kebab-case")]
1027pub struct DepositMethod {
1028 pub method: String,
1029 pub limit: BoolOrString,
1030 pub fee: Option<Decimal>,
1031 pub address_setup_fee: Option<Decimal>,
1032 pub gen_address: Option<bool>,
1033 pub minimum: Decimal,
1034}
1035
1036#[derive(Debug, Deserialize, PartialEq, Clone)]
1038pub struct WithdrawMethod {
1039 pub asset: String,
1040 pub method: String,
1041 pub network: Option<String>,
1042 pub minimum: Decimal,
1043}
1044
1045#[derive(Debug, Deserialize, PartialEq, Clone)]
1047pub struct DepositAddress {
1048 pub address: String,
1049 #[serde(rename = "expiretm")]
1050 pub expire_time: String,
1051 pub new: Option<bool>,
1052 pub memo: Option<String>,
1053 pub tag: Option<String>,
1054}
1055
1056#[derive(Debug, Deserialize, PartialEq, Clone)]
1058pub struct WithdrawalAddress {
1059 pub address: String,
1060 pub asset: String,
1061 pub method: String,
1062 pub key: String,
1063 pub memo: Option<String>,
1064 pub verified: bool,
1065}
1066
1067#[derive(Debug, Deserialize, PartialEq, Clone)]
1071#[serde(untagged)]
1072pub enum DepositWithdrawResponse {
1073 Cursor(DepositWithdrawalCursor),
1074 Response(Vec<DepositWithdrawal>),
1075}
1076
1077#[derive(Debug, Deserialize, PartialEq, Clone)]
1079pub struct DepositWithdrawalCursor {
1080 deposit: Vec<DepositWithdrawal>,
1081 cursor: BoolOrString,
1082}
1083
1084#[derive(Debug, Deserialize, PartialEq, Clone)]
1086pub struct DepositWithdrawal {
1087 pub method: String,
1088 #[serde(rename = "aclass")]
1089 pub asset_class: String,
1090 pub asset: String,
1091 #[serde(rename = "refid")]
1092 pub ref_id: String,
1093 #[serde(rename = "txid")]
1094 pub tx_id: String,
1095 pub info: String,
1096 pub amount: Decimal,
1097 pub fee: Decimal,
1098 pub time: i64,
1099 pub status: TransferStatus,
1100 #[serde(rename = "status-prop")]
1101 pub status_prop: Option<StatusProp>,
1102 pub orginators: Option<Vec<String>>,
1103}
1104
1105#[derive(Debug, Deserialize, PartialEq, Clone)]
1107pub struct Withdrawal {
1108 pub method: String,
1109 pub limit: BoolOrString,
1110 pub fee: Decimal,
1111 pub amount: Decimal,
1112}
1113
1114#[derive(Debug, Deserialize, PartialEq, Clone)]
1116pub struct ConfirmationRefId {
1117 #[serde(rename = "refid")]
1118 pub ref_id: String,
1119}
1120
1121#[derive(Debug, Deserialize, PartialEq, Clone)]
1123pub struct AccountTransfer {
1124 pub transfer_id: String,
1125 pub status: AccountTransferStatus,
1126}
1127
1128#[derive(Debug, Deserialize, PartialEq, Clone)]
1130pub struct AllocationStatus {
1131 pub pending: bool,
1132}
1133
1134#[derive(Debug, Deserialize, PartialEq, Clone)]
1136pub struct EarnStrategies {
1137 pub items: Vec<EarnStrategy>,
1138 pub next_cursor: Option<String>,
1139}
1140
1141#[derive(Debug, Deserialize, PartialEq, Clone)]
1143pub struct EarnStrategy {
1144 pub allocation_fee: EarnFee,
1145 pub allocation_restriction_info: Vec<String>,
1146 pub apr_estimate: Option<AprEstimate>,
1147 pub asset: String,
1148 pub auto_compound: AutoCompound,
1149 pub can_allocate: bool,
1150 pub can_deallocate: bool,
1151 pub deallocation_fee: EarnFee,
1152 pub id: String,
1153 pub lock_type: LockTypeDetail,
1154 pub user_cap: Option<Decimal>,
1155 pub user_min_allocation: Option<Decimal>,
1156 pub yield_source: YieldSource,
1157}
1158
1159#[derive(Debug, Deserialize, PartialEq, Clone)]
1161pub struct LockTypeDetail {
1162 #[serde(rename = "type")]
1163 pub lock_type: LockType,
1164 #[serde(flatten)]
1165 pub bonding: Option<BondingDetail>,
1166}
1167
1168#[derive(Debug, Deserialize, PartialEq, Clone)]
1170pub struct BondingDetail {
1171 pub payout_frequency: Option<i64>,
1172 pub bonding_period: Option<i64>,
1173 pub bonding_period_variable: Option<bool>,
1174 pub bonding_rewards: Option<bool>,
1175 pub exit_queue_period: Option<i64>,
1176 pub unbonding_period: Option<i64>,
1177 pub unbonding_period_variable: Option<bool>,
1178 pub unbonding_rewards: Option<bool>,
1179}
1180
1181#[derive(Debug, Deserialize, PartialEq, Clone)]
1183pub struct AprEstimate {
1184 pub low: Decimal,
1185 pub high: Decimal,
1186}
1187
1188#[derive(Debug, Deserialize, PartialEq, Clone)]
1190pub struct AutoCompound {
1191 #[serde(rename = "type")]
1192 pub auto_compound_type: AutoCompoundType,
1193 pub default: Option<bool>,
1194}
1195
1196#[derive(Debug, Deserialize, PartialEq, Clone)]
1198pub struct YieldSource {
1199 #[serde(rename = "type")]
1200 pub yield_type: YieldSourceType,
1201}
1202
1203#[derive(Debug, Deserialize, PartialEq, Clone)]
1205pub struct EarnAllocations {
1206 pub converted_asset: String,
1207 pub items: Vec<EarnAllocation>,
1208 pub total_allocated: Decimal,
1209 pub total_rewarded: Decimal,
1210}
1211
1212#[derive(Debug, Deserialize, PartialEq, Clone)]
1214pub struct EarnAllocation {
1215 pub amount_allocated: AmountAllocated,
1216 pub native_asset: String,
1217 pub payout: Option<Payout>,
1218 pub strategy_id: String,
1219 pub total_rewarded: EarnAmount,
1220}
1221
1222#[derive(Debug, Deserialize, PartialEq, Clone)]
1224pub struct AmountAllocated {
1225 pub bonding: Option<AllocationState>,
1226 pub exit_queue: Option<AllocationState>,
1227 pub pending: Option<EarnAmount>,
1228 pub total: EarnAmount,
1229 pub unbonding: Option<AllocationState>,
1230}
1231
1232#[derive(Debug, Deserialize, PartialEq, Clone)]
1234pub struct AllocationState {
1235 pub allocation_count: i64,
1236 pub allocations: Vec<Allocation>,
1237 pub converted: Decimal,
1238 pub native: Decimal,
1239}
1240
1241#[derive(Debug, Deserialize, PartialEq, Clone)]
1243pub struct Allocation {
1244 pub created_at: String,
1245 pub expires: String,
1246 pub converted: Decimal,
1247 pub native: Decimal,
1248}
1249
1250#[derive(Debug, Deserialize, PartialEq, Clone)]
1252pub struct Payout {
1253 pub period_end: String,
1254 pub period_start: String,
1255 pub accumulated_reward: EarnAmount,
1256 pub estimated_reward: EarnAmount,
1257}
1258
1259#[derive(Debug, Deserialize, PartialEq, Clone, Copy)]
1261pub struct EarnAmount {
1262 pub converted: Decimal,
1263 pub native: Decimal,
1264}
1265
1266#[derive(Debug, Deserialize, Clone)]
1268pub struct WebsocketToken {
1269 pub token: Token,
1270 pub expires: i64,
1271}
1272
1273#[cfg(test)]
1274mod tests {
1275 use crate::response_types::ExtendedBalance;
1276 use rust_decimal_macros::dec;
1277
1278 #[test]
1279 fn test_deserializing_extended_balance_full() {
1280 let balance =
1281 r#"{"balance": "0.01", "hold_trade": "0.02", "credit": "0.03", "credit_used": "0.04"}"#;
1282
1283 let expected_balance = ExtendedBalance {
1284 balance: dec!(0.01),
1285 hold_trade: dec!(0.02),
1286 credit: Some(dec!(0.03)),
1287 credit_used: Some(dec!(0.04)),
1288 };
1289
1290 assert_eq!(expected_balance, serde_json::from_str(balance).unwrap());
1291 }
1292
1293 #[test]
1294 fn test_deserializing_extended_balance_some_none() {
1295 let balance_missing = r#"{"balance": "0.01", "hold_trade": "0.02"}"#;
1296
1297 let expected_balance = ExtendedBalance {
1298 balance: dec!(0.01),
1299 hold_trade: dec!(0.02),
1300 credit: None,
1301 credit_used: None,
1302 };
1303
1304 assert_eq!(
1305 expected_balance,
1306 serde_json::from_str(balance_missing).unwrap()
1307 );
1308 }
1309
1310 #[test]
1311 fn test_deserializing_extended_balance_some_gibberish() {
1312 let gibberish = r#"{"balance": "0.01", "hold_trade": "0.02", "credit": "soNotANumber"}"#;
1313
1314 assert!(serde_json::from_str::<ExtendedBalance>(gibberish).is_err())
1315 }
1316}