Skip to main content

asterdex_sdk/futures/models/
account.rs

1// Tech Lead mini-task (Wave 4): replaced stubs with full type definitions
2// per 05_detail_design.md §2.3
3
4use serde::{Deserialize, Serialize};
5use crate::futures::models::de;
6
7// --- Balance ---
8
9/// Account balance for a single asset.
10#[derive(Debug, Deserialize)]
11pub struct Balance {
12    #[serde(rename = "accountAlias", default)]
13    pub account_alias: String,
14    pub asset: String,
15    /// Some testnet deployments return this field as `"balance"` instead of `"walletBalance"`.
16    #[serde(rename = "walletBalance", alias = "balance")]
17    pub wallet_balance: String,
18    #[serde(rename = "crossWalletBalance")]
19    pub cross_wallet_balance: String,
20    #[serde(rename = "crossUnPnl")]
21    pub cross_unpnl: String,
22    #[serde(rename = "availableBalance")]
23    pub available_balance: String,
24    #[serde(rename = "maxWithdrawAmount")]
25    pub max_withdraw_amount: String,
26    #[serde(rename = "marginAvailable", default)]
27    pub margin_available: bool,
28    #[serde(rename = "updateTime")]
29    pub update_time: u64,
30}
31
32// --- Position Side ---
33
34/// Response for the position side dual (hedge mode) setting.
35#[derive(Debug, Deserialize)]
36pub struct PositionSideDualResponse {
37    #[serde(rename = "dualSidePosition")]
38    pub dual_side_position: bool,
39}
40
41// --- Leverage ---
42
43/// Leverage bracket information for a symbol.
44#[derive(Debug, Deserialize)]
45pub struct LeverageBracket {
46    pub symbol: String,
47    pub brackets: Vec<Bracket>,
48}
49
50/// A single leverage bracket within a `LeverageBracket`.
51///
52/// `notional_cap`, `notional_floor`, `maint_margin_ratio`, and `cum` are returned
53/// as JSON numbers on some deployments and as JSON strings on others — the
54/// `string_or_number` deserializer normalises both forms to `String`.
55#[derive(Debug, Deserialize)]
56pub struct Bracket {
57    pub bracket: u32,
58    #[serde(rename = "initialLeverage")]
59    pub initial_leverage: u32,
60    #[serde(rename = "notionalCap", deserialize_with = "de::string_or_number")]
61    pub notional_cap: String,
62    #[serde(rename = "notionalFloor", deserialize_with = "de::string_or_number")]
63    pub notional_floor: String,
64    #[serde(rename = "maintMarginRatio", deserialize_with = "de::string_or_number")]
65    pub maint_margin_ratio: String,
66    #[serde(deserialize_with = "de::string_or_number")]
67    pub cum: String,
68}
69
70/// Response from setting leverage for a symbol.
71#[derive(Debug, Deserialize)]
72pub struct SetLeverageResponse {
73    pub leverage: u32,
74    #[serde(rename = "maxNotionalValue")]
75    pub max_notional_value: String,
76    pub symbol: String,
77}
78
79// --- Cancel All Orders ---
80
81/// Response from cancelling all open orders for a symbol.
82#[derive(Debug, Deserialize)]
83pub struct CancelAllResponse {
84    pub code: i64,
85    pub msg: String,
86}
87
88// --- Batch Orders ---
89
90/// Per-item result in a batch order response.
91/// May be a success (has `order_id`) or an error (has `code` + `msg`).
92#[derive(Debug, Deserialize)]
93pub struct BatchOrderResult {
94    #[serde(rename = "orderId")]
95    pub order_id: Option<i64>,
96    pub code: Option<i64>,
97    pub msg: Option<String>,
98    pub symbol: Option<String>,
99    pub status: Option<String>,
100}
101
102// --- Generic Status/Message Response ---
103
104/// Generic status/message response (code + message).
105#[derive(Debug, Deserialize)]
106pub struct StatusMsgResponse {
107    pub code: i64,
108    pub msg: String,
109}
110
111// --- MMP (used in Wave 9) ---
112
113/// Market Maker Protection (MMP) configuration response.
114///
115/// Limit fields use `i64` to accept the server sentinel `-1` meaning "no limit set".
116#[derive(Debug, Deserialize)]
117pub struct MmpResponse {
118    pub symbol: String,
119    #[serde(rename = "windowTimeInMilliseconds")]
120    pub window_time_ms: u64,
121    #[serde(rename = "frozenTimeInMilliseconds")]
122    pub frozen_time_ms: u64,
123    #[serde(rename = "qtyLimit", default)]
124    pub qty_limit: Option<i64>,
125    #[serde(rename = "valueLimit", default)]
126    pub value_limit: Option<i64>,
127    #[serde(rename = "deltaLimit", default)]
128    pub delta_limit: Option<i64>,
129}
130
131/// Parameters for updating MMP configuration (`POST /fapi/v3/mmp`).
132#[derive(Debug)]
133pub struct MmpUpdateParams {
134    pub symbol: String,
135    /// Time window in milliseconds for calculating limits.
136    pub window_time_ms: u64,
137    /// Duration in milliseconds during which MMP orders are prohibited after a limit is triggered.
138    pub frozen_time_ms: u64,
139    /// Maximum cumulative filled quantity within the window (optional).
140    pub qty_limit: Option<u64>,
141    /// Maximum cumulative notional value within the window (optional).
142    pub value_limit: Option<u64>,
143    /// Maximum cumulative net position change within the window (optional).
144    pub delta_limit: Option<u64>,
145}
146
147// --- Wallet Transfer (used in Wave 9) ---
148
149/// Parameters for a wallet asset transfer.
150#[derive(Debug, Serialize)]
151pub struct WalletTransferParams {
152    pub asset: String,
153    pub amount: String,
154    #[serde(rename = "type")]
155    pub transfer_type: u32,
156}
157
158/// Response from a wallet asset transfer.
159#[derive(Debug, Deserialize)]
160pub struct WalletTransferResponse {
161    #[serde(rename = "tranId")]
162    pub tran_id: i64,
163    #[serde(default)]
164    pub status: String,
165}
166
167// --- ADL Quantile (used in Wave 9) ---
168
169/// ADL (Auto-Deleveraging) quantile information for a symbol.
170#[derive(Debug, Deserialize)]
171pub struct AdlQuantileResponse {
172    pub symbol: String,
173    #[serde(rename = "adlQuantile")]
174    pub adl_quantile: serde_json::Value,
175}
176
177// --- Commission Rate (used in Wave 9) ---
178
179/// Commission rates for a trading symbol.
180#[derive(Debug, Deserialize)]
181pub struct CommissionRateResponse {
182    pub symbol: String,
183    #[serde(rename = "makerCommissionRate")]
184    pub maker_commission_rate: String,
185    #[serde(rename = "takerCommissionRate")]
186    pub taker_commission_rate: String,
187}
188
189// --- Multi-Assets Mode (used in Wave 9) ---
190
191/// Multi-assets margin mode setting.
192#[derive(Debug, Deserialize)]
193pub struct MultiAssetsModeResponse {
194    #[serde(rename = "multiAssetsMargin")]
195    pub multi_assets_margin: bool,
196}
197
198// --- Full Account Info (GET /fapi/v3/accountWithJoinMargin) ---
199
200/// Full account information response.
201#[derive(Debug, Deserialize)]
202pub struct AccountInfoResponse {
203    #[serde(rename = "feeTier")]
204    pub fee_tier: u32,
205    #[serde(rename = "canTrade")]
206    pub can_trade: bool,
207    #[serde(rename = "canDeposit")]
208    pub can_deposit: bool,
209    #[serde(rename = "canWithdraw")]
210    pub can_withdraw: bool,
211    #[serde(rename = "updateTime")]
212    pub update_time: u64,
213    #[serde(rename = "totalInitialMargin")]
214    pub total_initial_margin: String,
215    #[serde(rename = "totalMaintMargin")]
216    pub total_maint_margin: String,
217    #[serde(rename = "totalWalletBalance")]
218    pub total_wallet_balance: String,
219    #[serde(rename = "totalUnrealizedProfit")]
220    pub total_unrealized_profit: String,
221    #[serde(rename = "totalMarginBalance")]
222    pub total_margin_balance: String,
223    #[serde(rename = "totalPositionInitialMargin")]
224    pub total_position_initial_margin: String,
225    #[serde(rename = "totalOpenOrderInitialMargin")]
226    pub total_open_order_initial_margin: String,
227    #[serde(rename = "totalCrossWalletBalance")]
228    pub total_cross_wallet_balance: String,
229    #[serde(rename = "totalCrossUnPnl")]
230    pub total_cross_unpnl: String,
231    #[serde(rename = "availableBalance")]
232    pub available_balance: String,
233    #[serde(rename = "maxWithdrawAmount")]
234    pub max_withdraw_amount: String,
235    pub assets: Vec<AccountAsset>,
236    pub positions: Vec<AccountPosition>,
237}
238
239/// Per-asset details within `AccountInfoResponse`.
240#[derive(Debug, Deserialize)]
241pub struct AccountAsset {
242    pub asset: String,
243    #[serde(rename = "walletBalance")]
244    pub wallet_balance: String,
245    #[serde(rename = "unrealizedProfit")]
246    pub unrealized_profit: String,
247    #[serde(rename = "marginBalance")]
248    pub margin_balance: String,
249    #[serde(rename = "maintMargin")]
250    pub maint_margin: String,
251    #[serde(rename = "initialMargin")]
252    pub initial_margin: String,
253    #[serde(rename = "positionInitialMargin")]
254    pub position_initial_margin: String,
255    #[serde(rename = "openOrderInitialMargin")]
256    pub open_order_initial_margin: String,
257    #[serde(rename = "crossWalletBalance")]
258    pub cross_wallet_balance: String,
259    #[serde(rename = "crossUnPnl")]
260    pub cross_unpnl: String,
261    #[serde(rename = "availableBalance")]
262    pub available_balance: String,
263    #[serde(rename = "maxWithdrawAmount")]
264    pub max_withdraw_amount: String,
265    #[serde(rename = "marginAvailable", default)]
266    pub margin_available: bool,
267    #[serde(rename = "updateTime")]
268    pub update_time: u64,
269}
270
271/// Per-position details within `AccountInfoResponse`.
272#[derive(Debug, Deserialize)]
273pub struct AccountPosition {
274    pub symbol: String,
275    #[serde(rename = "initialMargin")]
276    pub initial_margin: String,
277    #[serde(rename = "maintMargin")]
278    pub maint_margin: String,
279    #[serde(rename = "unrealizedProfit")]
280    pub unrealized_profit: String,
281    #[serde(rename = "positionInitialMargin")]
282    pub position_initial_margin: String,
283    #[serde(rename = "openOrderInitialMargin")]
284    pub open_order_initial_margin: String,
285    pub leverage: String,
286    pub isolated: bool,
287    #[serde(rename = "entryPrice")]
288    pub entry_price: String,
289    #[serde(rename = "maxNotional")]
290    pub max_notional: String,
291    #[serde(rename = "positionSide")]
292    pub position_side: String,
293    #[serde(rename = "positionAmt")]
294    pub position_amt: String,
295    #[serde(rename = "updateTime")]
296    pub update_time: u64,
297}
298
299// --- Position Margin History (GET /fapi/v3/positionMargin/history) ---
300
301/// A single record from position margin change history.
302#[derive(Debug, Deserialize)]
303pub struct PositionMarginHistoryRecord {
304    pub amount: String,
305    pub asset: String,
306    pub symbol: String,
307    pub time: u64,
308    #[serde(rename = "type")]
309    pub margin_type: u8,
310    #[serde(rename = "positionSide")]
311    pub position_side: String,
312}