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