Skip to main content

rust_okx/api/account/
api.rs

1use crate::client::OkxClient;
2use crate::error::Error;
3use crate::model::InstType;
4use crate::transport::Transport;
5
6use super::endpoints::*;
7use super::internal::*;
8use super::requests::*;
9use super::responses::*;
10
11/// Accessor for the authenticated account endpoints.
12///
13/// Obtain one via [`OkxClient::account`](crate::OkxClient::account). All methods
14/// require credentials; calling them without credentials returns
15/// [`Error::Configuration`].
16pub struct Account<'a, T> {
17    client: &'a OkxClient<T>,
18}
19
20impl<'a, T: Transport> Account<'a, T> {
21    pub(crate) fn new(client: &'a OkxClient<T>) -> Self {
22        Self { client }
23    }
24
25    /// Retrieve the trading-account balance.
26    ///
27    /// `GET /api/v5/account/balance`. Authenticated. Pass `ccy` to filter to one
28    /// or more comma-separated currencies (e.g. `Some("BTC,USDT")`). The result
29    /// is a single [`AccountBalance`].
30    ///
31    /// # Errors
32    ///
33    /// Returns [`Error::Configuration`] if no credentials are set,
34    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
35    pub async fn get_balance(&self, ccy: Option<&str>) -> Result<Vec<AccountBalance>, Error> {
36        let query = BalanceQuery { ccy };
37        self.client.get(BALANCE, &query, true).await
38    }
39
40    /// Retrieve open positions.
41    ///
42    /// `GET /api/v5/account/positions`. Authenticated. Both filters are
43    /// optional; omit them to return all positions.
44    ///
45    /// # Errors
46    ///
47    /// Returns [`Error::Configuration`] if no credentials are set,
48    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
49    pub async fn get_positions(
50        &self,
51        inst_type: Option<InstType>,
52        inst_id: Option<&str>,
53    ) -> Result<Vec<Position>, Error> {
54        let query = PositionsQuery {
55            inst_type: inst_type.as_ref(),
56            inst_id,
57        };
58        self.client.get(POSITIONS, &query, true).await
59    }
60
61    /// Retrieve account position risk.
62    ///
63    /// `GET /api/v5/account/account-position-risk`. Authenticated.
64    ///
65    /// # Errors
66    ///
67    /// Returns [`Error::Configuration`] if no credentials are set,
68    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
69    pub async fn get_position_risk(
70        &self,
71        inst_type: Option<InstType>,
72    ) -> Result<Vec<PositionRisk>, Error> {
73        let query = PositionRiskQuery {
74            inst_type: inst_type.as_ref(),
75        };
76        self.client.get(POSITION_RISK, &query, true).await
77    }
78
79    /// Retrieve account configuration.
80    ///
81    /// `GET /api/v5/account/config`. Authenticated.
82    ///
83    /// # Errors
84    ///
85    /// Returns [`Error::Configuration`] if no credentials are set,
86    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
87    pub async fn get_account_config(&self) -> Result<Vec<AccountConfig>, Error> {
88        self.client.get(ACCOUNT_CONFIG, &NoQuery, true).await
89    }
90
91    /// Retrieve recent account bills.
92    ///
93    /// `GET /api/v5/account/bills`. Authenticated.
94    ///
95    /// # Errors
96    ///
97    /// Returns [`Error::InvalidRequest`] on validation failure,
98    /// [`Error::Configuration`] if no credentials are set,
99    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
100    pub async fn get_account_bills(
101        &self,
102        request: &BillsRequest,
103    ) -> Result<Vec<AccountBill>, Error> {
104        self.client.get(BILLS, request, true).await
105    }
106
107    /// Retrieve archived account bills.
108    ///
109    /// `GET /api/v5/account/bills-archive`. Authenticated.
110    ///
111    /// # Errors
112    ///
113    /// Returns [`Error::InvalidRequest`] on validation failure,
114    /// [`Error::Configuration`] if no credentials are set,
115    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
116    pub async fn get_account_bills_archive(
117        &self,
118        request: &BillsArchiveRequest,
119    ) -> Result<Vec<AccountBill>, Error> {
120        self.client.get(BILLS_ARCHIVE, request, true).await
121    }
122
123    /// Set the account position mode.
124    ///
125    /// `POST /api/v5/account/set-position-mode`. Authenticated.
126    ///
127    /// # Errors
128    ///
129    /// Returns [`Error::Configuration`] if no credentials are set,
130    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
131    pub async fn set_position_mode(
132        &self,
133        pos_mode: &str,
134    ) -> Result<Vec<SetPositionModeResult>, Error> {
135        let body = SetPositionModeBody { pos_mode };
136        self.client.post(SET_POSITION_MODE, &body, true).await
137    }
138
139    /// Set leverage for an instrument or currency.
140    ///
141    /// `POST /api/v5/account/set-leverage`. Authenticated.
142    ///
143    /// # Errors
144    ///
145    /// Returns [`Error::InvalidRequest`] on validation failure,
146    /// [`Error::Configuration`] if no credentials are set,
147    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
148    pub async fn set_leverage(
149        &self,
150        request: &SetLeverageRequest,
151    ) -> Result<Vec<LeverageInfo>, Error> {
152        self.client.post(SET_LEVERAGE, request, true).await
153    }
154
155    /// Retrieve leverage settings.
156    ///
157    /// `GET /api/v5/account/leverage-info`. Authenticated.
158    ///
159    /// # Errors
160    ///
161    /// Returns [`Error::InvalidRequest`] on validation failure,
162    /// [`Error::Configuration`] if no credentials are set,
163    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
164    pub async fn get_leverage(
165        &self,
166        request: &LeverageRequest,
167    ) -> Result<Vec<LeverageInfo>, Error> {
168        self.client.get(GET_LEVERAGE, request, true).await
169    }
170
171    /// Retrieve maximum tradable size for an instrument.
172    ///
173    /// `GET /api/v5/account/max-size`. Authenticated.
174    ///
175    /// # Errors
176    ///
177    /// Returns [`Error::InvalidRequest`] on validation failure,
178    /// [`Error::Configuration`] if no credentials are set,
179    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
180    pub async fn get_max_order_size(
181        &self,
182        request: &MaxOrderSizeRequest,
183    ) -> Result<Vec<MaxOrderSize>, Error> {
184        self.client.get(MAX_ORDER_SIZE, request, true).await
185    }
186
187    /// Retrieve maximum available size for an instrument.
188    ///
189    /// `GET /api/v5/account/max-avail-size`. Authenticated.
190    ///
191    /// # Errors
192    ///
193    /// Returns [`Error::InvalidRequest`] on validation failure,
194    /// [`Error::Configuration`] if no credentials are set,
195    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
196    pub async fn get_max_avail_size(
197        &self,
198        request: &MaxAvailableSizeRequest,
199    ) -> Result<Vec<MaxAvailableSize>, Error> {
200        self.client.get(MAX_AVAILABLE_SIZE, request, true).await
201    }
202
203    /// Increase or decrease margin for a position.
204    ///
205    /// `POST /api/v5/account/position/margin-balance`. Authenticated.
206    ///
207    /// # Errors
208    ///
209    /// Returns [`Error::InvalidRequest`] on validation failure,
210    /// [`Error::Configuration`] if no credentials are set,
211    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
212    pub async fn adjust_margin(
213        &self,
214        request: &AdjustMarginRequest,
215    ) -> Result<Vec<AdjustMarginResult>, Error> {
216        self.client.post(ADJUST_MARGIN, request, true).await
217    }
218
219    /// Retrieve trade fee rates.
220    ///
221    /// `GET /api/v5/account/trade-fee`. Authenticated.
222    ///
223    /// # Errors
224    ///
225    /// Returns [`Error::InvalidRequest`] on validation failure,
226    /// [`Error::Configuration`] if no credentials are set,
227    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
228    pub async fn get_fee_rates(&self, request: &FeeRatesRequest) -> Result<Vec<FeeRate>, Error> {
229        self.client.get(FEE_RATES, request, true).await
230    }
231
232    /// Retrieve account-available instruments.
233    ///
234    /// `GET /api/v5/account/instruments`. Authenticated.
235    ///
236    /// # Errors
237    ///
238    /// Returns [`Error::InvalidRequest`] on validation failure,
239    /// [`Error::Configuration`] if no credentials are set,
240    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
241    pub async fn get_account_instruments(
242        &self,
243        request: &AccountInstrumentsRequest,
244    ) -> Result<Vec<AccountInstrument>, Error> {
245        self.client.get(ACCOUNT_INSTRUMENTS, request, true).await
246    }
247
248    /// Retrieve the maximum loan amount.
249    ///
250    /// `GET /api/v5/account/max-loan`. Authenticated.
251    ///
252    /// # Errors
253    ///
254    /// Returns [`Error::InvalidRequest`] on validation failure,
255    /// [`Error::Configuration`] if no credentials are set,
256    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
257    pub async fn get_max_loan(&self, request: &MaxLoanRequest) -> Result<Vec<MaxLoan>, Error> {
258        self.client.get(MAX_LOAN, request, true).await
259    }
260
261    /// Retrieve interest-accrued records.
262    ///
263    /// `GET /api/v5/account/interest-accrued`. Authenticated.
264    ///
265    /// # Errors
266    ///
267    /// Returns [`Error::InvalidRequest`] on validation failure,
268    /// [`Error::Configuration`] if no credentials are set,
269    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
270    pub async fn get_interest_accrued(
271        &self,
272        request: &InterestAccruedRequest,
273    ) -> Result<Vec<InterestAccrued>, Error> {
274        self.client.get(INTEREST_ACCRUED, request, true).await
275    }
276
277    /// Retrieve interest rates.
278    ///
279    /// `GET /api/v5/account/interest-rate`. Authenticated.
280    ///
281    /// # Errors
282    ///
283    /// Returns [`Error::Configuration`] if no credentials are set,
284    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
285    pub async fn get_interest_rate(&self, ccy: Option<&str>) -> Result<Vec<InterestRate>, Error> {
286        let query = BalanceQuery { ccy };
287        self.client.get(INTEREST_RATE, &query, true).await
288    }
289
290    /// Set the greeks display type.
291    ///
292    /// `POST /api/v5/account/set-greeks`. Authenticated.
293    ///
294    /// # Errors
295    ///
296    /// Returns [`Error::Configuration`] if no credentials are set,
297    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
298    pub async fn set_greeks(&self, greeks_type: &str) -> Result<Vec<SetGreeksResult>, Error> {
299        let body = SetGreeksBody { greeks_type };
300        self.client.post(SET_GREEKS, &body, true).await
301    }
302
303    /// Set isolated margin transfer mode.
304    ///
305    /// `POST /api/v5/account/set-isolated-mode`. Authenticated.
306    ///
307    /// # Errors
308    ///
309    /// Returns [`Error::Configuration`] if no credentials are set,
310    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
311    pub async fn set_isolated_mode(
312        &self,
313        iso_mode: &str,
314        mode_type: &str,
315    ) -> Result<Vec<SetIsolatedModeResult>, Error> {
316        let body = SetIsolatedModeBody {
317            iso_mode,
318            mode_type,
319        };
320        self.client.post(SET_ISOLATED_MODE, &body, true).await
321    }
322
323    /// Retrieve maximum withdrawal amounts.
324    ///
325    /// `GET /api/v5/account/max-withdrawal`. Authenticated.
326    ///
327    /// # Errors
328    ///
329    /// Returns [`Error::Configuration`] if no credentials are set,
330    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
331    pub async fn get_max_withdrawal(&self, ccy: Option<&str>) -> Result<Vec<MaxWithdrawal>, Error> {
332        let query = BalanceQuery { ccy };
333        self.client.get(MAX_WITHDRAWAL, &query, true).await
334    }
335
336    /// Retrieve borrowing rate and limit information.
337    ///
338    /// `GET /api/v5/account/interest-limits`. Authenticated.
339    ///
340    /// # Errors
341    ///
342    /// Returns [`Error::InvalidRequest`] on validation failure,
343    /// [`Error::Configuration`] if no credentials are set,
344    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
345    pub async fn get_interest_limits(
346        &self,
347        request: &InterestLimitsRequest,
348    ) -> Result<Vec<InterestLimit>, Error> {
349        self.client.get(INTEREST_LIMITS, request, true).await
350    }
351
352    /// Calculate simulated margin information.
353    ///
354    /// `POST /api/v5/account/simulated_margin`. Authenticated. This is separate
355    /// from [`OkxClientBuilder::demo_trading`](crate::OkxClientBuilder::demo_trading),
356    /// which only toggles the OKX simulated-trading header.
357    ///
358    /// # Errors
359    ///
360    /// Returns [`Error::InvalidRequest`] on validation failure,
361    /// [`Error::Configuration`] if no credentials are set,
362    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
363    pub async fn get_simulated_margin(
364        &self,
365        request: &SimulatedMarginRequest,
366    ) -> Result<Vec<SimulatedMargin>, Error> {
367        self.client.post(SIMULATED_MARGIN, request, true).await
368    }
369
370    /// Retrieve greeks.
371    ///
372    /// `GET /api/v5/account/greeks`. Authenticated.
373    ///
374    /// # Errors
375    ///
376    /// Returns [`Error::Configuration`] if no credentials are set,
377    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
378    pub async fn get_greeks(&self, ccy: Option<&str>) -> Result<Vec<Greek>, Error> {
379        let query = BalanceQuery { ccy };
380        self.client.get(GREEKS, &query, true).await
381    }
382
383    /// Retrieve position history.
384    ///
385    /// `GET /api/v5/account/positions-history`. Authenticated.
386    ///
387    /// # Errors
388    ///
389    /// Returns [`Error::InvalidRequest`] on validation failure,
390    /// [`Error::Configuration`] if no credentials are set,
391    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
392    pub async fn get_positions_history(
393        &self,
394        request: &PositionsHistoryRequest,
395    ) -> Result<Vec<PositionHistory>, Error> {
396        self.client.get(POSITIONS_HISTORY, request, true).await
397    }
398
399    /// Retrieve account position tiers.
400    ///
401    /// `GET /api/v5/account/position-tiers`. Authenticated.
402    ///
403    /// # Errors
404    ///
405    /// Returns [`Error::InvalidRequest`] on validation failure,
406    /// [`Error::Configuration`] if no credentials are set,
407    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
408    pub async fn get_account_position_tiers(
409        &self,
410        request: &AccountPositionTiersRequest,
411    ) -> Result<Vec<AccountPositionTier>, Error> {
412        self.client.get(ACCOUNT_POSITION_TIERS, request, true).await
413    }
414
415    /// Retrieve the account risk state.
416    ///
417    /// `GET /api/v5/account/risk-state`. Authenticated.
418    ///
419    /// # Errors
420    ///
421    /// Returns [`Error::Configuration`] if no credentials are set,
422    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
423    pub async fn get_risk_state(&self) -> Result<Vec<RiskState>, Error> {
424        self.client.get(RISK_STATE, &NoQuery, true).await
425    }
426
427    /// Set account auto-loan mode.
428    ///
429    /// `POST /api/v5/account/set-auto-loan`. Authenticated.
430    ///
431    /// # Errors
432    ///
433    /// Returns [`Error::Configuration`] if no credentials are set,
434    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
435    pub async fn set_auto_loan(&self, auto_loan: bool) -> Result<Vec<SetAutoLoanResult>, Error> {
436        let body = SetAutoLoanBody { auto_loan };
437        self.client.post(SET_AUTO_LOAN, &body, true).await
438    }
439
440    /// Set the account level.
441    ///
442    /// `POST /api/v5/account/set-account-level`. Authenticated.
443    ///
444    /// # Errors
445    ///
446    /// Returns [`Error::Configuration`] if no credentials are set,
447    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
448    pub async fn set_account_level(
449        &self,
450        acct_lv: &str,
451    ) -> Result<Vec<SetAccountLevelResult>, Error> {
452        let body = SetAccountLevelBody { acct_lv };
453        self.client.post(SET_ACCOUNT_LEVEL, &body, true).await
454    }
455
456    /// Activate option trading.
457    ///
458    /// `POST /api/v5/account/activate-option`. Authenticated.
459    ///
460    /// # Errors
461    ///
462    /// Returns [`Error::Configuration`] if no credentials are set,
463    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
464    pub async fn activate_option(&self) -> Result<Vec<ActivateOptionResult>, Error> {
465        self.client.post(ACTIVATE_OPTION, &EmptyBody {}, true).await
466    }
467
468    /// Build simulated positions and equity.
469    ///
470    /// `POST /api/v5/account/position-builder`. Authenticated.
471    ///
472    /// # Errors
473    ///
474    /// Returns [`Error::InvalidRequest`] on validation failure,
475    /// [`Error::Configuration`] if no credentials are set,
476    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
477    pub async fn position_builder(
478        &self,
479        request: &PositionBuilderRequest,
480    ) -> Result<Vec<PositionBuilderResult>, Error> {
481        self.client.post(POSITION_BUILDER, request, true).await
482    }
483
484    /// Manually borrow or repay spot liabilities.
485    ///
486    /// `POST /api/v5/account/spot-manual-borrow-repay`. Authenticated.
487    ///
488    /// # Errors
489    ///
490    /// Returns [`Error::InvalidRequest`] on validation failure,
491    /// [`Error::Configuration`] if no credentials are set,
492    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
493    pub async fn spot_manual_borrow_repay(
494        &self,
495        request: &SpotManualBorrowRepayRequest,
496    ) -> Result<Vec<SpotBorrowRepayResult>, Error> {
497        self.client
498            .post(SPOT_MANUAL_BORROW_REPAY, request, true)
499            .await
500    }
501
502    /// Set automatic repayment for spot borrow/repay.
503    ///
504    /// `POST /api/v5/account/set-auto-repay`. Authenticated.
505    ///
506    /// # Errors
507    ///
508    /// Returns [`Error::InvalidRequest`] on validation failure,
509    /// [`Error::Configuration`] if no credentials are set,
510    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
511    pub async fn set_auto_repay(
512        &self,
513        request: &SetAutoRepayRequest,
514    ) -> Result<Vec<SetAutoRepayResult>, Error> {
515        self.client.post(SET_AUTO_REPAY, request, true).await
516    }
517
518    /// Retrieve spot borrow/repay history.
519    ///
520    /// `GET /api/v5/account/spot-borrow-repay-history`. Authenticated.
521    ///
522    /// # Errors
523    ///
524    /// Returns [`Error::InvalidRequest`] on validation failure,
525    /// [`Error::Configuration`] if no credentials are set,
526    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
527    pub async fn get_spot_borrow_repay_history(
528        &self,
529        request: &SpotBorrowRepayHistoryRequest,
530    ) -> Result<Vec<SpotBorrowRepayHistory>, Error> {
531        self.client
532            .get(SPOT_BORROW_REPAY_HISTORY, request, true)
533            .await
534    }
535
536    /// Set automatic earn for the account.
537    ///
538    /// `POST /api/v5/account/set-auto-earn`. Authenticated.
539    ///
540    /// # Errors
541    ///
542    /// Returns [`Error::InvalidRequest`] on validation failure,
543    /// [`Error::Configuration`] if no credentials are set,
544    /// [`Error::Api`] on a non-zero OKX code, or transport/decode errors.
545    pub async fn set_auto_earn(
546        &self,
547        request: &SetAutoEarnRequest,
548    ) -> Result<Vec<SetAutoEarnResult>, Error> {
549        self.client.post(SET_AUTO_EARN, request, true).await
550    }
551}