1use serde::Serialize;
2
3use crate::model::{
4 OrderSide, OrderState, OrderType, PositionSide, TradeMode, ValidateRequest, one_of,
5 optional_non_empty, optional_unsigned_integer_string, range_u64,
6};
7
8mod advanced;
9mod algo;
10
11pub use advanced::*;
12pub use algo::*;
13
14#[derive(Debug, Clone, Serialize)]
20pub struct PlaceOrderRequest {
21 #[serde(rename = "instId")]
22 inst_id: String,
23 #[serde(rename = "tdMode")]
24 td_mode: TradeMode,
25 side: OrderSide,
26 #[serde(rename = "ordType")]
27 ord_type: OrderType,
28 sz: String,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 ccy: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 tag: Option<String>,
33 #[serde(rename = "px", skip_serializing_if = "Option::is_none")]
34 px: Option<String>,
35 #[serde(rename = "posSide", skip_serializing_if = "Option::is_none")]
36 pos_side: Option<PositionSide>,
37 #[serde(rename = "clOrdId", skip_serializing_if = "Option::is_none")]
38 cl_ord_id: Option<String>,
39 #[serde(rename = "reduceOnly", skip_serializing_if = "Option::is_none")]
40 reduce_only: Option<bool>,
41 #[serde(rename = "tgtCcy", skip_serializing_if = "Option::is_none")]
42 tgt_ccy: Option<String>,
43}
44
45impl PlaceOrderRequest {
46 pub fn new(
48 inst_id: impl Into<String>,
49 td_mode: TradeMode,
50 side: OrderSide,
51 ord_type: OrderType,
52 sz: impl Into<String>,
53 ) -> Self {
54 Self {
55 inst_id: inst_id.into(),
56 td_mode,
57 side,
58 ord_type,
59 sz: sz.into(),
60 ccy: None,
61 tag: None,
62 px: None,
63 pos_side: None,
64 cl_ord_id: None,
65 reduce_only: None,
66 tgt_ccy: None,
67 }
68 }
69
70 pub fn price(mut self, px: impl Into<String>) -> Self {
72 self.px = Some(px.into());
73 self
74 }
75
76 pub fn position_side(mut self, pos_side: PositionSide) -> Self {
78 self.pos_side = Some(pos_side);
79 self
80 }
81
82 pub fn client_order_id(mut self, cl_ord_id: impl Into<String>) -> Self {
84 self.cl_ord_id = Some(cl_ord_id.into());
85 self
86 }
87
88 pub fn reduce_only(mut self, reduce_only: bool) -> Self {
90 self.reduce_only = Some(reduce_only);
91 self
92 }
93
94 pub fn target_ccy(mut self, tgt_ccy: impl Into<String>) -> Self {
96 self.tgt_ccy = Some(tgt_ccy.into());
97 self
98 }
99
100 pub fn currency(mut self, ccy: impl Into<String>) -> Self {
102 self.ccy = Some(ccy.into());
103 self
104 }
105
106 pub fn tag(mut self, tag: impl Into<String>) -> Self {
108 self.tag = Some(tag.into());
109 self
110 }
111}
112
113#[derive(Debug, Clone, Serialize)]
115pub struct CancelOrderRequest {
116 #[serde(rename = "instId")]
117 inst_id: String,
118 #[serde(rename = "ordId", skip_serializing_if = "Option::is_none")]
119 ord_id: Option<String>,
120 #[serde(rename = "clOrdId", skip_serializing_if = "Option::is_none")]
121 cl_ord_id: Option<String>,
122}
123
124impl CancelOrderRequest {
125 pub fn by_order_id(inst_id: impl Into<String>, ord_id: impl Into<String>) -> Self {
127 Self {
128 inst_id: inst_id.into(),
129 ord_id: Some(ord_id.into()),
130 cl_ord_id: None,
131 }
132 }
133
134 pub fn by_client_order_id(inst_id: impl Into<String>, cl_ord_id: impl Into<String>) -> Self {
136 Self {
137 inst_id: inst_id.into(),
138 ord_id: None,
139 cl_ord_id: Some(cl_ord_id.into()),
140 }
141 }
142}
143
144#[derive(Debug, Clone, Serialize)]
146pub struct AmendOrderRequest {
147 #[serde(rename = "instId")]
148 inst_id: String,
149 #[serde(rename = "ordId", skip_serializing_if = "Option::is_none")]
150 ord_id: Option<String>,
151 #[serde(rename = "clOrdId", skip_serializing_if = "Option::is_none")]
152 cl_ord_id: Option<String>,
153 #[serde(rename = "reqId", skip_serializing_if = "Option::is_none")]
154 req_id: Option<String>,
155 #[serde(rename = "cxlOnFail", skip_serializing_if = "Option::is_none")]
156 cxl_on_fail: Option<bool>,
157 #[serde(rename = "newSz", skip_serializing_if = "Option::is_none")]
158 new_sz: Option<String>,
159 #[serde(rename = "newPx", skip_serializing_if = "Option::is_none")]
160 new_px: Option<String>,
161}
162
163impl AmendOrderRequest {
164 pub fn new(inst_id: impl Into<String>) -> Self {
166 Self {
167 inst_id: inst_id.into(),
168 ord_id: None,
169 cl_ord_id: None,
170 req_id: None,
171 cxl_on_fail: None,
172 new_sz: None,
173 new_px: None,
174 }
175 }
176
177 pub fn order_id(mut self, ord_id: impl Into<String>) -> Self {
179 self.ord_id = Some(ord_id.into());
180 self
181 }
182
183 pub fn client_order_id(mut self, cl_ord_id: impl Into<String>) -> Self {
185 self.cl_ord_id = Some(cl_ord_id.into());
186 self
187 }
188
189 pub fn request_id(mut self, req_id: impl Into<String>) -> Self {
191 self.req_id = Some(req_id.into());
192 self
193 }
194
195 pub fn cancel_on_fail(mut self, cxl_on_fail: bool) -> Self {
197 self.cxl_on_fail = Some(cxl_on_fail);
198 self
199 }
200
201 pub fn new_size(mut self, new_sz: impl Into<String>) -> Self {
203 self.new_sz = Some(new_sz.into());
204 self
205 }
206
207 pub fn new_price(mut self, new_px: impl Into<String>) -> Self {
209 self.new_px = Some(new_px.into());
210 self
211 }
212}
213
214#[derive(Debug, Clone, Serialize)]
216pub struct ClosePositionRequest {
217 #[serde(rename = "instId")]
218 inst_id: String,
219 #[serde(rename = "mgnMode")]
220 mgn_mode: TradeMode,
221 #[serde(rename = "posSide", skip_serializing_if = "Option::is_none")]
222 pos_side: Option<PositionSide>,
223 #[serde(skip_serializing_if = "Option::is_none")]
224 ccy: Option<String>,
225 #[serde(rename = "autoCxl", skip_serializing_if = "Option::is_none")]
226 auto_cancel: Option<bool>,
227 #[serde(rename = "clOrdId", skip_serializing_if = "Option::is_none")]
228 cl_ord_id: Option<String>,
229 #[serde(skip_serializing_if = "Option::is_none")]
230 tag: Option<String>,
231}
232
233impl ClosePositionRequest {
234 pub fn new(inst_id: impl Into<String>, mgn_mode: TradeMode) -> Self {
236 Self {
237 inst_id: inst_id.into(),
238 mgn_mode,
239 pos_side: None,
240 ccy: None,
241 auto_cancel: None,
242 cl_ord_id: None,
243 tag: None,
244 }
245 }
246
247 pub fn position_side(mut self, pos_side: PositionSide) -> Self {
249 self.pos_side = Some(pos_side);
250 self
251 }
252
253 pub fn currency(mut self, ccy: impl Into<String>) -> Self {
255 self.ccy = Some(ccy.into());
256 self
257 }
258
259 pub fn auto_cancel(mut self, auto_cancel: bool) -> Self {
261 self.auto_cancel = Some(auto_cancel);
262 self
263 }
264
265 pub fn client_order_id(mut self, cl_ord_id: impl Into<String>) -> Self {
267 self.cl_ord_id = Some(cl_ord_id.into());
268 self
269 }
270
271 pub fn tag(mut self, tag: impl Into<String>) -> Self {
273 self.tag = Some(tag.into());
274 self
275 }
276}
277
278#[derive(Debug, Clone, Default, Serialize)]
280pub struct OrderListRequest {
281 #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
282 inst_type: Option<crate::model::InstType>,
283 #[serde(rename = "uly", skip_serializing_if = "Option::is_none")]
284 underlying: Option<String>,
285 #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
286 inst_id: Option<String>,
287 #[serde(rename = "ordType", skip_serializing_if = "Option::is_none")]
288 ord_type: Option<OrderType>,
289 #[serde(skip_serializing_if = "Option::is_none")]
290 state: Option<OrderState>,
291 #[serde(skip_serializing_if = "Option::is_none")]
292 after: Option<String>,
293 #[serde(skip_serializing_if = "Option::is_none")]
294 before: Option<String>,
295 #[serde(skip_serializing_if = "Option::is_none")]
296 limit: Option<u32>,
297 #[serde(rename = "instFamily", skip_serializing_if = "Option::is_none")]
298 inst_family: Option<String>,
299}
300
301impl OrderListRequest {
302 pub fn new() -> Self {
304 Self::default()
305 }
306
307 pub fn inst_type(mut self, inst_type: crate::model::InstType) -> Self {
309 self.inst_type = Some(inst_type);
310 self
311 }
312
313 pub fn underlying(mut self, underlying: impl Into<String>) -> Self {
315 self.underlying = Some(underlying.into());
316 self
317 }
318
319 pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
321 self.inst_id = Some(inst_id.into());
322 self
323 }
324
325 pub fn order_type(mut self, ord_type: OrderType) -> Self {
327 self.ord_type = Some(ord_type);
328 self
329 }
330
331 pub fn state(mut self, state: OrderState) -> Self {
333 self.state = Some(state);
334 self
335 }
336
337 pub fn after(mut self, after: impl Into<String>) -> Self {
339 self.after = Some(after.into());
340 self
341 }
342
343 pub fn before(mut self, before: impl Into<String>) -> Self {
345 self.before = Some(before.into());
346 self
347 }
348
349 pub fn limit(mut self, limit: u32) -> Self {
351 self.limit = Some(limit);
352 self
353 }
354
355 pub fn inst_family(mut self, inst_family: impl Into<String>) -> Self {
357 self.inst_family = Some(inst_family.into());
358 self
359 }
360}
361
362#[derive(Debug, Clone, Serialize)]
364pub struct OrderHistoryRequest {
365 #[serde(flatten)]
366 base: OrderListRequest,
367 #[serde(skip_serializing_if = "Option::is_none")]
368 begin: Option<String>,
369 #[serde(skip_serializing_if = "Option::is_none")]
370 end: Option<String>,
371}
372
373impl OrderHistoryRequest {
374 pub fn new(inst_type: crate::model::InstType) -> Self {
376 Self {
377 base: OrderListRequest::new().inst_type(inst_type),
378 begin: None,
379 end: None,
380 }
381 }
382
383 pub fn filters(mut self, base: OrderListRequest) -> Self {
385 self.base = base;
386 self
387 }
388
389 pub fn begin(mut self, begin: impl Into<String>) -> Self {
391 self.begin = Some(begin.into());
392 self
393 }
394
395 pub fn end(mut self, end: impl Into<String>) -> Self {
397 self.end = Some(end.into());
398 self
399 }
400}
401
402#[derive(Debug, Clone, Default, Serialize)]
404pub struct FillsRequest {
405 #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
406 inst_type: Option<crate::model::InstType>,
407 #[serde(rename = "uly", skip_serializing_if = "Option::is_none")]
408 underlying: Option<String>,
409 #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
410 inst_id: Option<String>,
411 #[serde(rename = "ordId", skip_serializing_if = "Option::is_none")]
412 ord_id: Option<String>,
413 #[serde(skip_serializing_if = "Option::is_none")]
414 after: Option<String>,
415 #[serde(skip_serializing_if = "Option::is_none")]
416 before: Option<String>,
417 #[serde(skip_serializing_if = "Option::is_none")]
418 begin: Option<String>,
419 #[serde(skip_serializing_if = "Option::is_none")]
420 end: Option<String>,
421 #[serde(skip_serializing_if = "Option::is_none")]
422 limit: Option<u32>,
423 #[serde(rename = "instFamily", skip_serializing_if = "Option::is_none")]
424 inst_family: Option<String>,
425}
426
427impl FillsRequest {
428 pub fn new() -> Self {
430 Self::default()
431 }
432
433 pub fn inst_type(mut self, inst_type: crate::model::InstType) -> Self {
435 self.inst_type = Some(inst_type);
436 self
437 }
438
439 pub fn underlying(mut self, underlying: impl Into<String>) -> Self {
441 self.underlying = Some(underlying.into());
442 self
443 }
444
445 pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
447 self.inst_id = Some(inst_id.into());
448 self
449 }
450
451 pub fn order_id(mut self, ord_id: impl Into<String>) -> Self {
453 self.ord_id = Some(ord_id.into());
454 self
455 }
456
457 pub fn after(mut self, after: impl Into<String>) -> Self {
459 self.after = Some(after.into());
460 self
461 }
462
463 pub fn before(mut self, before: impl Into<String>) -> Self {
465 self.before = Some(before.into());
466 self
467 }
468
469 pub fn begin(mut self, begin: impl Into<String>) -> Self {
471 self.begin = Some(begin.into());
472 self
473 }
474
475 pub fn end(mut self, end: impl Into<String>) -> Self {
477 self.end = Some(end.into());
478 self
479 }
480
481 pub fn limit(mut self, limit: u32) -> Self {
483 self.limit = Some(limit);
484 self
485 }
486
487 pub fn inst_family(mut self, inst_family: impl Into<String>) -> Self {
489 self.inst_family = Some(inst_family.into());
490 self
491 }
492}
493
494#[derive(Debug, Clone, Serialize)]
500pub struct FillHistoryRequest {
501 #[serde(rename = "instType")]
502 inst_type: crate::model::InstType,
503 #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
504 inst_id: Option<String>,
505 #[serde(rename = "ordId", skip_serializing_if = "Option::is_none")]
506 ord_id: Option<String>,
507 #[serde(skip_serializing_if = "Option::is_none")]
508 after: Option<String>,
509 #[serde(skip_serializing_if = "Option::is_none")]
510 before: Option<String>,
511 #[serde(skip_serializing_if = "Option::is_none")]
512 begin: Option<String>,
513 #[serde(skip_serializing_if = "Option::is_none")]
514 end: Option<String>,
515 #[serde(skip_serializing_if = "Option::is_none")]
516 limit: Option<u32>,
517}
518
519impl FillHistoryRequest {
520 pub fn new(inst_type: crate::model::InstType) -> Self {
522 Self {
523 inst_type,
524 inst_id: None,
525 ord_id: None,
526 after: None,
527 before: None,
528 begin: None,
529 end: None,
530 limit: None,
531 }
532 }
533
534 pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
536 self.inst_id = Some(inst_id.into());
537 self
538 }
539
540 pub fn order_id(mut self, ord_id: impl Into<String>) -> Self {
542 self.ord_id = Some(ord_id.into());
543 self
544 }
545
546 pub fn after(mut self, after: impl Into<String>) -> Self {
548 self.after = Some(after.into());
549 self
550 }
551
552 pub fn before(mut self, before: impl Into<String>) -> Self {
554 self.before = Some(before.into());
555 self
556 }
557
558 pub fn begin(mut self, begin: impl Into<String>) -> Self {
560 self.begin = Some(begin.into());
561 self
562 }
563
564 pub fn end(mut self, end: impl Into<String>) -> Self {
566 self.end = Some(end.into());
567 self
568 }
569
570 pub fn limit(mut self, limit: u32) -> Self {
572 self.limit = Some(limit);
573 self
574 }
575}
576
577impl ValidateRequest for FillHistoryRequest {
578 fn validate(&self) -> Result<(), crate::model::RequestValidationError> {
579 one_of("instType", self.inst_type.as_str(), &["SPOT"], "SPOT")?;
580 optional_non_empty("instId", self.inst_id.as_deref())?;
581 optional_unsigned_integer_string("ordId", self.ord_id.as_deref())?;
582 optional_unsigned_integer_string("after", self.after.as_deref())?;
583 optional_unsigned_integer_string("before", self.before.as_deref())?;
584 optional_unsigned_integer_string("begin", self.begin.as_deref())?;
585 optional_unsigned_integer_string("end", self.end.as_deref())?;
586 if let Some(limit) = self.limit {
587 range_u64("limit", u64::from(limit), 1, 100)?;
588 }
589 Ok(())
590 }
591}