Skip to main content

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}