Skip to main content

rust_okx/api/account/
requests.rs

1use serde::Serialize;
2
3use crate::model::{InstType, PositionSide, RequestParams, TradeMode};
4
5/// Query parameters for VIP interest-accrued records.
6pub type VipInterestAccruedRequest = RequestParams;
7
8/// Query parameters for VIP interest-deducted records.
9pub type VipInterestDeductedRequest = RequestParams;
10
11/// Query parameters for VIP-loan order list.
12pub type VipLoanOrderListRequest = RequestParams;
13
14/// Query parameters for VIP-loan order detail.
15pub type VipLoanOrderDetailRequest = RequestParams;
16
17/// Query parameters for fixed-loan borrowing limits.
18pub type FixedLoanBorrowingLimitRequest = RequestParams;
19
20/// Request body for a fixed-loan borrowing quote.
21pub type FixedLoanBorrowingQuoteRequest = RequestParams;
22
23/// Request body for placing a fixed-loan borrowing order.
24pub type FixedLoanBorrowingOrderRequest = RequestParams;
25
26/// Request body for amending a fixed-loan borrowing order.
27pub type FixedLoanAmendBorrowingOrderRequest = RequestParams;
28
29/// Request body for manually reborrowing a fixed-loan order.
30pub type FixedLoanManualReborrowRequest = RequestParams;
31
32/// Request body for repaying a fixed-loan borrowing order.
33pub type FixedLoanRepayBorrowingOrderRequest = RequestParams;
34
35/// Query parameters for fixed-loan borrowing order history/list.
36pub type FixedLoanBorrowingOrdersListRequest = RequestParams;
37
38/// Request body for spot manual borrow/repay.
39pub type SpotManualBorrowRepayRequest = RequestParams;
40
41/// Request body for setting spot auto repay.
42pub type SetAutoRepayRequest = RequestParams;
43
44/// Query parameters for spot borrow/repay history.
45pub type SpotBorrowRepayHistoryRequest = RequestParams;
46
47/// Request body for setting auto earn.
48pub type SetAutoEarnRequest = RequestParams;
49
50/// Query parameters for account bills.
51#[derive(Debug, Clone, Default, Serialize)]
52pub struct BillsRequest {
53    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
54    inst_type: Option<InstType>,
55    #[serde(skip_serializing_if = "Option::is_none")]
56    ccy: Option<String>,
57    #[serde(rename = "mgnMode", skip_serializing_if = "Option::is_none")]
58    mgn_mode: Option<TradeMode>,
59    #[serde(rename = "ctType", skip_serializing_if = "Option::is_none")]
60    ct_type: Option<String>,
61    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
62    bill_type: Option<String>,
63    #[serde(rename = "subType", skip_serializing_if = "Option::is_none")]
64    sub_type: Option<String>,
65    #[serde(skip_serializing_if = "Option::is_none")]
66    after: Option<String>,
67    #[serde(skip_serializing_if = "Option::is_none")]
68    before: Option<String>,
69    #[serde(skip_serializing_if = "Option::is_none")]
70    limit: Option<u32>,
71}
72
73impl BillsRequest {
74    /// Create an empty account-bills query.
75    pub fn new() -> Self {
76        Self::default()
77    }
78
79    /// Set the instrument type filter.
80    pub fn inst_type(mut self, inst_type: InstType) -> Self {
81        self.inst_type = Some(inst_type);
82        self
83    }
84
85    /// Set the currency filter.
86    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
87        self.ccy = Some(ccy.into());
88        self
89    }
90
91    /// Set the margin mode filter.
92    pub fn margin_mode(mut self, mgn_mode: TradeMode) -> Self {
93        self.mgn_mode = Some(mgn_mode);
94        self
95    }
96
97    /// Set the contract type filter.
98    pub fn contract_type(mut self, ct_type: impl Into<String>) -> Self {
99        self.ct_type = Some(ct_type.into());
100        self
101    }
102
103    /// Set the bill type filter.
104    pub fn bill_type(mut self, bill_type: impl Into<String>) -> Self {
105        self.bill_type = Some(bill_type.into());
106        self
107    }
108
109    /// Set the bill subtype filter.
110    pub fn sub_type(mut self, sub_type: impl Into<String>) -> Self {
111        self.sub_type = Some(sub_type.into());
112        self
113    }
114
115    /// Return records after this pagination cursor.
116    pub fn after(mut self, after: impl Into<String>) -> Self {
117        self.after = Some(after.into());
118        self
119    }
120
121    /// Return records before this pagination cursor.
122    pub fn before(mut self, before: impl Into<String>) -> Self {
123        self.before = Some(before.into());
124        self
125    }
126
127    /// Set the maximum number of rows to return.
128    pub fn limit(mut self, limit: u32) -> Self {
129        self.limit = Some(limit);
130        self
131    }
132}
133
134/// Query parameters for archived account bills.
135#[derive(Debug, Clone, Default, Serialize)]
136pub struct BillsArchiveRequest {
137    #[serde(flatten)]
138    base: BillsRequest,
139    #[serde(skip_serializing_if = "Option::is_none")]
140    begin: Option<String>,
141    #[serde(skip_serializing_if = "Option::is_none")]
142    end: Option<String>,
143}
144
145impl BillsArchiveRequest {
146    /// Create an empty archived-bills query.
147    pub fn new() -> Self {
148        Self::default()
149    }
150
151    /// Set the common bills filters.
152    pub fn filters(mut self, base: BillsRequest) -> Self {
153        self.base = base;
154        self
155    }
156
157    /// Set the begin timestamp.
158    pub fn begin(mut self, begin: impl Into<String>) -> Self {
159        self.begin = Some(begin.into());
160        self
161    }
162
163    /// Set the end timestamp.
164    pub fn end(mut self, end: impl Into<String>) -> Self {
165        self.end = Some(end.into());
166        self
167    }
168}
169
170/// Request body for setting leverage.
171#[derive(Debug, Clone, Serialize)]
172pub struct SetLeverageRequest {
173    lever: String,
174    #[serde(rename = "mgnMode")]
175    mgn_mode: TradeMode,
176    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
177    inst_id: Option<String>,
178    #[serde(skip_serializing_if = "Option::is_none")]
179    ccy: Option<String>,
180    #[serde(rename = "posSide", skip_serializing_if = "Option::is_none")]
181    pos_side: Option<PositionSide>,
182}
183
184impl SetLeverageRequest {
185    /// Create a leverage-setting request.
186    pub fn new(lever: impl Into<String>, mgn_mode: TradeMode) -> Self {
187        Self {
188            lever: lever.into(),
189            mgn_mode,
190            inst_id: None,
191            ccy: None,
192            pos_side: None,
193        }
194    }
195
196    /// Set the instrument ID.
197    pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
198        self.inst_id = Some(inst_id.into());
199        self
200    }
201
202    /// Set the currency.
203    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
204        self.ccy = Some(ccy.into());
205        self
206    }
207
208    /// Set the position side.
209    pub fn position_side(mut self, pos_side: PositionSide) -> Self {
210        self.pos_side = Some(pos_side);
211        self
212    }
213}
214
215/// Query parameters for retrieving leverage.
216#[derive(Debug, Clone, Serialize)]
217pub struct LeverageRequest {
218    #[serde(rename = "mgnMode")]
219    mgn_mode: TradeMode,
220    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
221    inst_id: Option<String>,
222    #[serde(skip_serializing_if = "Option::is_none")]
223    ccy: Option<String>,
224}
225
226impl LeverageRequest {
227    /// Create a leverage-info query.
228    pub fn new(mgn_mode: TradeMode) -> Self {
229        Self {
230            mgn_mode,
231            inst_id: None,
232            ccy: None,
233        }
234    }
235
236    /// Set the instrument ID.
237    pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
238        self.inst_id = Some(inst_id.into());
239        self
240    }
241
242    /// Set the currency.
243    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
244        self.ccy = Some(ccy.into());
245        self
246    }
247}
248
249/// Query parameters for maximum order size.
250#[derive(Debug, Clone, Serialize)]
251pub struct MaxOrderSizeRequest {
252    #[serde(rename = "instId")]
253    inst_id: String,
254    #[serde(rename = "tdMode")]
255    td_mode: TradeMode,
256    #[serde(skip_serializing_if = "Option::is_none")]
257    ccy: Option<String>,
258    #[serde(skip_serializing_if = "Option::is_none")]
259    px: Option<String>,
260    #[serde(rename = "tradeQuoteCcy", skip_serializing_if = "Option::is_none")]
261    trade_quote_ccy: Option<String>,
262}
263
264impl MaxOrderSizeRequest {
265    /// Create a maximum-order-size query.
266    pub fn new(inst_id: impl Into<String>, td_mode: TradeMode) -> Self {
267        Self {
268            inst_id: inst_id.into(),
269            td_mode,
270            ccy: None,
271            px: None,
272            trade_quote_ccy: None,
273        }
274    }
275
276    /// Set the currency.
277    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
278        self.ccy = Some(ccy.into());
279        self
280    }
281
282    /// Set the price.
283    pub fn price(mut self, px: impl Into<String>) -> Self {
284        self.px = Some(px.into());
285        self
286    }
287
288    /// Set the trade quote currency.
289    pub fn trade_quote_currency(mut self, trade_quote_ccy: impl Into<String>) -> Self {
290        self.trade_quote_ccy = Some(trade_quote_ccy.into());
291        self
292    }
293}
294
295/// Query parameters for maximum available size.
296#[derive(Debug, Clone, Serialize)]
297pub struct MaxAvailableSizeRequest {
298    #[serde(rename = "instId")]
299    inst_id: String,
300    #[serde(rename = "tdMode")]
301    td_mode: TradeMode,
302    #[serde(skip_serializing_if = "Option::is_none")]
303    ccy: Option<String>,
304    #[serde(rename = "reduceOnly", skip_serializing_if = "Option::is_none")]
305    reduce_only: Option<bool>,
306    #[serde(rename = "unSpotOffset", skip_serializing_if = "Option::is_none")]
307    un_spot_offset: Option<bool>,
308    #[serde(rename = "quickMgnType", skip_serializing_if = "Option::is_none")]
309    quick_mgn_type: Option<String>,
310    #[serde(rename = "tradeQuoteCcy", skip_serializing_if = "Option::is_none")]
311    trade_quote_ccy: Option<String>,
312}
313
314impl MaxAvailableSizeRequest {
315    /// Create a maximum-available-size query.
316    pub fn new(inst_id: impl Into<String>, td_mode: TradeMode) -> Self {
317        Self {
318            inst_id: inst_id.into(),
319            td_mode,
320            ccy: None,
321            reduce_only: None,
322            un_spot_offset: None,
323            quick_mgn_type: None,
324            trade_quote_ccy: None,
325        }
326    }
327
328    /// Set the currency.
329    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
330        self.ccy = Some(ccy.into());
331        self
332    }
333
334    /// Set the reduce-only filter.
335    pub fn reduce_only(mut self, reduce_only: bool) -> Self {
336        self.reduce_only = Some(reduce_only);
337        self
338    }
339
340    /// Set the spot offset flag.
341    pub fn un_spot_offset(mut self, un_spot_offset: bool) -> Self {
342        self.un_spot_offset = Some(un_spot_offset);
343        self
344    }
345
346    /// Set the quick margin type.
347    pub fn quick_margin_type(mut self, quick_mgn_type: impl Into<String>) -> Self {
348        self.quick_mgn_type = Some(quick_mgn_type.into());
349        self
350    }
351
352    /// Set the trade quote currency.
353    pub fn trade_quote_currency(mut self, trade_quote_ccy: impl Into<String>) -> Self {
354        self.trade_quote_ccy = Some(trade_quote_ccy.into());
355        self
356    }
357}
358
359/// Request body for adjusting position margin.
360#[derive(Debug, Clone, Serialize)]
361pub struct AdjustMarginRequest {
362    #[serde(rename = "instId")]
363    inst_id: String,
364    #[serde(rename = "posSide")]
365    pos_side: PositionSide,
366    #[serde(rename = "type")]
367    action: String,
368    amt: String,
369    #[serde(rename = "loanTrans", skip_serializing_if = "Option::is_none")]
370    loan_trans: Option<bool>,
371}
372
373impl AdjustMarginRequest {
374    /// Create a margin-adjustment request.
375    pub fn new(
376        inst_id: impl Into<String>,
377        pos_side: PositionSide,
378        action: impl Into<String>,
379        amt: impl Into<String>,
380    ) -> Self {
381        Self {
382            inst_id: inst_id.into(),
383            pos_side,
384            action: action.into(),
385            amt: amt.into(),
386            loan_trans: None,
387        }
388    }
389
390    /// Set whether to allow loan transfer.
391    pub fn loan_transfer(mut self, loan_trans: bool) -> Self {
392        self.loan_trans = Some(loan_trans);
393        self
394    }
395}
396
397/// Query parameters for trade fee rates.
398#[derive(Debug, Clone, Serialize)]
399pub struct FeeRatesRequest {
400    #[serde(rename = "instType")]
401    inst_type: InstType,
402    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
403    inst_id: Option<String>,
404    #[serde(rename = "uly", skip_serializing_if = "Option::is_none")]
405    underlying: Option<String>,
406    #[serde(skip_serializing_if = "Option::is_none")]
407    category: Option<String>,
408    #[serde(rename = "instFamily", skip_serializing_if = "Option::is_none")]
409    inst_family: Option<String>,
410}
411
412impl FeeRatesRequest {
413    /// Create a fee-rates query.
414    pub fn new(inst_type: InstType) -> Self {
415        Self {
416            inst_type,
417            inst_id: None,
418            underlying: None,
419            category: None,
420            inst_family: None,
421        }
422    }
423
424    /// Set the instrument ID.
425    pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
426        self.inst_id = Some(inst_id.into());
427        self
428    }
429
430    /// Set the underlying.
431    pub fn underlying(mut self, underlying: impl Into<String>) -> Self {
432        self.underlying = Some(underlying.into());
433        self
434    }
435
436    /// Set the fee category.
437    pub fn category(mut self, category: impl Into<String>) -> Self {
438        self.category = Some(category.into());
439        self
440    }
441
442    /// Set the instrument family.
443    pub fn inst_family(mut self, inst_family: impl Into<String>) -> Self {
444        self.inst_family = Some(inst_family.into());
445        self
446    }
447}
448
449/// Query parameters for account instruments.
450#[derive(Debug, Clone, Default, Serialize)]
451pub struct AccountInstrumentsRequest {
452    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
453    inst_type: Option<InstType>,
454    #[serde(rename = "uly", skip_serializing_if = "Option::is_none")]
455    underlying: Option<String>,
456    #[serde(rename = "instFamily", skip_serializing_if = "Option::is_none")]
457    inst_family: Option<String>,
458    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
459    inst_id: Option<String>,
460}
461
462impl AccountInstrumentsRequest {
463    /// Create an empty account-instruments query.
464    pub fn new() -> Self {
465        Self::default()
466    }
467
468    /// Set the instrument type filter.
469    pub fn inst_type(mut self, inst_type: InstType) -> Self {
470        self.inst_type = Some(inst_type);
471        self
472    }
473
474    /// Set the underlying filter.
475    pub fn underlying(mut self, underlying: impl Into<String>) -> Self {
476        self.underlying = Some(underlying.into());
477        self
478    }
479
480    /// Set the instrument family filter.
481    pub fn inst_family(mut self, inst_family: impl Into<String>) -> Self {
482        self.inst_family = Some(inst_family.into());
483        self
484    }
485
486    /// Set the instrument ID filter.
487    pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
488        self.inst_id = Some(inst_id.into());
489        self
490    }
491}
492
493/// Query parameters for maximum loan.
494#[derive(Debug, Clone, Serialize)]
495pub struct MaxLoanRequest {
496    #[serde(rename = "instId")]
497    inst_id: String,
498    #[serde(rename = "mgnMode")]
499    mgn_mode: TradeMode,
500    #[serde(rename = "mgnCcy", skip_serializing_if = "Option::is_none")]
501    mgn_ccy: Option<String>,
502    #[serde(rename = "tradeQuoteCcy", skip_serializing_if = "Option::is_none")]
503    trade_quote_ccy: Option<String>,
504}
505
506impl MaxLoanRequest {
507    /// Create a maximum-loan query.
508    pub fn new(inst_id: impl Into<String>, mgn_mode: TradeMode) -> Self {
509        Self {
510            inst_id: inst_id.into(),
511            mgn_mode,
512            mgn_ccy: None,
513            trade_quote_ccy: None,
514        }
515    }
516
517    /// Set the margin currency.
518    pub fn margin_currency(mut self, mgn_ccy: impl Into<String>) -> Self {
519        self.mgn_ccy = Some(mgn_ccy.into());
520        self
521    }
522
523    /// Set the trade quote currency.
524    pub fn trade_quote_currency(mut self, trade_quote_ccy: impl Into<String>) -> Self {
525        self.trade_quote_ccy = Some(trade_quote_ccy.into());
526        self
527    }
528}
529
530/// Query parameters for interest-accrued records.
531#[derive(Debug, Clone, Default, Serialize)]
532pub struct InterestAccruedRequest {
533    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
534    inst_id: Option<String>,
535    #[serde(skip_serializing_if = "Option::is_none")]
536    ccy: Option<String>,
537    #[serde(rename = "mgnMode", skip_serializing_if = "Option::is_none")]
538    mgn_mode: Option<TradeMode>,
539    #[serde(skip_serializing_if = "Option::is_none")]
540    after: Option<String>,
541    #[serde(skip_serializing_if = "Option::is_none")]
542    before: Option<String>,
543    #[serde(skip_serializing_if = "Option::is_none")]
544    limit: Option<u32>,
545}
546
547impl InterestAccruedRequest {
548    /// Create an empty interest-accrued query.
549    pub fn new() -> Self {
550        Self::default()
551    }
552
553    /// Set the instrument ID filter.
554    pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
555        self.inst_id = Some(inst_id.into());
556        self
557    }
558
559    /// Set the currency filter.
560    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
561        self.ccy = Some(ccy.into());
562        self
563    }
564
565    /// Set the margin mode filter.
566    pub fn margin_mode(mut self, mgn_mode: TradeMode) -> Self {
567        self.mgn_mode = Some(mgn_mode);
568        self
569    }
570
571    /// Return records after this pagination cursor.
572    pub fn after(mut self, after: impl Into<String>) -> Self {
573        self.after = Some(after.into());
574        self
575    }
576
577    /// Return records before this pagination cursor.
578    pub fn before(mut self, before: impl Into<String>) -> Self {
579        self.before = Some(before.into());
580        self
581    }
582
583    /// Set the maximum number of rows to return.
584    pub fn limit(mut self, limit: u32) -> Self {
585        self.limit = Some(limit);
586        self
587    }
588}
589/// Request body for borrow/repay.
590#[derive(Debug, Clone, Serialize)]
591pub struct BorrowRepayRequest {
592    ccy: String,
593    side: String,
594    amt: String,
595    #[serde(rename = "ordId", skip_serializing_if = "Option::is_none")]
596    ord_id: Option<String>,
597}
598
599impl BorrowRepayRequest {
600    /// Create a borrow/repay request.
601    pub fn new(ccy: impl Into<String>, side: impl Into<String>, amt: impl Into<String>) -> Self {
602        Self {
603            ccy: ccy.into(),
604            side: side.into(),
605            amt: amt.into(),
606            ord_id: None,
607        }
608    }
609
610    /// Set the related order ID.
611    pub fn order_id(mut self, ord_id: impl Into<String>) -> Self {
612        self.ord_id = Some(ord_id.into());
613        self
614    }
615}
616
617/// Query parameters for borrow/repay history.
618#[derive(Debug, Clone, Default, Serialize)]
619pub struct BorrowRepayHistoryRequest {
620    #[serde(skip_serializing_if = "Option::is_none")]
621    ccy: Option<String>,
622    #[serde(skip_serializing_if = "Option::is_none")]
623    after: Option<String>,
624    #[serde(skip_serializing_if = "Option::is_none")]
625    before: Option<String>,
626    #[serde(skip_serializing_if = "Option::is_none")]
627    limit: Option<u32>,
628}
629
630impl BorrowRepayHistoryRequest {
631    /// Create an empty borrow/repay-history query.
632    pub fn new() -> Self {
633        Self::default()
634    }
635
636    /// Set the currency filter.
637    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
638        self.ccy = Some(ccy.into());
639        self
640    }
641
642    /// Return records after this pagination cursor.
643    pub fn after(mut self, after: impl Into<String>) -> Self {
644        self.after = Some(after.into());
645        self
646    }
647
648    /// Return records before this pagination cursor.
649    pub fn before(mut self, before: impl Into<String>) -> Self {
650        self.before = Some(before.into());
651        self
652    }
653
654    /// Set the maximum number of rows to return.
655    pub fn limit(mut self, limit: u32) -> Self {
656        self.limit = Some(limit);
657        self
658    }
659}
660
661/// Query parameters for interest limits.
662#[derive(Debug, Clone, Default, Serialize)]
663pub struct InterestLimitsRequest {
664    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
665    limit_type: Option<String>,
666    #[serde(skip_serializing_if = "Option::is_none")]
667    ccy: Option<String>,
668}
669
670impl InterestLimitsRequest {
671    /// Create an empty interest-limits query.
672    pub fn new() -> Self {
673        Self::default()
674    }
675
676    /// Set the OKX interest-limit type.
677    pub fn limit_type(mut self, limit_type: impl Into<String>) -> Self {
678        self.limit_type = Some(limit_type.into());
679        self
680    }
681
682    /// Set the currency filter.
683    pub fn currency(mut self, ccy: impl Into<String>) -> Self {
684        self.ccy = Some(ccy.into());
685        self
686    }
687}
688
689/// A simulated position used by position-builder and simulated-margin requests.
690#[derive(Debug, Clone, Serialize)]
691pub struct SimulatedPosition {
692    #[serde(rename = "instId")]
693    inst_id: String,
694    #[serde(skip_serializing_if = "Option::is_none")]
695    pos: Option<String>,
696    #[serde(rename = "avgPx", skip_serializing_if = "Option::is_none")]
697    avg_px: Option<String>,
698    #[serde(skip_serializing_if = "Option::is_none")]
699    lever: Option<String>,
700}
701
702impl SimulatedPosition {
703    /// Create a simulated position for an instrument.
704    pub fn new(inst_id: impl Into<String>) -> Self {
705        Self {
706            inst_id: inst_id.into(),
707            pos: None,
708            avg_px: None,
709            lever: None,
710        }
711    }
712
713    /// Set the simulated position size.
714    pub fn position(mut self, pos: impl Into<String>) -> Self {
715        self.pos = Some(pos.into());
716        self
717    }
718
719    /// Set the simulated average price.
720    pub fn average_price(mut self, avg_px: impl Into<String>) -> Self {
721        self.avg_px = Some(avg_px.into());
722        self
723    }
724
725    /// Set the simulated leverage.
726    pub fn leverage(mut self, lever: impl Into<String>) -> Self {
727        self.lever = Some(lever.into());
728        self
729    }
730}
731
732/// A simulated asset used by position-builder requests.
733#[derive(Debug, Clone, Serialize)]
734pub struct SimulatedAsset {
735    ccy: String,
736    #[serde(skip_serializing_if = "Option::is_none")]
737    eq: Option<String>,
738}
739
740impl SimulatedAsset {
741    /// Create a simulated asset for a currency.
742    pub fn new(ccy: impl Into<String>) -> Self {
743        Self {
744            ccy: ccy.into(),
745            eq: None,
746        }
747    }
748
749    /// Set the simulated equity.
750    pub fn equity(mut self, eq: impl Into<String>) -> Self {
751        self.eq = Some(eq.into());
752        self
753    }
754}
755
756/// Request body for simulated margin calculation.
757#[derive(Debug, Clone, Default, Serialize)]
758pub struct SimulatedMarginRequest {
759    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
760    inst_type: Option<InstType>,
761    #[serde(rename = "inclRealPos", skip_serializing_if = "Option::is_none")]
762    include_real_positions: Option<bool>,
763    #[serde(rename = "spotOffsetType", skip_serializing_if = "Option::is_none")]
764    spot_offset_type: Option<String>,
765    #[serde(rename = "simPos", skip_serializing_if = "Option::is_none")]
766    simulated_positions: Option<Vec<SimulatedPosition>>,
767}
768
769impl SimulatedMarginRequest {
770    /// Create an empty simulated-margin request.
771    pub fn new() -> Self {
772        Self::default()
773    }
774
775    /// Set the instrument type.
776    pub fn inst_type(mut self, inst_type: InstType) -> Self {
777        self.inst_type = Some(inst_type);
778        self
779    }
780
781    /// Set whether real positions and equity are included.
782    pub fn include_real_positions(mut self, include_real_positions: bool) -> Self {
783        self.include_real_positions = Some(include_real_positions);
784        self
785    }
786
787    /// Set the spot offset type.
788    pub fn spot_offset_type(mut self, spot_offset_type: impl Into<String>) -> Self {
789        self.spot_offset_type = Some(spot_offset_type.into());
790        self
791    }
792
793    /// Set simulated positions.
794    pub fn simulated_positions(mut self, simulated_positions: Vec<SimulatedPosition>) -> Self {
795        self.simulated_positions = Some(simulated_positions);
796        self
797    }
798}
799
800/// Query parameters for account position tiers.
801#[derive(Debug, Clone, Default, Serialize)]
802pub struct AccountPositionTiersRequest {
803    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
804    inst_type: Option<InstType>,
805    #[serde(rename = "uly", skip_serializing_if = "Option::is_none")]
806    underlying: Option<String>,
807    #[serde(rename = "instFamily", skip_serializing_if = "Option::is_none")]
808    inst_family: Option<String>,
809}
810
811impl AccountPositionTiersRequest {
812    /// Create an empty account position-tiers query.
813    pub fn new() -> Self {
814        Self::default()
815    }
816
817    /// Set the instrument type filter.
818    pub fn inst_type(mut self, inst_type: InstType) -> Self {
819        self.inst_type = Some(inst_type);
820        self
821    }
822
823    /// Set the underlying filter.
824    pub fn underlying(mut self, underlying: impl Into<String>) -> Self {
825        self.underlying = Some(underlying.into());
826        self
827    }
828
829    /// Set the instrument family filter.
830    pub fn inst_family(mut self, inst_family: impl Into<String>) -> Self {
831        self.inst_family = Some(inst_family.into());
832        self
833    }
834}
835/// Request body for position builder.
836#[derive(Debug, Clone, Default, Serialize)]
837pub struct PositionBuilderRequest {
838    #[serde(rename = "acctLv", skip_serializing_if = "Option::is_none")]
839    acct_lv: Option<String>,
840    #[serde(rename = "inclRealPosAndEq", skip_serializing_if = "Option::is_none")]
841    include_real_positions_and_equity: Option<bool>,
842    #[serde(skip_serializing_if = "Option::is_none")]
843    lever: Option<String>,
844    #[serde(rename = "greeksType", skip_serializing_if = "Option::is_none")]
845    greeks_type: Option<String>,
846    #[serde(rename = "simPos", skip_serializing_if = "Option::is_none")]
847    simulated_positions: Option<Vec<SimulatedPosition>>,
848    #[serde(rename = "simAsset", skip_serializing_if = "Option::is_none")]
849    simulated_assets: Option<Vec<SimulatedAsset>>,
850    #[serde(rename = "idxVol", skip_serializing_if = "Option::is_none")]
851    index_volatility: Option<String>,
852}
853
854impl PositionBuilderRequest {
855    /// Create an empty position-builder request.
856    pub fn new() -> Self {
857        Self::default()
858    }
859
860    /// Set the account level.
861    pub fn account_level(mut self, acct_lv: impl Into<String>) -> Self {
862        self.acct_lv = Some(acct_lv.into());
863        self
864    }
865
866    /// Set whether real positions and equity are included.
867    pub fn include_real_positions_and_equity(mut self, include: bool) -> Self {
868        self.include_real_positions_and_equity = Some(include);
869        self
870    }
871
872    /// Set leverage.
873    pub fn leverage(mut self, lever: impl Into<String>) -> Self {
874        self.lever = Some(lever.into());
875        self
876    }
877
878    /// Set greeks display type.
879    pub fn greeks_type(mut self, greeks_type: impl Into<String>) -> Self {
880        self.greeks_type = Some(greeks_type.into());
881        self
882    }
883
884    /// Set simulated positions.
885    pub fn simulated_positions(mut self, simulated_positions: Vec<SimulatedPosition>) -> Self {
886        self.simulated_positions = Some(simulated_positions);
887        self
888    }
889
890    /// Set simulated assets.
891    pub fn simulated_assets(mut self, simulated_assets: Vec<SimulatedAsset>) -> Self {
892        self.simulated_assets = Some(simulated_assets);
893        self
894    }
895
896    /// Set index volatility.
897    pub fn index_volatility(mut self, index_volatility: impl Into<String>) -> Self {
898        self.index_volatility = Some(index_volatility.into());
899        self
900    }
901}
902
903/// Query parameters for position history.
904#[derive(Debug, Clone, Default, Serialize)]
905pub struct PositionsHistoryRequest {
906    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
907    inst_type: Option<InstType>,
908    #[serde(rename = "instId", skip_serializing_if = "Option::is_none")]
909    inst_id: Option<String>,
910    #[serde(rename = "mgnMode", skip_serializing_if = "Option::is_none")]
911    mgn_mode: Option<TradeMode>,
912    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
913    close_type: Option<String>,
914    #[serde(rename = "posId", skip_serializing_if = "Option::is_none")]
915    pos_id: Option<String>,
916    #[serde(skip_serializing_if = "Option::is_none")]
917    after: Option<String>,
918    #[serde(skip_serializing_if = "Option::is_none")]
919    before: Option<String>,
920    #[serde(skip_serializing_if = "Option::is_none")]
921    limit: Option<u32>,
922}
923
924impl PositionsHistoryRequest {
925    /// Create an empty position-history query.
926    pub fn new() -> Self {
927        Self::default()
928    }
929
930    /// Set the instrument type filter.
931    pub fn inst_type(mut self, inst_type: InstType) -> Self {
932        self.inst_type = Some(inst_type);
933        self
934    }
935
936    /// Set the instrument ID filter.
937    pub fn inst_id(mut self, inst_id: impl Into<String>) -> Self {
938        self.inst_id = Some(inst_id.into());
939        self
940    }
941
942    /// Set the margin mode filter.
943    pub fn margin_mode(mut self, mgn_mode: TradeMode) -> Self {
944        self.mgn_mode = Some(mgn_mode);
945        self
946    }
947
948    /// Set the OKX close type filter.
949    pub fn close_type(mut self, close_type: impl Into<String>) -> Self {
950        self.close_type = Some(close_type.into());
951        self
952    }
953
954    /// Set the position ID filter.
955    pub fn position_id(mut self, pos_id: impl Into<String>) -> Self {
956        self.pos_id = Some(pos_id.into());
957        self
958    }
959
960    /// Return records after this pagination cursor.
961    pub fn after(mut self, after: impl Into<String>) -> Self {
962        self.after = Some(after.into());
963        self
964    }
965
966    /// Return records before this pagination cursor.
967    pub fn before(mut self, before: impl Into<String>) -> Self {
968        self.before = Some(before.into());
969        self
970    }
971
972    /// Set the maximum number of rows to return.
973    pub fn limit(mut self, limit: u32) -> Self {
974        self.limit = Some(limit);
975        self
976    }
977}