ccxt_exchanges/okx/rest/
account.rs1use super::super::{Okx, parser};
4use ccxt_core::{
5 Error, ParseError, Result,
6 types::{Balance, Trade},
7};
8use std::collections::HashMap;
9use tracing::warn;
10
11impl Okx {
12 pub async fn fetch_balance(&self) -> Result<Balance> {
22 let path = Self::build_api_path("/account/balance");
23 let response = self.signed_request(&path).execute().await?;
24
25 let data = response
26 .get("data")
27 .ok_or_else(|| Error::from(ParseError::missing_field("data")))?;
28
29 let balances = data.as_array().ok_or_else(|| {
30 Error::from(ParseError::invalid_format(
31 "data",
32 "Expected array of balances",
33 ))
34 })?;
35
36 if balances.is_empty() {
37 return Ok(Balance {
38 balances: HashMap::new(),
39 info: HashMap::new(),
40 });
41 }
42
43 parser::parse_balance(&balances[0])
44 }
45
46 pub async fn fetch_my_trades(
58 &self,
59 symbol: &str,
60 since: Option<i64>,
61 limit: Option<u32>,
62 ) -> Result<Vec<Trade>> {
63 let market = self.base().market(symbol).await?;
64
65 let path = Self::build_api_path("/trade/fills");
66
67 let actual_limit = limit.map_or(100, |l| l.min(100));
68
69 let mut builder = self
70 .signed_request(&path)
71 .param("instId", &market.id)
72 .param("instType", self.get_inst_type())
73 .param("limit", actual_limit);
74
75 if let Some(start_time) = since {
76 builder = builder.param("begin", start_time);
77 }
78
79 let response = builder.execute().await?;
80
81 let data = response
82 .get("data")
83 .ok_or_else(|| Error::from(ParseError::missing_field("data")))?;
84
85 let trades_array = data.as_array().ok_or_else(|| {
86 Error::from(ParseError::invalid_format(
87 "data",
88 "Expected array of trades",
89 ))
90 })?;
91
92 let mut trades = Vec::new();
93 for trade_data in trades_array {
94 match parser::parse_trade(trade_data, Some(&market)) {
95 Ok(trade) => trades.push(trade),
96 Err(e) => {
97 warn!(error = %e, "Failed to parse my trade");
98 }
99 }
100 }
101
102 Ok(trades)
103 }
104}