1use serde::{Deserialize, Serialize};
6
7use super::string_or_float;
8use crate::types::{OrderSide, OrderStatus, OrderType, TimeInForce};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12pub enum MarginTransferType {
13 #[serde(rename = "1")]
15 MainToMargin,
16 #[serde(rename = "2")]
18 MarginToMain,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
23#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
24pub enum IsolatedMarginTransferType {
25 Spot,
27 IsolatedMargin,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
33#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
34pub enum SideEffectType {
35 #[default]
37 NoSideEffect,
38 MarginBuy,
40 AutoRepay,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46#[serde(rename_all = "camelCase")]
47pub struct TransactionId {
48 pub tran_id: u64,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54#[serde(rename_all = "camelCase")]
55pub struct MarginAccountDetails {
56 pub borrow_enabled: bool,
58 #[serde(with = "string_or_float")]
60 pub margin_level: f64,
61 #[serde(with = "string_or_float")]
63 pub total_asset_of_btc: f64,
64 #[serde(with = "string_or_float")]
66 pub total_liability_of_btc: f64,
67 #[serde(with = "string_or_float")]
69 pub total_net_asset_of_btc: f64,
70 pub trade_enabled: bool,
72 pub transfer_enabled: bool,
74 pub user_assets: Vec<MarginAsset>,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80#[serde(rename_all = "camelCase")]
81pub struct MarginAsset {
82 pub asset: String,
84 #[serde(with = "string_or_float")]
86 pub borrowed: f64,
87 #[serde(with = "string_or_float")]
89 pub free: f64,
90 #[serde(with = "string_or_float")]
92 pub interest: f64,
93 #[serde(with = "string_or_float")]
95 pub locked: f64,
96 #[serde(with = "string_or_float")]
98 pub net_asset: f64,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct IsolatedMarginAccountDetails {
105 #[serde(default)]
107 pub assets: Vec<IsolatedMarginAccountAsset>,
108 #[serde(default, with = "string_or_float_option")]
110 pub total_asset_of_btc: Option<f64>,
111 #[serde(default, with = "string_or_float_option")]
113 pub total_liability_of_btc: Option<f64>,
114 #[serde(default, with = "string_or_float_option")]
116 pub total_net_asset_of_btc: Option<f64>,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121#[serde(rename_all = "camelCase")]
122pub struct IsolatedMarginAccountAsset {
123 pub base_asset: IsolatedAssetDetails,
125 pub quote_asset: IsolatedAssetDetails,
127 pub symbol: String,
129 pub isolated_created: bool,
131 pub enabled: bool,
133 #[serde(with = "string_or_float")]
135 pub margin_level: f64,
136 #[serde(with = "string_or_float")]
138 pub margin_ratio: f64,
139 #[serde(with = "string_or_float")]
141 pub index_price: f64,
142 #[serde(with = "string_or_float")]
144 pub liquidate_price: f64,
145 #[serde(with = "string_or_float")]
147 pub liquidate_rate: f64,
148 pub trade_enabled: bool,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
154#[serde(rename_all = "camelCase")]
155pub struct IsolatedAssetDetails {
156 pub asset: String,
158 pub borrow_enabled: bool,
160 #[serde(with = "string_or_float")]
162 pub borrowed: f64,
163 #[serde(with = "string_or_float")]
165 pub free: f64,
166 #[serde(with = "string_or_float")]
168 pub interest: f64,
169 #[serde(with = "string_or_float")]
171 pub locked: f64,
172 #[serde(with = "string_or_float")]
174 pub net_asset: f64,
175 #[serde(with = "string_or_float")]
177 pub net_asset_of_btc: f64,
178 pub repay_enabled: bool,
180 #[serde(with = "string_or_float")]
182 pub total_asset: f64,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize)]
187#[serde(rename_all = "camelCase")]
188pub struct MaxBorrowableAmount {
189 #[serde(with = "string_or_float")]
191 pub amount: f64,
192 #[serde(default, with = "string_or_float_option")]
194 pub borrow_limit: Option<f64>,
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize)]
199#[serde(rename_all = "camelCase")]
200pub struct MaxTransferableAmount {
201 #[serde(with = "string_or_float")]
203 pub amount: f64,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
208#[serde(rename_all = "camelCase")]
209pub struct MarginOrderResult {
210 pub symbol: String,
212 pub order_id: u64,
214 pub client_order_id: String,
216 pub transact_time: u64,
218 #[serde(with = "string_or_float")]
220 pub price: f64,
221 #[serde(with = "string_or_float")]
223 pub orig_qty: f64,
224 #[serde(with = "string_or_float")]
226 pub executed_qty: f64,
227 #[serde(with = "string_or_float")]
229 pub cummulative_quote_qty: f64,
230 pub status: OrderStatus,
232 pub time_in_force: TimeInForce,
234 #[serde(rename = "type")]
236 pub order_type: OrderType,
237 pub side: OrderSide,
239 #[serde(default)]
241 pub is_isolated: Option<bool>,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize)]
246#[serde(rename_all = "camelCase")]
247pub struct MarginOrderState {
248 pub client_order_id: String,
250 #[serde(with = "string_or_float")]
252 pub cummulative_quote_qty: f64,
253 #[serde(with = "string_or_float")]
255 pub executed_qty: f64,
256 #[serde(default, with = "string_or_float_option")]
258 pub iceberg_qty: Option<f64>,
259 pub is_working: bool,
261 pub order_id: u64,
263 #[serde(with = "string_or_float")]
265 pub orig_qty: f64,
266 #[serde(with = "string_or_float")]
268 pub price: f64,
269 pub side: OrderSide,
271 pub status: OrderStatus,
273 #[serde(default, with = "string_or_float_option")]
275 pub stop_price: Option<f64>,
276 pub symbol: String,
278 #[serde(default)]
280 pub is_isolated: Option<bool>,
281 pub time: u64,
283 pub time_in_force: TimeInForce,
285 #[serde(rename = "type")]
287 pub order_type: OrderType,
288 pub update_time: u64,
290}
291
292#[derive(Debug, Clone, Serialize, Deserialize)]
294#[serde(rename_all = "camelCase")]
295pub struct MarginOrderCancellation {
296 pub symbol: String,
298 #[serde(default)]
300 pub order_id: Option<u64>,
301 pub orig_client_order_id: String,
303 pub client_order_id: String,
305 #[serde(with = "string_or_float")]
307 pub price: f64,
308 #[serde(with = "string_or_float")]
310 pub orig_qty: f64,
311 #[serde(with = "string_or_float")]
313 pub executed_qty: f64,
314 #[serde(with = "string_or_float")]
316 pub cummulative_quote_qty: f64,
317 pub status: OrderStatus,
319 pub time_in_force: TimeInForce,
321 #[serde(rename = "type")]
323 pub order_type: OrderType,
324 pub side: OrderSide,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize)]
330#[serde(rename_all = "camelCase")]
331pub struct MarginTrade {
332 #[serde(with = "string_or_float")]
334 pub commission: f64,
335 pub commission_asset: String,
337 pub id: u64,
339 pub is_buyer: bool,
341 #[serde(default)]
343 pub is_isolated: Option<bool>,
344 pub is_maker: bool,
346 pub order_id: u64,
348 #[serde(with = "string_or_float")]
350 pub price: f64,
351 #[serde(with = "string_or_float")]
353 pub qty: f64,
354 pub symbol: String,
356 pub time: u64,
358}
359
360#[derive(Debug, Clone, Serialize, Deserialize)]
362#[serde(rename_all = "camelCase")]
363pub struct InterestHistoryRecord {
364 pub asset: String,
366 #[serde(with = "string_or_float")]
368 pub interest: f64,
369 pub interest_accured_time: u64,
371 #[serde(with = "string_or_float")]
373 pub interest_rate: f64,
374 #[serde(with = "string_or_float")]
376 pub principal: f64,
377 #[serde(rename = "type")]
379 pub interest_type: String,
380 #[serde(default)]
382 pub isolated_symbol: Option<String>,
383}
384
385#[derive(Debug, Clone, Serialize, Deserialize)]
387#[serde(rename_all = "camelCase")]
388pub struct InterestRateRecord {
389 pub asset: String,
391 #[serde(with = "string_or_float")]
393 pub daily_interest_rate: f64,
394 pub timestamp: u64,
396 #[serde(default)]
398 pub vip_level: Option<u32>,
399}
400
401#[derive(Debug, Clone, Serialize, Deserialize)]
403#[serde(rename_all = "camelCase")]
404pub struct LoanRecord {
405 pub asset: String,
407 #[serde(with = "string_or_float")]
409 pub principal: f64,
410 pub timestamp: u64,
412 pub status: String,
414 #[serde(default)]
416 pub isolated_symbol: Option<String>,
417 pub tx_id: u64,
419}
420
421#[derive(Debug, Clone, Serialize, Deserialize)]
423#[serde(rename_all = "camelCase")]
424pub struct RepayRecord {
425 pub asset: String,
427 #[serde(with = "string_or_float")]
429 pub amount: f64,
430 #[serde(with = "string_or_float")]
432 pub interest: f64,
433 #[serde(with = "string_or_float")]
435 pub principal: f64,
436 pub timestamp: u64,
438 pub status: String,
440 #[serde(default)]
442 pub isolated_symbol: Option<String>,
443 pub tx_id: u64,
445}
446
447#[derive(Debug, Clone, Serialize, Deserialize)]
449pub struct RecordsQueryResult<T> {
450 pub total: u64,
452 pub rows: Vec<T>,
454}
455
456#[derive(Debug, Clone, Serialize, Deserialize)]
458#[serde(rename_all = "camelCase")]
459pub struct MarginPairDetails {
460 pub id: u64,
462 pub symbol: String,
464 pub base: String,
466 pub quote: String,
468 pub is_margin_trade: bool,
470 pub is_buy_allowed: bool,
472 pub is_sell_allowed: bool,
474}
475
476#[derive(Debug, Clone, Serialize, Deserialize)]
478#[serde(rename_all = "camelCase")]
479pub struct MarginAssetInfo {
480 pub asset_name: String,
482 pub asset_full_name: String,
484 pub is_borrowable: bool,
486 pub is_mortgageable: bool,
488 #[serde(with = "string_or_float")]
490 pub user_min_borrow: f64,
491 #[serde(with = "string_or_float")]
493 pub user_min_repay: f64,
494}
495
496#[derive(Debug, Clone, Serialize, Deserialize)]
498#[serde(rename_all = "camelCase")]
499pub struct MarginPriceIndex {
500 pub calc_time: u64,
502 #[serde(with = "string_or_float")]
504 pub price: f64,
505 pub symbol: String,
507}
508
509#[derive(Debug, Clone, Serialize, Deserialize)]
511#[serde(rename_all = "camelCase")]
512pub struct IsolatedAccountLimit {
513 pub enabled_account: u32,
515 pub max_account: u32,
517}
518
519#[derive(Debug, Clone, Serialize, Deserialize)]
521#[serde(rename_all = "camelCase")]
522pub struct BnbBurnStatus {
523 pub spot_bnb_burn: bool,
525 pub interest_bnb_burn: bool,
527}
528
529mod string_or_float_option {
531 use serde::{self, Deserialize, Deserializer, Serializer};
532
533 pub fn serialize<S>(value: &Option<f64>, serializer: S) -> Result<S::Ok, S::Error>
534 where
535 S: Serializer,
536 {
537 match value {
538 Some(v) => serializer.serialize_str(&v.to_string()),
539 None => serializer.serialize_none(),
540 }
541 }
542
543 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
544 where
545 D: Deserializer<'de>,
546 {
547 #[derive(Deserialize)]
548 #[serde(untagged)]
549 enum StringOrFloat {
550 String(String),
551 Float(f64),
552 }
553
554 let opt: Option<StringOrFloat> = Option::deserialize(deserializer)?;
555 match opt {
556 Some(StringOrFloat::Float(f)) => Ok(Some(f)),
557 Some(StringOrFloat::String(s)) => {
558 s.parse::<f64>().map(Some).map_err(serde::de::Error::custom)
559 }
560 None => Ok(None),
561 }
562 }
563}