Skip to main content

bybit_client/types/
account.rs

1//! Account-related types for wallet and account management.
2
3use serde::{Deserialize, Serialize};
4
5use crate::types::{AccountType, Category};
6
7
8/// Parameters for getting wallet balance.
9#[derive(Debug, Clone, Serialize)]
10#[serde(rename_all = "camelCase")]
11pub struct GetWalletBalanceParams {
12    /// Account type.
13    pub account_type: AccountType,
14    /// Coin filter.
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub coin: Option<String>,
17}
18
19impl GetWalletBalanceParams {
20    /// Create new parameters.
21    pub fn new(account_type: AccountType) -> Self {
22        Self {
23            account_type,
24            coin: None,
25        }
26    }
27
28    /// Set coin filter.
29    pub fn coin(mut self, coin: impl Into<String>) -> Self {
30        self.coin = Some(coin.into());
31        self
32    }
33}
34
35/// Parameters for getting fee rates.
36#[derive(Debug, Clone, Serialize)]
37#[serde(rename_all = "camelCase")]
38pub struct GetFeeRatesParams {
39    /// Product category.
40    pub category: Category,
41    /// Trading symbol.
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub symbol: Option<String>,
44    /// Base coin filter.
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub base_coin: Option<String>,
47}
48
49impl GetFeeRatesParams {
50    /// Create new parameters.
51    pub fn new(category: Category) -> Self {
52        Self {
53            category,
54            symbol: None,
55            base_coin: None,
56        }
57    }
58
59    /// Set symbol filter.
60    pub fn symbol(mut self, symbol: impl Into<String>) -> Self {
61        self.symbol = Some(symbol.into());
62        self
63    }
64
65    /// Set base coin filter.
66    pub fn base_coin(mut self, coin: impl Into<String>) -> Self {
67        self.base_coin = Some(coin.into());
68        self
69    }
70}
71
72/// Parameters for getting borrow history.
73#[derive(Debug, Clone, Serialize)]
74#[serde(rename_all = "camelCase")]
75pub struct GetBorrowHistoryParams {
76    /// Currency filter.
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub currency: Option<String>,
79    /// Start time (ms).
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub start_time: Option<u64>,
82    /// End time (ms).
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub end_time: Option<u64>,
85    /// Limit.
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub limit: Option<u32>,
88    /// Cursor.
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub cursor: Option<String>,
91}
92
93impl GetBorrowHistoryParams {
94    /// Create new parameters.
95    pub fn new() -> Self {
96        Self {
97            currency: None,
98            start_time: None,
99            end_time: None,
100            limit: None,
101            cursor: None,
102        }
103    }
104
105    /// Set currency filter.
106    pub fn currency(mut self, currency: impl Into<String>) -> Self {
107        self.currency = Some(currency.into());
108        self
109    }
110
111    /// Set start time.
112    pub fn start_time(mut self, start: u64) -> Self {
113        self.start_time = Some(start);
114        self
115    }
116
117    /// Set end time.
118    pub fn end_time(mut self, end: u64) -> Self {
119        self.end_time = Some(end);
120        self
121    }
122
123    /// Set limit.
124    pub fn limit(mut self, limit: u32) -> Self {
125        self.limit = Some(limit);
126        self
127    }
128
129    /// Set cursor.
130    pub fn cursor(mut self, cursor: impl Into<String>) -> Self {
131        self.cursor = Some(cursor.into());
132        self
133    }
134}
135
136impl Default for GetBorrowHistoryParams {
137    fn default() -> Self {
138        Self::new()
139    }
140}
141
142/// Parameters for getting collateral info.
143#[derive(Debug, Clone, Serialize)]
144#[serde(rename_all = "camelCase")]
145pub struct GetCollateralInfoParams {
146    /// Currency filter.
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub currency: Option<String>,
149}
150
151impl GetCollateralInfoParams {
152    /// Create new parameters.
153    pub fn new() -> Self {
154        Self { currency: None }
155    }
156
157    /// Set currency filter.
158    pub fn currency(mut self, currency: impl Into<String>) -> Self {
159        self.currency = Some(currency.into());
160        self
161    }
162}
163
164impl Default for GetCollateralInfoParams {
165    fn default() -> Self {
166        Self::new()
167    }
168}
169
170/// Parameters for setting collateral coin.
171#[derive(Debug, Clone, Serialize)]
172#[serde(rename_all = "camelCase")]
173pub struct SetCollateralCoinParams {
174    /// Coin to set.
175    pub coin: String,
176    /// Collateral switch (ON or OFF).
177    pub collateral_switch: String,
178}
179
180impl SetCollateralCoinParams {
181    /// Create parameters to enable collateral.
182    pub fn enable(coin: impl Into<String>) -> Self {
183        Self {
184            coin: coin.into(),
185            collateral_switch: "ON".to_string(),
186        }
187    }
188
189    /// Create parameters to disable collateral.
190    pub fn disable(coin: impl Into<String>) -> Self {
191        Self {
192            coin: coin.into(),
193            collateral_switch: "OFF".to_string(),
194        }
195    }
196}
197
198/// Parameters for getting coin greeks.
199#[derive(Debug, Clone, Serialize)]
200#[serde(rename_all = "camelCase")]
201pub struct GetCoinGreeksParams {
202    /// Base coin filter.
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub base_coin: Option<String>,
205}
206
207impl GetCoinGreeksParams {
208    /// Create new parameters.
209    pub fn new() -> Self {
210        Self { base_coin: None }
211    }
212
213    /// Set base coin filter.
214    pub fn base_coin(mut self, coin: impl Into<String>) -> Self {
215        self.base_coin = Some(coin.into());
216        self
217    }
218}
219
220impl Default for GetCoinGreeksParams {
221    fn default() -> Self {
222        Self::new()
223    }
224}
225
226/// Parameters for getting transaction log.
227#[derive(Debug, Clone, Serialize)]
228#[serde(rename_all = "camelCase")]
229pub struct GetTransactionLogParams {
230    /// Account type.
231    #[serde(skip_serializing_if = "Option::is_none")]
232    pub account_type: Option<AccountType>,
233    /// Product category.
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub category: Option<Category>,
236    /// Currency filter.
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub currency: Option<String>,
239    /// Base coin filter.
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub base_coin: Option<String>,
242    /// Transaction type filter.
243    #[serde(skip_serializing_if = "Option::is_none", rename = "type")]
244    pub transaction_type: Option<String>,
245    /// Start time (ms).
246    #[serde(skip_serializing_if = "Option::is_none")]
247    pub start_time: Option<u64>,
248    /// End time (ms).
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub end_time: Option<u64>,
251    /// Limit.
252    #[serde(skip_serializing_if = "Option::is_none")]
253    pub limit: Option<u32>,
254    /// Cursor.
255    #[serde(skip_serializing_if = "Option::is_none")]
256    pub cursor: Option<String>,
257}
258
259impl GetTransactionLogParams {
260    /// Create new parameters.
261    pub fn new() -> Self {
262        Self {
263            account_type: None,
264            category: None,
265            currency: None,
266            base_coin: None,
267            transaction_type: None,
268            start_time: None,
269            end_time: None,
270            limit: None,
271            cursor: None,
272        }
273    }
274
275    /// Set account type.
276    pub fn account_type(mut self, account_type: AccountType) -> Self {
277        self.account_type = Some(account_type);
278        self
279    }
280
281    /// Set category.
282    pub fn category(mut self, category: Category) -> Self {
283        self.category = Some(category);
284        self
285    }
286
287    /// Set currency filter.
288    pub fn currency(mut self, currency: impl Into<String>) -> Self {
289        self.currency = Some(currency.into());
290        self
291    }
292
293    /// Set transaction type filter.
294    pub fn transaction_type(mut self, t: impl Into<String>) -> Self {
295        self.transaction_type = Some(t.into());
296        self
297    }
298
299    /// Set start time.
300    pub fn start_time(mut self, start: u64) -> Self {
301        self.start_time = Some(start);
302        self
303    }
304
305    /// Set end time.
306    pub fn end_time(mut self, end: u64) -> Self {
307        self.end_time = Some(end);
308        self
309    }
310
311    /// Set limit.
312    pub fn limit(mut self, limit: u32) -> Self {
313        self.limit = Some(limit);
314        self
315    }
316
317    /// Set cursor.
318    pub fn cursor(mut self, cursor: impl Into<String>) -> Self {
319        self.cursor = Some(cursor.into());
320        self
321    }
322}
323
324impl Default for GetTransactionLogParams {
325    fn default() -> Self {
326        Self::new()
327    }
328}
329
330/// Parameters for setting margin mode.
331#[derive(Debug, Clone, Serialize)]
332#[serde(rename_all = "camelCase")]
333pub struct SetMarginModeParams {
334    /// Margin mode: REGULAR_MARGIN or PORTFOLIO_MARGIN.
335    pub set_margin_mode: String,
336}
337
338impl SetMarginModeParams {
339    /// Set regular margin mode.
340    pub fn regular_margin() -> Self {
341        Self {
342            set_margin_mode: "REGULAR_MARGIN".to_string(),
343        }
344    }
345
346    /// Set portfolio margin mode.
347    pub fn portfolio_margin() -> Self {
348        Self {
349            set_margin_mode: "PORTFOLIO_MARGIN".to_string(),
350        }
351    }
352}
353
354
355/// Coin balance within a wallet.
356#[derive(Debug, Clone, Deserialize)]
357#[serde(rename_all = "camelCase")]
358pub struct CoinBalance {
359    /// Coin name.
360    pub coin: String,
361    /// Equity.
362    pub equity: String,
363    /// USD value.
364    pub usd_value: String,
365    /// Wallet balance.
366    pub wallet_balance: String,
367    /// Free balance (spot only).
368    #[serde(default)]
369    pub free: Option<String>,
370    /// Locked balance (spot only).
371    #[serde(default)]
372    pub locked: Option<String>,
373    /// Borrow amount.
374    #[serde(default)]
375    pub borrow_amount: Option<String>,
376    /// Available to borrow.
377    #[serde(default)]
378    pub available_to_borrow: Option<String>,
379    /// Available to withdraw.
380    #[serde(default)]
381    pub available_to_withdraw: Option<String>,
382    /// Accrued interest.
383    #[serde(default)]
384    pub accrued_interest: Option<String>,
385    /// Total order initial margin.
386    #[serde(default)]
387    pub total_order_i_m: Option<String>,
388    /// Total position initial margin.
389    #[serde(default)]
390    pub total_position_i_m: Option<String>,
391    /// Total position maintenance margin.
392    #[serde(default)]
393    pub total_position_m_m: Option<String>,
394    /// Unrealised PnL.
395    #[serde(default)]
396    pub unrealised_pnl: Option<String>,
397    /// Cumulative realised PnL.
398    #[serde(default)]
399    pub cum_realised_pnl: Option<String>,
400    /// Bonus.
401    #[serde(default)]
402    pub bonus: Option<String>,
403    /// Margin collateral.
404    #[serde(default)]
405    pub margin_collateral: Option<bool>,
406    /// Collateral switch.
407    #[serde(default)]
408    pub collateral_switch: Option<bool>,
409    /// Spot borrow.
410    #[serde(default)]
411    pub spot_borrow: Option<String>,
412}
413
414/// Wallet balance.
415#[derive(Debug, Clone, Deserialize)]
416#[serde(rename_all = "camelCase")]
417pub struct WalletBalance {
418    /// Account type.
419    pub account_type: String,
420    /// Account LTV.
421    #[serde(default)]
422    pub account_l_t_v: Option<String>,
423    /// Account initial margin rate.
424    #[serde(default)]
425    pub account_i_m_rate: Option<String>,
426    /// Account maintenance margin rate.
427    #[serde(default)]
428    pub account_m_m_rate: Option<String>,
429    /// Total equity.
430    pub total_equity: String,
431    /// Total wallet balance.
432    pub total_wallet_balance: String,
433    /// Total margin balance.
434    #[serde(default)]
435    pub total_margin_balance: Option<String>,
436    /// Total available balance.
437    pub total_available_balance: String,
438    /// Total perpetual unrealised PnL.
439    #[serde(default)]
440    pub total_perp_u_p_l: Option<String>,
441    /// Total initial margin.
442    #[serde(default)]
443    pub total_initial_margin: Option<String>,
444    /// Total maintenance margin.
445    #[serde(default)]
446    pub total_maintenance_margin: Option<String>,
447    /// Coin balances.
448    pub coin: Vec<CoinBalance>,
449}
450
451/// Wallet balance list result.
452#[derive(Debug, Clone, Deserialize)]
453#[serde(rename_all = "camelCase")]
454pub struct WalletBalanceResult {
455    /// List of wallet balances.
456    pub list: Vec<WalletBalance>,
457}
458
459/// Account information.
460#[derive(Debug, Clone, Deserialize)]
461#[serde(rename_all = "camelCase")]
462pub struct AccountInfo {
463    /// Unified margin status.
464    #[serde(default)]
465    pub unified_margin_status: Option<i32>,
466    /// Margin mode.
467    pub margin_mode: String,
468    /// Is master trader.
469    #[serde(default)]
470    pub is_master_trader: Option<bool>,
471    /// Spot hedging status.
472    #[serde(default)]
473    pub spot_hedging_status: Option<String>,
474    /// Updated time.
475    pub updated_time: String,
476}
477
478/// Fee rate information.
479#[derive(Debug, Clone, Deserialize)]
480#[serde(rename_all = "camelCase")]
481pub struct FeeRate {
482    /// Trading symbol.
483    pub symbol: String,
484    /// Base coin.
485    #[serde(default)]
486    pub base_coin: Option<String>,
487    /// Taker fee rate.
488    pub taker_fee_rate: String,
489    /// Maker fee rate.
490    pub maker_fee_rate: String,
491}
492
493/// Fee rate list result.
494#[derive(Debug, Clone, Deserialize)]
495#[serde(rename_all = "camelCase")]
496pub struct FeeRateResult {
497    /// Product category.
498    #[serde(default)]
499    pub category: Option<Category>,
500    /// List of fee rates.
501    pub list: Vec<FeeRate>,
502}
503
504/// Borrow history record.
505#[derive(Debug, Clone, Deserialize)]
506#[serde(rename_all = "camelCase")]
507pub struct BorrowHistoryRecord {
508    /// Currency.
509    pub currency: String,
510    /// Created time.
511    pub created_time: u64,
512    /// Borrow cost.
513    pub borrow_cost: String,
514    /// Hourly borrow rate.
515    pub hourly_borrow_rate: String,
516    /// Interest bearing borrow size.
517    #[serde(rename = "InterestBearingBorrowSize")]
518    #[serde(default)]
519    pub interest_bearing_borrow_size: Option<String>,
520    /// Cost exemption.
521    #[serde(default)]
522    pub cost_exemption: Option<String>,
523    /// Borrow amount.
524    #[serde(default)]
525    pub borrow_amount: Option<String>,
526    /// Unrealised loss.
527    #[serde(default)]
528    pub unrealised_loss: Option<String>,
529    /// Free borrowed amount.
530    #[serde(default)]
531    pub free_borrowed_amount: Option<String>,
532}
533
534/// Borrow history result.
535#[derive(Debug, Clone, Deserialize)]
536#[serde(rename_all = "camelCase")]
537pub struct BorrowHistoryResult {
538    /// List of borrow history records.
539    pub list: Vec<BorrowHistoryRecord>,
540    /// Cursor for next page.
541    #[serde(default)]
542    pub next_page_cursor: Option<String>,
543}
544
545/// Collateral information.
546#[derive(Debug, Clone, Deserialize)]
547#[serde(rename_all = "camelCase")]
548pub struct CollateralInfo {
549    /// Currency.
550    pub currency: String,
551    /// Hourly borrow rate.
552    pub hourly_borrow_rate: String,
553    /// Max borrowing amount.
554    pub max_borrowing_amount: String,
555    /// Free borrow amount.
556    #[serde(default)]
557    pub free_borrow_amount: Option<String>,
558    /// Free borrowing limit.
559    #[serde(default)]
560    pub free_borrowing_limit: Option<String>,
561    /// Borrow amount.
562    #[serde(default)]
563    pub borrow_amount: Option<String>,
564    /// Available to borrow.
565    #[serde(default)]
566    pub available_to_borrow: Option<String>,
567    /// Is borrowable.
568    pub borrowable: bool,
569    /// Borrow usage rate.
570    #[serde(default)]
571    pub borrow_usage_rate: Option<String>,
572    /// Margin collateral.
573    #[serde(default)]
574    pub margin_collateral: Option<bool>,
575    /// Collateral switch.
576    #[serde(default)]
577    pub collateral_switch: Option<bool>,
578    /// Collateral ratio.
579    #[serde(default)]
580    pub collateral_ratio: Option<String>,
581}
582
583/// Collateral info result.
584#[derive(Debug, Clone, Deserialize)]
585#[serde(rename_all = "camelCase")]
586pub struct CollateralInfoResult {
587    /// List of collateral info.
588    pub list: Vec<CollateralInfo>,
589}
590
591/// Coin greeks.
592#[derive(Debug, Clone, Deserialize)]
593#[serde(rename_all = "camelCase")]
594pub struct CoinGreeks {
595    /// Base coin.
596    pub base_coin: String,
597    /// Total delta.
598    pub total_delta: String,
599    /// Total gamma.
600    pub total_gamma: String,
601    /// Total vega.
602    pub total_vega: String,
603    /// Total theta.
604    pub total_theta: String,
605}
606
607/// Coin greeks result.
608#[derive(Debug, Clone, Deserialize)]
609#[serde(rename_all = "camelCase")]
610pub struct CoinGreeksResult {
611    /// List of coin greeks.
612    pub list: Vec<CoinGreeks>,
613}
614
615/// Transaction log entry.
616#[derive(Debug, Clone, Deserialize)]
617#[serde(rename_all = "camelCase")]
618pub struct TransactionLog {
619    /// Trading symbol.
620    #[serde(default)]
621    pub symbol: Option<String>,
622    /// Product category.
623    #[serde(default)]
624    pub category: Option<String>,
625    /// Side.
626    #[serde(default)]
627    pub side: Option<String>,
628    /// Transaction time.
629    pub transaction_time: String,
630    /// Transaction type.
631    #[serde(rename = "type")]
632    pub transaction_type: String,
633    /// Quantity.
634    #[serde(default)]
635    pub qty: Option<String>,
636    /// Size.
637    #[serde(default)]
638    pub size: Option<String>,
639    /// Currency.
640    pub currency: String,
641    /// Trade price.
642    #[serde(default)]
643    pub trade_price: Option<String>,
644    /// Funding.
645    #[serde(default)]
646    pub funding: Option<String>,
647    /// Fee.
648    #[serde(default)]
649    pub fee: Option<String>,
650    /// Cash flow.
651    pub cash_flow: String,
652    /// Change.
653    pub change: String,
654    /// Cash balance.
655    pub cash_balance: String,
656    /// Fee rate.
657    #[serde(default)]
658    pub fee_rate: Option<String>,
659    /// Bonus change.
660    #[serde(default)]
661    pub bonus_change: Option<String>,
662    /// Trade ID.
663    #[serde(default)]
664    pub trade_id: Option<String>,
665    /// Order ID.
666    #[serde(default)]
667    pub order_id: Option<String>,
668    /// Order link ID.
669    #[serde(default)]
670    pub order_link_id: Option<String>,
671}
672
673/// Transaction log result.
674#[derive(Debug, Clone, Deserialize)]
675#[serde(rename_all = "camelCase")]
676pub struct TransactionLogResult {
677    /// List of transaction logs.
678    pub list: Vec<TransactionLog>,
679    /// Cursor for next page.
680    #[serde(default)]
681    pub next_page_cursor: Option<String>,
682}
683
684/// Margin mode result.
685#[derive(Debug, Clone, Deserialize)]
686#[serde(rename_all = "camelCase")]
687pub struct MarginModeResult {
688    /// List of reasons (if failed).
689    #[serde(default)]
690    pub reasons: Option<Vec<MarginModeReason>>,
691}
692
693/// Margin mode change reason.
694#[derive(Debug, Clone, Deserialize)]
695#[serde(rename_all = "camelCase")]
696pub struct MarginModeReason {
697    /// Reason code.
698    pub reason_code: String,
699    /// Reason message.
700    pub reason_msg: String,
701}
702
703#[cfg(test)]
704mod tests {
705    use super::*;
706
707    #[test]
708    fn test_get_wallet_balance_params() {
709        let params = GetWalletBalanceParams::new(AccountType::Unified)
710            .coin("BTC");
711
712        assert_eq!(params.coin, Some("BTC".to_string()));
713    }
714
715    #[test]
716    fn test_get_fee_rates_params() {
717        let params = GetFeeRatesParams::new(Category::Linear)
718            .symbol("BTCUSDT");
719
720        assert_eq!(params.symbol, Some("BTCUSDT".to_string()));
721    }
722
723    #[test]
724    fn test_set_collateral_coin_params() {
725        let enable = SetCollateralCoinParams::enable("BTC");
726        assert_eq!(enable.collateral_switch, "ON");
727
728        let disable = SetCollateralCoinParams::disable("ETH");
729        assert_eq!(disable.collateral_switch, "OFF");
730    }
731
732    #[test]
733    fn test_set_margin_mode_params() {
734        let regular = SetMarginModeParams::regular_margin();
735        assert_eq!(regular.set_margin_mode, "REGULAR_MARGIN");
736
737        let portfolio = SetMarginModeParams::portfolio_margin();
738        assert_eq!(portfolio.set_margin_mode, "PORTFOLIO_MARGIN");
739    }
740}