Skip to main content

rust_okx/api/trade/
api.rs

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