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 [`Error::Configuration`] without credentials, [`Error::Api`] 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(&self, request: &OrderListRequest) -> Result<Vec<Order>, Error> {
144 self.client.get(ORDERS_PENDING, request, true).await
145 }
146
147 /// Retrieve order history for the recent window.
148 ///
149 /// `GET /api/v5/trade/orders-history`. Authenticated.
150 ///
151 /// # Errors
152 ///
153 /// See [`place_order`](Self::place_order).
154 pub async fn get_orders_history(
155 &self,
156 request: &OrderHistoryRequest,
157 ) -> Result<Vec<Order>, Error> {
158 self.client.get(ORDERS_HISTORY, request, true).await
159 }
160
161 /// Retrieve archived order history.
162 ///
163 /// `GET /api/v5/trade/orders-history-archive`. Authenticated.
164 ///
165 /// # Errors
166 ///
167 /// See [`place_order`](Self::place_order).
168 pub async fn get_orders_history_archive(
169 &self,
170 request: &OrderHistoryRequest,
171 ) -> Result<Vec<Order>, Error> {
172 self.client.get(ORDERS_HISTORY_ARCHIVE, request, true).await
173 }
174
175 /// Retrieve recent fills.
176 ///
177 /// `GET /api/v5/trade/fills`. Authenticated.
178 ///
179 /// # Errors
180 ///
181 /// See [`place_order`](Self::place_order).
182 pub async fn get_fills(&self, request: &FillsRequest) -> Result<Vec<Fill>, Error> {
183 self.client.get(FILLS, request, true).await
184 }
185
186 /// Retrieve historical fills.
187 ///
188 /// `GET /api/v5/trade/fills-history`. Authenticated.
189 ///
190 /// # Errors
191 ///
192 /// See [`place_order`](Self::place_order).
193 pub async fn get_fills_history(
194 &self,
195 request: &FillHistoryRequest,
196 ) -> Result<Vec<FillHistory>, Error> {
197 self.client.get(FILLS_HISTORY, request, true).await
198 }
199
200 /// Place an algo order.
201 ///
202 /// `POST /api/v5/trade/order-algo`. Authenticated.
203 ///
204 /// # Errors
205 ///
206 /// See [`place_order`](Self::place_order).
207 pub async fn place_algo_order(
208 &self,
209 request: &AlgoOrderRequest,
210 ) -> Result<Vec<AlgoOrderResult>, Error> {
211 self.client.post(ORDER_ALGO, request, true).await
212 }
213
214 /// Cancel algo orders.
215 ///
216 /// `POST /api/v5/trade/cancel-algos`. Authenticated.
217 ///
218 /// # Errors
219 ///
220 /// See [`place_order`](Self::place_order).
221 pub async fn cancel_algo_orders(
222 &self,
223 requests: &[CancelAlgoOrderRequest],
224 ) -> Result<Vec<AlgoOrderResult>, Error> {
225 self.client.post(CANCEL_ALGOS, &requests, true).await
226 }
227
228 /// Amend an algo order.
229 ///
230 /// `POST /api/v5/trade/amend-algos`. Authenticated.
231 ///
232 /// # Errors
233 ///
234 /// See [`place_order`](Self::place_order).
235 pub async fn amend_algo_order(
236 &self,
237 request: &AmendAlgoOrderRequest,
238 ) -> Result<Vec<AlgoOrderResult>, Error> {
239 self.client.post(AMEND_ALGOS, request, true).await
240 }
241
242 /// Retrieve pending algo orders.
243 ///
244 /// `GET /api/v5/trade/orders-algo-pending`. Authenticated.
245 ///
246 /// # Errors
247 ///
248 /// See [`place_order`](Self::place_order).
249 pub async fn get_algo_order_list(
250 &self,
251 request: &AlgoOrderListRequest,
252 ) -> Result<Vec<AlgoOrder>, Error> {
253 self.client.get(ORDERS_ALGO_PENDING, request, true).await
254 }
255
256 /// Retrieve algo order history.
257 ///
258 /// `GET /api/v5/trade/orders-algo-history`. Authenticated.
259 ///
260 /// # Errors
261 ///
262 /// See [`place_order`](Self::place_order).
263 pub async fn get_algo_orders_history(
264 &self,
265 request: &AlgoOrderHistoryRequest,
266 ) -> Result<Vec<AlgoOrder>, Error> {
267 self.client.get(ORDERS_ALGO_HISTORY, request, true).await
268 }
269
270 /// Retrieve details for an algo order.
271 ///
272 /// `GET /api/v5/trade/order-algo`. Authenticated.
273 ///
274 /// # Errors
275 ///
276 /// See [`place_order`](Self::place_order).
277 pub async fn get_algo_order_details(
278 &self,
279 request: &AlgoOrderDetailsRequest,
280 ) -> Result<Vec<AlgoOrder>, Error> {
281 self.client.get(ORDER_ALGO_DETAILS, request, true).await
282 }
283
284 /// Retrieve the easy-convert currency list.
285 ///
286 /// `GET /api/v5/trade/easy-convert-currency-list`. Authenticated.
287 ///
288 /// # Errors
289 ///
290 /// See [`place_order`](Self::place_order).
291 pub async fn get_easy_convert_currency_list(&self) -> Result<Vec<EasyConvertCurrency>, Error> {
292 self.client
293 .get(EASY_CONVERT_CURRENCY_LIST, &EmptyRequest {}, true)
294 .await
295 }
296
297 /// Execute an easy-convert request.
298 ///
299 /// `POST /api/v5/trade/easy-convert`. Authenticated.
300 ///
301 /// # Errors
302 ///
303 /// See [`place_order`](Self::place_order).
304 pub async fn easy_convert(
305 &self,
306 request: &EasyConvertRequest,
307 ) -> Result<Vec<EasyConvertResult>, Error> {
308 self.client.post(EASY_CONVERT, request, true).await
309 }
310
311 /// Retrieve easy-convert history.
312 ///
313 /// `GET /api/v5/trade/easy-convert-history`. Authenticated.
314 ///
315 /// # Errors
316 ///
317 /// See [`place_order`](Self::place_order).
318 pub async fn get_easy_convert_history(
319 &self,
320 request: &EasyConvertHistoryRequest,
321 ) -> Result<Vec<EasyConvertHistory>, Error> {
322 self.client.get(EASY_CONVERT_HISTORY, request, true).await
323 }
324
325 /// Retrieve one-click-repay currency pairs.
326 ///
327 /// `GET /api/v5/trade/one-click-repay-currency-list`. Authenticated.
328 ///
329 /// # Errors
330 ///
331 /// See [`place_order`](Self::place_order).
332 pub async fn get_one_click_repay_currency_list(
333 &self,
334 request: &OneClickRepayCurrencyListRequest,
335 ) -> Result<Vec<OneClickRepayCurrency>, Error> {
336 self.client
337 .get(ONE_CLICK_REPAY_CURRENCY_LIST, request, true)
338 .await
339 }
340
341 /// Execute one-click repay.
342 ///
343 /// `POST /api/v5/trade/one-click-repay`. Authenticated.
344 ///
345 /// # Errors
346 ///
347 /// See [`place_order`](Self::place_order).
348 pub async fn one_click_repay(
349 &self,
350 request: &OneClickRepayRequest,
351 ) -> Result<Vec<OneClickRepayResult>, Error> {
352 self.client.post(ONE_CLICK_REPAY, request, true).await
353 }
354
355 /// Retrieve one-click-repay history.
356 ///
357 /// `GET /api/v5/trade/one-click-repay-history`. Authenticated.
358 ///
359 /// # Errors
360 ///
361 /// See [`place_order`](Self::place_order).
362 pub async fn get_one_click_repay_history(
363 &self,
364 request: &OneClickRepayHistoryRequest,
365 ) -> Result<Vec<OneClickRepayHistory>, Error> {
366 self.client
367 .get(ONE_CLICK_REPAY_HISTORY, request, true)
368 .await
369 }
370
371 /// Retrieve one-click-repay v2 currency pairs.
372 ///
373 /// `GET /api/v5/trade/one-click-repay-currency-list-v2`. Authenticated.
374 ///
375 /// # Errors
376 ///
377 /// See [`place_order`](Self::place_order).
378 pub async fn get_one_click_repay_currency_list_v2(
379 &self,
380 request: &OneClickRepayCurrencyListRequest,
381 ) -> Result<Vec<OneClickRepayCurrency>, Error> {
382 self.client
383 .get(ONE_CLICK_REPAY_CURRENCY_LIST_V2, request, true)
384 .await
385 }
386
387 /// Execute one-click repay v2.
388 ///
389 /// `POST /api/v5/trade/one-click-repay-v2`. Authenticated.
390 ///
391 /// # Errors
392 ///
393 /// See [`place_order`](Self::place_order).
394 pub async fn one_click_repay_v2(
395 &self,
396 request: &OneClickRepayRequest,
397 ) -> Result<Vec<OneClickRepayResult>, Error> {
398 self.client.post(ONE_CLICK_REPAY_V2, request, true).await
399 }
400
401 /// Retrieve one-click-repay v2 history.
402 ///
403 /// `GET /api/v5/trade/one-click-repay-history-v2`. Authenticated.
404 ///
405 /// # Errors
406 ///
407 /// See [`place_order`](Self::place_order).
408 pub async fn get_one_click_repay_history_v2(
409 &self,
410 request: &OneClickRepayHistoryRequest,
411 ) -> Result<Vec<OneClickRepayHistory>, Error> {
412 self.client
413 .get(ONE_CLICK_REPAY_HISTORY_V2, request, true)
414 .await
415 }
416}