rust_okx/api/trade/api.rs
1use crate::client::OkxClient;
2use crate::error::Error;
3
4use crate::transport::Transport;
5
6use super::endpoints::*;
7use super::internal::*;
8use super::requests::*;
9use super::responses::*;
10
11/// Accessor for the authenticated trading endpoints.
12///
13/// Obtain one via [`OkxClient::trade`](crate::OkxClient::trade). All methods
14/// require credentials.
15pub struct Trade<'a, T> {
16 client: &'a OkxClient<T>,
17}
18
19impl<'a, T: Transport> Trade<'a, T> {
20 pub(crate) fn new(client: &'a OkxClient<T>) -> Self {
21 Self { client }
22 }
23
24 /// Place an order.
25 ///
26 /// `POST /api/v5/trade/order`. Authenticated. Build the request with
27 /// [`PlaceOrderRequest::new`] plus optional setters. The returned vector
28 /// contains one [`PlaceOrderResult`]; inspect its
29 /// [`s_code`](PlaceOrderResult::s_code) to confirm acceptance (`"0"`).
30 ///
31 /// # Errors
32 ///
33 /// Returns [`Error::Configuration`] without credentials, [`Error::Api`] on a
34 /// non-zero top-level OKX code, or transport/decode errors.
35 pub async fn place_order(
36 &self,
37 request: &PlaceOrderRequest,
38 ) -> Result<Vec<PlaceOrderResult>, Error> {
39 self.client.post(ORDER, request, true).await
40 }
41
42 /// Place multiple orders.
43 ///
44 /// `POST /api/v5/trade/batch-orders`. Authenticated.
45 ///
46 /// # Errors
47 ///
48 /// See [`place_order`](Self::place_order).
49 pub async fn place_multiple_orders(
50 &self,
51 requests: &[PlaceOrderRequest],
52 ) -> Result<Vec<PlaceOrderResult>, Error> {
53 self.client.post(BATCH_ORDERS, &requests, true).await
54 }
55
56 /// Cancel an order by its OKX order ID.
57 ///
58 /// `POST /api/v5/trade/cancel-order`. Authenticated.
59 ///
60 /// # Errors
61 ///
62 /// See [`place_order`](Self::place_order).
63 pub async fn cancel_order(
64 &self,
65 inst_id: &str,
66 ord_id: &str,
67 ) -> Result<Vec<CancelOrderResult>, Error> {
68 let body = CancelOrderBody { inst_id, ord_id };
69 self.client.post(CANCEL_ORDER, &body, true).await
70 }
71
72 /// Cancel multiple orders.
73 ///
74 /// `POST /api/v5/trade/cancel-batch-orders`. Authenticated.
75 ///
76 /// # Errors
77 ///
78 /// See [`place_order`](Self::place_order).
79 pub async fn cancel_multiple_orders(
80 &self,
81 requests: &[CancelOrderRequest],
82 ) -> Result<Vec<CancelOrderResult>, Error> {
83 self.client.post(CANCEL_BATCH_ORDERS, &requests, true).await
84 }
85
86 /// Amend an existing order.
87 ///
88 /// `POST /api/v5/trade/amend-order`. Authenticated.
89 ///
90 /// # Errors
91 ///
92 /// See [`place_order`](Self::place_order).
93 pub async fn amend_order(
94 &self,
95 request: &AmendOrderRequest,
96 ) -> Result<Vec<AmendOrderResult>, Error> {
97 self.client.post(AMEND_ORDER, request, true).await
98 }
99
100 /// Amend multiple existing orders.
101 ///
102 /// `POST /api/v5/trade/amend-batch-orders`. Authenticated.
103 ///
104 /// # Errors
105 ///
106 /// See [`place_order`](Self::place_order).
107 pub async fn amend_multiple_orders(
108 &self,
109 requests: &[AmendOrderRequest],
110 ) -> Result<Vec<AmendOrderResult>, Error> {
111 self.client.post(AMEND_BATCH_ORDERS, &requests, true).await
112 }
113
114 /// Close positions for an instrument.
115 ///
116 /// `POST /api/v5/trade/close-position`. Authenticated.
117 ///
118 /// # Errors
119 ///
120 /// See [`place_order`](Self::place_order).
121 pub async fn close_positions(
122 &self,
123 request: &ClosePositionRequest,
124 ) -> Result<Vec<ClosePositionResult>, Error> {
125 self.client.post(CLOSE_POSITION, request, true).await
126 }
127
128 /// Retrieve the details of a single order by its OKX order ID.
129 ///
130 /// `GET /api/v5/trade/order`. Authenticated.
131 ///
132 /// # Errors
133 ///
134 /// See [`place_order`](Self::place_order).
135 pub async fn get_order(&self, inst_id: &str, ord_id: &str) -> Result<Vec<Order>, Error> {
136 let query = GetOrderQuery { inst_id, ord_id };
137 self.client.get(ORDER, &query, true).await
138 }
139
140 /// Retrieve pending orders.
141 ///
142 /// `GET /api/v5/trade/orders-pending`. Authenticated.
143 ///
144 /// # Errors
145 ///
146 /// See [`place_order`](Self::place_order).
147 pub async fn get_order_list(&self, request: &OrderListRequest) -> Result<Vec<Order>, Error> {
148 self.client.get(ORDERS_PENDING, request, true).await
149 }
150
151 /// Retrieve order history for the recent window.
152 ///
153 /// `GET /api/v5/trade/orders-history`. Authenticated.
154 ///
155 /// # Errors
156 ///
157 /// See [`place_order`](Self::place_order).
158 pub async fn get_orders_history(
159 &self,
160 request: &OrderHistoryRequest,
161 ) -> Result<Vec<Order>, Error> {
162 self.client.get(ORDERS_HISTORY, request, true).await
163 }
164
165 /// Retrieve archived order history.
166 ///
167 /// `GET /api/v5/trade/orders-history-archive`. Authenticated.
168 ///
169 /// # Errors
170 ///
171 /// See [`place_order`](Self::place_order).
172 pub async fn get_orders_history_archive(
173 &self,
174 request: &OrderHistoryRequest,
175 ) -> Result<Vec<Order>, Error> {
176 self.client.get(ORDERS_HISTORY_ARCHIVE, request, true).await
177 }
178
179 /// Retrieve recent fills.
180 ///
181 /// `GET /api/v5/trade/fills`. Authenticated.
182 ///
183 /// # Errors
184 ///
185 /// See [`place_order`](Self::place_order).
186 pub async fn get_fills(&self, request: &FillsRequest) -> Result<Vec<Fill>, Error> {
187 self.client.get(FILLS, request, true).await
188 }
189
190 /// Retrieve historical fills.
191 ///
192 /// `GET /api/v5/trade/fills-history`. Authenticated.
193 ///
194 /// # Errors
195 ///
196 /// See [`place_order`](Self::place_order).
197 pub async fn get_fills_history(&self, request: &FillsRequest) -> Result<Vec<Fill>, Error> {
198 self.client.get(FILLS_HISTORY, request, true).await
199 }
200
201 /// Place an algo order.
202 ///
203 /// `POST /api/v5/trade/order-algo`. Authenticated.
204 ///
205 /// # Errors
206 ///
207 /// See [`place_order`](Self::place_order).
208 pub async fn place_algo_order(
209 &self,
210 request: &AlgoOrderRequest,
211 ) -> Result<Vec<AlgoOrderResult>, Error> {
212 self.client.post(ORDER_ALGO, request, true).await
213 }
214
215 /// Cancel algo orders.
216 ///
217 /// `POST /api/v5/trade/cancel-algos`. Authenticated.
218 ///
219 /// # Errors
220 ///
221 /// See [`place_order`](Self::place_order).
222 pub async fn cancel_algo_orders(
223 &self,
224 requests: &[CancelAlgoOrderRequest],
225 ) -> Result<Vec<AlgoOrderResult>, Error> {
226 self.client.post(CANCEL_ALGOS, &requests, true).await
227 }
228
229 /// Amend an algo order.
230 ///
231 /// `POST /api/v5/trade/amend-algos`. Authenticated.
232 ///
233 /// # Errors
234 ///
235 /// See [`place_order`](Self::place_order).
236 pub async fn amend_algo_order(
237 &self,
238 request: &AmendAlgoOrderRequest,
239 ) -> Result<Vec<AlgoOrderResult>, Error> {
240 self.client.post(AMEND_ALGOS, request, true).await
241 }
242
243 /// Retrieve pending algo orders.
244 ///
245 /// `GET /api/v5/trade/orders-algo-pending`. Authenticated.
246 ///
247 /// # Errors
248 ///
249 /// See [`place_order`](Self::place_order).
250 pub async fn get_algo_order_list(
251 &self,
252 request: &AlgoOrderListRequest,
253 ) -> Result<Vec<AlgoOrder>, Error> {
254 self.client.get(ORDERS_ALGO_PENDING, request, true).await
255 }
256
257 /// Retrieve algo order history.
258 ///
259 /// `GET /api/v5/trade/orders-algo-history`. Authenticated.
260 ///
261 /// # Errors
262 ///
263 /// See [`place_order`](Self::place_order).
264 pub async fn get_algo_orders_history(
265 &self,
266 request: &AlgoOrderHistoryRequest,
267 ) -> Result<Vec<AlgoOrder>, Error> {
268 self.client.get(ORDERS_ALGO_HISTORY, request, true).await
269 }
270
271 /// Retrieve details for an algo order.
272 ///
273 /// `GET /api/v5/trade/order-algo`. Authenticated.
274 ///
275 /// # Errors
276 ///
277 /// See [`place_order`](Self::place_order).
278 pub async fn get_algo_order_details(
279 &self,
280 request: &AlgoOrderDetailsRequest,
281 ) -> Result<Vec<AlgoOrder>, Error> {
282 self.client.get(ORDER_ALGO_DETAILS, request, true).await
283 }
284
285 /// Retrieve the easy-convert currency list.
286 ///
287 /// `GET /api/v5/trade/easy-convert-currency-list`. Authenticated.
288 ///
289 /// # Errors
290 ///
291 /// See [`place_order`](Self::place_order).
292 pub async fn get_easy_convert_currency_list(&self) -> Result<Vec<EasyConvertCurrency>, Error> {
293 self.client
294 .get(EASY_CONVERT_CURRENCY_LIST, &NoQuery, true)
295 .await
296 }
297
298 /// Execute an easy-convert request.
299 ///
300 /// `POST /api/v5/trade/easy-convert`. Authenticated.
301 ///
302 /// # Errors
303 ///
304 /// See [`place_order`](Self::place_order).
305 pub async fn easy_convert(
306 &self,
307 request: &EasyConvertRequest,
308 ) -> Result<Vec<EasyConvertResult>, Error> {
309 self.client.post(EASY_CONVERT, request, true).await
310 }
311
312 /// Retrieve easy-convert history.
313 ///
314 /// `GET /api/v5/trade/easy-convert-history`. Authenticated.
315 ///
316 /// # Errors
317 ///
318 /// See [`place_order`](Self::place_order).
319 pub async fn get_easy_convert_history(
320 &self,
321 request: &EasyConvertHistoryRequest,
322 ) -> Result<Vec<EasyConvertHistory>, Error> {
323 self.client.get(EASY_CONVERT_HISTORY, request, true).await
324 }
325
326 /// Retrieve one-click-repay currency pairs.
327 ///
328 /// `GET /api/v5/trade/one-click-repay-currency-list`. Authenticated.
329 ///
330 /// # Errors
331 ///
332 /// See [`place_order`](Self::place_order).
333 pub async fn get_one_click_repay_currency_list(
334 &self,
335 request: &OneClickRepayCurrencyListRequest,
336 ) -> Result<Vec<OneClickRepayCurrency>, Error> {
337 self.client
338 .get(ONE_CLICK_REPAY_CURRENCY_LIST, request, true)
339 .await
340 }
341
342 /// Execute one-click repay.
343 ///
344 /// `POST /api/v5/trade/one-click-repay`. Authenticated.
345 ///
346 /// # Errors
347 ///
348 /// See [`place_order`](Self::place_order).
349 pub async fn one_click_repay(
350 &self,
351 request: &OneClickRepayRequest,
352 ) -> Result<Vec<OneClickRepayResult>, Error> {
353 self.client.post(ONE_CLICK_REPAY, request, true).await
354 }
355
356 /// Retrieve one-click-repay history.
357 ///
358 /// `GET /api/v5/trade/one-click-repay-history`. Authenticated.
359 ///
360 /// # Errors
361 ///
362 /// See [`place_order`](Self::place_order).
363 pub async fn get_one_click_repay_history(
364 &self,
365 request: &OneClickRepayHistoryRequest,
366 ) -> Result<Vec<OneClickRepayHistory>, Error> {
367 self.client
368 .get(ONE_CLICK_REPAY_HISTORY, request, true)
369 .await
370 }
371
372 /// Retrieve one-click-repay v2 currency pairs.
373 ///
374 /// `GET /api/v5/trade/one-click-repay-currency-list-v2`. Authenticated.
375 ///
376 /// # Errors
377 ///
378 /// See [`place_order`](Self::place_order).
379 pub async fn get_one_click_repay_currency_list_v2(
380 &self,
381 request: &OneClickRepayCurrencyListRequest,
382 ) -> Result<Vec<OneClickRepayCurrency>, Error> {
383 self.client
384 .get(ONE_CLICK_REPAY_CURRENCY_LIST_V2, request, true)
385 .await
386 }
387
388 /// Execute one-click repay v2.
389 ///
390 /// `POST /api/v5/trade/one-click-repay-v2`. Authenticated.
391 ///
392 /// # Errors
393 ///
394 /// See [`place_order`](Self::place_order).
395 pub async fn one_click_repay_v2(
396 &self,
397 request: &OneClickRepayRequest,
398 ) -> Result<Vec<OneClickRepayResult>, Error> {
399 self.client.post(ONE_CLICK_REPAY_V2, request, true).await
400 }
401
402 /// Retrieve one-click-repay v2 history.
403 ///
404 /// `GET /api/v5/trade/one-click-repay-history-v2`. Authenticated.
405 ///
406 /// # Errors
407 ///
408 /// See [`place_order`](Self::place_order).
409 pub async fn get_one_click_repay_history_v2(
410 &self,
411 request: &OneClickRepayHistoryRequest,
412 ) -> Result<Vec<OneClickRepayHistory>, Error> {
413 self.client
414 .get(ONE_CLICK_REPAY_HISTORY_V2, request, true)
415 .await
416 }
417}