1use derive_builder::Builder;
19use serde::{Deserialize, Serialize};
20
21use crate::common::{
22 enums::{
23 BybitAccountType, BybitBboSideType, BybitExecType, BybitInstrumentStatus,
24 BybitKlineInterval, BybitMarginMode, BybitMarketUnit, BybitOpenOnly, BybitOptionType,
25 BybitOrderFilter, BybitOrderSide, BybitOrderStatus, BybitOrderType, BybitPositionIdx,
26 BybitPositionMode, BybitProductType, BybitSmpType, BybitStopOrderType, BybitTimeInForce,
27 BybitTpSlMode, BybitTriggerDirection, BybitTriggerType,
28 },
29 parse::opt_bool_as_int,
30};
31
32#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
37#[serde(rename_all = "camelCase")]
38#[builder(default)]
39#[builder(setter(into))]
40pub struct BybitInstrumentsInfoParams {
41 pub category: BybitProductType,
42 #[builder(setter(strip_option))]
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub symbol: Option<String>,
45 #[builder(setter(strip_option))]
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub status: Option<BybitInstrumentStatus>,
48 #[builder(setter(strip_option))]
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub base_coin: Option<String>,
51 #[builder(setter(strip_option))]
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub limit: Option<u32>,
54 #[builder(setter(strip_option))]
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub cursor: Option<String>,
57}
58
59#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
64#[serde(rename_all = "camelCase")]
65#[builder(default)]
66#[builder(setter(into))]
67pub struct BybitTickersParams {
68 pub category: BybitProductType,
69 #[serde(skip_serializing_if = "Option::is_none")]
70 #[builder(setter(strip_option))]
71 pub symbol: Option<String>,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 #[builder(setter(strip_option))]
74 pub base_coin: Option<String>,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 #[builder(setter(strip_option))]
77 pub exp_date: Option<String>,
78}
79
80#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
85#[serde(rename_all = "camelCase")]
86#[builder(setter(into, strip_option), default)]
87pub struct BybitKlinesParams {
88 pub category: BybitProductType,
89 pub symbol: String,
90 pub interval: BybitKlineInterval,
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub start: Option<i64>,
93 #[serde(skip_serializing_if = "Option::is_none")]
94 pub end: Option<i64>,
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub limit: Option<u32>,
97}
98
99impl Default for BybitKlinesParams {
100 fn default() -> Self {
101 Self {
102 category: BybitProductType::Linear,
103 symbol: String::new(),
104 interval: BybitKlineInterval::Minute1,
105 start: None,
106 end: None,
107 limit: None,
108 }
109 }
110}
111
112#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
117#[serde(rename_all = "camelCase")]
118#[builder(setter(into, strip_option), default)]
119pub struct BybitTradesParams {
120 pub category: BybitProductType,
121 pub symbol: String,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub base_coin: Option<String>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub option_type: Option<BybitOptionType>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub limit: Option<u32>,
128}
129
130impl Default for BybitTradesParams {
131 fn default() -> Self {
132 Self {
133 category: BybitProductType::Linear,
134 symbol: String::new(),
135 base_coin: None,
136 option_type: None,
137 limit: None,
138 }
139 }
140}
141
142#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
147#[serde(rename_all = "camelCase")]
148#[builder(setter(into, strip_option), default)]
149pub struct BybitFundingParams {
150 pub category: BybitProductType,
151 pub symbol: String,
152 #[serde(skip_serializing_if = "Option::is_none")]
153 pub start_time: Option<i64>,
154 #[serde(skip_serializing_if = "Option::is_none")]
155 pub end_time: Option<i64>,
156 #[serde(skip_serializing_if = "Option::is_none")]
157 pub limit: Option<u32>,
158}
159
160impl Default for BybitFundingParams {
161 fn default() -> Self {
162 Self {
163 category: BybitProductType::Linear,
164 symbol: String::new(),
165 start_time: None,
166 end_time: None,
167 limit: None,
168 }
169 }
170}
171
172#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
177#[builder(setter(into, strip_option), default)]
178pub struct BybitOrderbookParams {
179 pub category: BybitProductType,
180 pub symbol: String,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 pub limit: Option<u32>,
183}
184
185impl Default for BybitOrderbookParams {
186 fn default() -> Self {
187 Self {
188 category: BybitProductType::Linear,
189 symbol: String::new(),
190 limit: None,
191 }
192 }
193}
194
195#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
200#[serde(rename_all = "camelCase")]
201#[builder(default)]
202#[builder(setter(into))]
203pub struct BybitCoinInfoParams {
204 #[serde(skip_serializing_if = "Option::is_none")]
205 #[builder(setter(strip_option))]
206 pub coin: Option<String>,
207}
208
209#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
214#[serde(rename_all = "camelCase")]
215#[builder(default)]
216#[builder(setter(into))]
217pub struct BybitFeeRateParams {
218 pub category: BybitProductType,
219 #[builder(setter(strip_option))]
220 #[serde(skip_serializing_if = "Option::is_none")]
221 pub symbol: Option<String>,
222 #[builder(setter(strip_option))]
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub base_coin: Option<String>,
225}
226
227#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
232#[serde(rename_all = "camelCase")]
233pub struct BybitWalletBalanceParams {
234 pub account_type: BybitAccountType,
235 #[serde(skip_serializing_if = "Option::is_none")]
236 #[builder(setter(strip_option))]
237 pub coin: Option<String>,
238}
239
240#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
245#[serde(rename_all = "camelCase")]
246#[builder(default)]
247#[builder(setter(into))]
248pub struct BybitPositionListParams {
249 pub category: BybitProductType,
250 #[serde(skip_serializing_if = "Option::is_none")]
251 #[builder(setter(strip_option))]
252 pub symbol: Option<String>,
253 #[serde(skip_serializing_if = "Option::is_none")]
254 #[builder(setter(strip_option))]
255 pub base_coin: Option<String>,
256 #[serde(skip_serializing_if = "Option::is_none")]
257 #[builder(setter(strip_option))]
258 pub settle_coin: Option<String>,
259 #[serde(skip_serializing_if = "Option::is_none")]
260 #[builder(setter(strip_option))]
261 pub limit: Option<u32>,
262 #[serde(skip_serializing_if = "Option::is_none")]
263 #[builder(setter(strip_option))]
264 pub cursor: Option<String>,
265}
266
267#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
272#[serde(rename_all = "camelCase")]
273pub struct BybitSetMarginModeParams {
274 pub set_margin_mode: BybitMarginMode,
275}
276
277#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
282#[serde(rename_all = "camelCase")]
283pub struct BybitSetLeverageParams {
284 pub category: BybitProductType,
285 pub symbol: String,
286 pub buy_leverage: String,
287 pub sell_leverage: String,
288}
289
290#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
295#[serde(rename_all = "camelCase")]
296pub struct BybitSwitchModeParams {
297 pub category: BybitProductType,
298 #[builder(default)]
299 #[serde(skip_serializing_if = "Option::is_none")]
300 #[builder(setter(strip_option))]
301 pub symbol: Option<String>,
302 #[builder(default)]
303 #[serde(skip_serializing_if = "Option::is_none")]
304 #[builder(setter(strip_option))]
305 pub coin: Option<String>,
306 pub mode: BybitPositionMode,
307}
308
309#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
314#[serde(rename_all = "camelCase")]
315pub struct BybitSetTradingStopParams {
316 pub category: BybitProductType,
317 pub symbol: String,
318 pub position_idx: BybitPositionIdx,
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub take_profit: Option<String>,
321 #[serde(skip_serializing_if = "Option::is_none")]
322 pub stop_loss: Option<String>,
323 #[serde(skip_serializing_if = "Option::is_none")]
324 pub trailing_stop: Option<String>,
325 #[serde(skip_serializing_if = "Option::is_none")]
326 pub tp_trigger_by: Option<BybitTriggerType>,
327 #[serde(skip_serializing_if = "Option::is_none")]
328 pub sl_trigger_by: Option<BybitTriggerType>,
329 #[serde(skip_serializing_if = "Option::is_none")]
330 pub active_price: Option<String>,
331 #[serde(skip_serializing_if = "Option::is_none")]
332 pub tpsl_mode: Option<BybitTpSlMode>,
333 #[serde(skip_serializing_if = "Option::is_none")]
334 pub tp_size: Option<String>,
335 #[serde(skip_serializing_if = "Option::is_none")]
336 pub sl_size: Option<String>,
337 #[serde(skip_serializing_if = "Option::is_none")]
338 pub tp_limit_price: Option<String>,
339 #[serde(skip_serializing_if = "Option::is_none")]
340 pub sl_limit_price: Option<String>,
341 #[serde(skip_serializing_if = "Option::is_none")]
342 pub tp_order_type: Option<BybitOrderType>,
343 #[serde(skip_serializing_if = "Option::is_none")]
344 pub sl_order_type: Option<BybitOrderType>,
345}
346
347#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
353#[serde(rename_all = "camelCase")]
354pub struct BybitBorrowParams {
355 pub coin: String,
356 pub amount: String,
357}
358
359#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
365#[serde(rename_all = "camelCase")]
366pub struct BybitNoConvertRepayParams {
367 pub coin: String,
368 #[serde(skip_serializing_if = "Option::is_none")]
369 #[builder(setter(strip_option), default)]
370 pub amount: Option<String>,
371}
372
373#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
379#[serde(rename_all = "camelCase")]
380pub struct BybitRepayParams {
381 #[serde(skip_serializing_if = "Option::is_none")]
382 #[builder(setter(strip_option), default)]
383 pub coin: Option<String>,
384 #[serde(skip_serializing_if = "Option::is_none")]
385 #[builder(setter(strip_option), default)]
386 pub amount: Option<String>,
387 #[serde(skip_serializing_if = "Option::is_none")]
388 #[builder(setter(strip_option), default)]
389 pub repayment_type: Option<String>,
390}
391
392#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
397#[serde(rename_all = "camelCase")]
398pub struct BybitBatchPlaceOrderEntry {
399 pub symbol: String,
400 #[builder(default)]
401 #[serde(skip_serializing_if = "Option::is_none")]
402 pub is_leverage: Option<i32>,
403 pub side: BybitOrderSide,
404 pub order_type: BybitOrderType,
405 pub qty: String,
406 #[builder(default)]
407 #[serde(skip_serializing_if = "Option::is_none")]
408 pub price: Option<String>,
409 #[builder(default)]
410 #[serde(skip_serializing_if = "Option::is_none")]
411 pub market_unit: Option<BybitMarketUnit>,
412 #[builder(default)]
413 #[serde(skip_serializing_if = "Option::is_none")]
414 pub trigger_direction: Option<BybitTriggerDirection>,
415 #[builder(default)]
416 #[serde(skip_serializing_if = "Option::is_none")]
417 pub order_filter: Option<BybitOrderFilter>,
418 #[builder(default)]
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub trigger_price: Option<String>,
421 #[builder(default)]
422 #[serde(skip_serializing_if = "Option::is_none")]
423 pub trigger_by: Option<BybitTriggerType>,
424 #[builder(default)]
425 #[serde(skip_serializing_if = "Option::is_none")]
426 pub order_iv: Option<String>,
427 #[builder(default)]
428 #[serde(skip_serializing_if = "Option::is_none")]
429 pub time_in_force: Option<BybitTimeInForce>,
430 #[builder(default)]
431 #[serde(skip_serializing_if = "Option::is_none")]
432 pub position_idx: Option<BybitPositionIdx>,
433 #[builder(default)]
434 #[serde(skip_serializing_if = "Option::is_none")]
435 #[builder(setter(strip_option))]
436 pub order_link_id: Option<String>,
437 #[builder(default)]
438 #[serde(skip_serializing_if = "Option::is_none")]
439 pub take_profit: Option<String>,
440 #[builder(default)]
441 #[serde(skip_serializing_if = "Option::is_none")]
442 pub stop_loss: Option<String>,
443 #[builder(default)]
444 #[serde(skip_serializing_if = "Option::is_none")]
445 pub tp_trigger_by: Option<BybitTriggerType>,
446 #[builder(default)]
447 #[serde(skip_serializing_if = "Option::is_none")]
448 pub sl_trigger_by: Option<BybitTriggerType>,
449 #[builder(default)]
450 #[serde(skip_serializing_if = "Option::is_none")]
451 pub reduce_only: Option<bool>,
452 #[builder(default)]
453 #[serde(skip_serializing_if = "Option::is_none")]
454 pub close_on_trigger: Option<bool>,
455 #[builder(default)]
456 #[serde(skip_serializing_if = "Option::is_none")]
457 pub smp_type: Option<BybitSmpType>,
458 #[builder(default)]
459 #[serde(skip_serializing_if = "Option::is_none")]
460 pub mmp: Option<bool>,
461 #[builder(default)]
462 #[serde(skip_serializing_if = "Option::is_none")]
463 pub tpsl_mode: Option<BybitTpSlMode>,
464 #[builder(default)]
465 #[serde(skip_serializing_if = "Option::is_none")]
466 pub tp_limit_price: Option<String>,
467 #[builder(default)]
468 #[serde(skip_serializing_if = "Option::is_none")]
469 pub sl_limit_price: Option<String>,
470 #[builder(default)]
471 #[serde(skip_serializing_if = "Option::is_none")]
472 pub tp_order_type: Option<BybitOrderType>,
473 #[builder(default)]
474 #[serde(skip_serializing_if = "Option::is_none")]
475 pub sl_order_type: Option<BybitOrderType>,
476 #[builder(default)]
477 #[serde(skip_serializing_if = "Option::is_none")]
478 pub bbo_side_type: Option<BybitBboSideType>,
479 #[builder(default)]
480 #[serde(skip_serializing_if = "Option::is_none")]
481 pub bbo_level: Option<String>,
482}
483
484#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
489#[serde(rename_all = "camelCase")]
490pub struct BybitBatchPlaceOrderParams {
491 pub category: BybitProductType,
492 pub request: Vec<BybitBatchPlaceOrderEntry>,
493}
494
495#[derive(Debug, Clone, Default)]
506pub struct BybitNativeTpSlParams {
507 pub take_profit: Option<String>,
508 pub stop_loss: Option<String>,
509 pub tp_trigger_by: Option<BybitTriggerType>,
510 pub sl_trigger_by: Option<BybitTriggerType>,
511 pub tp_order_type: Option<BybitOrderType>,
512 pub sl_order_type: Option<BybitOrderType>,
513 pub tp_limit_price: Option<String>,
514 pub sl_limit_price: Option<String>,
515 pub tpsl_mode: Option<BybitTpSlMode>,
516 pub close_on_trigger: Option<bool>,
517 pub order_iv: Option<String>,
518 pub mmp: Option<bool>,
519}
520
521impl BybitNativeTpSlParams {
522 #[must_use]
524 pub fn is_empty(&self) -> bool {
525 self.take_profit.is_none()
526 && self.stop_loss.is_none()
527 && self.tp_trigger_by.is_none()
528 && self.sl_trigger_by.is_none()
529 && self.tp_order_type.is_none()
530 && self.sl_order_type.is_none()
531 && self.tp_limit_price.is_none()
532 && self.sl_limit_price.is_none()
533 && self.tpsl_mode.is_none()
534 && self.close_on_trigger.is_none()
535 && self.order_iv.is_none()
536 && self.mmp.is_none()
537 }
538}
539
540#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
545#[serde(rename_all = "camelCase")]
546pub struct BybitPlaceOrderParams {
547 #[serde(flatten)]
548 pub order: BybitBatchPlaceOrderEntry,
549 pub category: BybitProductType,
550 #[builder(default)]
551 #[serde(skip_serializing_if = "Option::is_none")]
552 pub slippage_tolerance_type: Option<String>,
553 #[builder(default)]
554 #[serde(skip_serializing_if = "Option::is_none")]
555 pub slippage_tolerance: Option<String>,
556}
557
558#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
563#[serde(rename_all = "camelCase")]
564pub struct BybitBatchAmendOrderEntry {
565 pub symbol: String,
566 #[builder(default)]
567 #[serde(skip_serializing_if = "Option::is_none")]
568 #[builder(setter(strip_option))]
569 pub order_id: Option<String>,
570 #[builder(default)]
571 #[serde(skip_serializing_if = "Option::is_none")]
572 #[builder(setter(strip_option))]
573 pub order_link_id: Option<String>,
574 #[builder(default)]
575 #[serde(skip_serializing_if = "Option::is_none")]
576 pub order_iv: Option<String>,
577 #[builder(default)]
578 #[serde(skip_serializing_if = "Option::is_none")]
579 pub trigger_price: Option<String>,
580 #[builder(default)]
581 #[serde(skip_serializing_if = "Option::is_none")]
582 pub qty: Option<String>,
583 #[builder(default)]
584 #[serde(skip_serializing_if = "Option::is_none")]
585 pub price: Option<String>,
586 #[builder(default)]
587 #[serde(skip_serializing_if = "Option::is_none")]
588 pub tpsl_mode: Option<BybitTpSlMode>,
589 #[builder(default)]
590 #[serde(skip_serializing_if = "Option::is_none")]
591 pub take_profit: Option<String>,
592 #[builder(default)]
593 #[serde(skip_serializing_if = "Option::is_none")]
594 pub stop_loss: Option<String>,
595 #[builder(default)]
596 #[serde(skip_serializing_if = "Option::is_none")]
597 pub tp_trigger_by: Option<BybitTriggerType>,
598 #[builder(default)]
599 #[serde(skip_serializing_if = "Option::is_none")]
600 pub sl_trigger_by: Option<BybitTriggerType>,
601 #[builder(default)]
602 #[serde(skip_serializing_if = "Option::is_none")]
603 pub trigger_by: Option<BybitTriggerType>,
604 #[builder(default)]
605 #[serde(skip_serializing_if = "Option::is_none")]
606 pub tp_limit_price: Option<String>,
607 #[builder(default)]
608 #[serde(skip_serializing_if = "Option::is_none")]
609 pub sl_limit_price: Option<String>,
610}
611
612#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
617#[serde(rename_all = "camelCase")]
618pub struct BybitBatchAmendOrderParams {
619 pub category: BybitProductType,
620 pub request: Vec<BybitBatchAmendOrderEntry>,
621}
622
623#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
628#[serde(rename_all = "camelCase")]
629pub struct BybitAmendOrderParams {
630 #[serde(flatten)]
631 pub order: BybitBatchAmendOrderEntry,
632 pub category: BybitProductType,
633}
634
635#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
640#[serde(rename_all = "camelCase")]
641pub struct BybitBatchCancelOrderEntry {
642 pub symbol: String,
643 #[builder(default)]
644 #[serde(skip_serializing_if = "Option::is_none")]
645 #[builder(setter(strip_option))]
646 pub order_id: Option<String>,
647 #[builder(default)]
648 #[serde(skip_serializing_if = "Option::is_none")]
649 #[builder(setter(strip_option))]
650 pub order_link_id: Option<String>,
651 #[builder(default)]
652 #[serde(skip_serializing_if = "Option::is_none")]
653 pub order_filter: Option<BybitOrderFilter>,
654}
655
656#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
661#[serde(rename_all = "camelCase")]
662pub struct BybitBatchCancelOrderParams {
663 pub category: BybitProductType,
664 pub request: Vec<BybitBatchCancelOrderEntry>,
665}
666
667#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
672#[serde(rename_all = "camelCase")]
673pub struct BybitCancelOrderParams {
674 #[serde(flatten)]
675 pub order: BybitBatchCancelOrderEntry,
676 pub category: BybitProductType,
677}
678
679#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
684#[serde(rename_all = "camelCase")]
685#[builder(default)]
686#[builder(setter(into))]
687pub struct BybitCancelAllOrdersParams {
688 pub category: BybitProductType,
689 #[serde(skip_serializing_if = "Option::is_none")]
690 #[builder(setter(strip_option))]
691 pub symbol: Option<String>,
692 #[serde(skip_serializing_if = "Option::is_none")]
693 #[builder(setter(strip_option))]
694 pub base_coin: Option<String>,
695 #[serde(skip_serializing_if = "Option::is_none")]
696 #[builder(setter(strip_option))]
697 pub settle_coin: Option<String>,
698 #[serde(skip_serializing_if = "Option::is_none")]
699 #[builder(setter(strip_option))]
700 pub order_filter: Option<BybitOrderFilter>,
701 #[serde(skip_serializing_if = "Option::is_none")]
702 #[builder(setter(strip_option))]
703 pub stop_order_type: Option<BybitStopOrderType>,
704}
705
706#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
711#[serde(rename_all = "camelCase")]
712#[builder(default)]
713#[builder(setter(into))]
714pub struct BybitOpenOrdersParams {
715 pub category: BybitProductType,
716 #[serde(skip_serializing_if = "Option::is_none")]
717 #[builder(setter(strip_option))]
718 pub symbol: Option<String>,
719 #[serde(skip_serializing_if = "Option::is_none")]
720 #[builder(setter(strip_option))]
721 pub base_coin: Option<String>,
722 #[serde(skip_serializing_if = "Option::is_none")]
723 #[builder(setter(strip_option))]
724 pub settle_coin: Option<String>,
725 #[serde(skip_serializing_if = "Option::is_none")]
726 #[builder(setter(strip_option))]
727 pub order_id: Option<String>,
728 #[serde(skip_serializing_if = "Option::is_none")]
729 #[builder(setter(strip_option))]
730 pub order_link_id: Option<String>,
731 #[serde(skip_serializing_if = "Option::is_none")]
732 #[builder(setter(strip_option))]
733 pub open_only: Option<BybitOpenOnly>,
734 #[serde(skip_serializing_if = "Option::is_none")]
735 #[builder(setter(strip_option))]
736 pub order_filter: Option<BybitOrderFilter>,
737 #[serde(skip_serializing_if = "Option::is_none")]
738 #[builder(setter(strip_option))]
739 pub limit: Option<u32>,
740 #[serde(skip_serializing_if = "Option::is_none")]
741 #[builder(setter(strip_option))]
742 pub cursor: Option<String>,
743}
744
745#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
750#[serde(rename_all = "camelCase")]
751#[builder(default)]
752#[builder(setter(into))]
753pub struct BybitOrderHistoryParams {
754 pub category: BybitProductType,
755 #[serde(skip_serializing_if = "Option::is_none")]
756 #[builder(setter(strip_option))]
757 pub symbol: Option<String>,
758 #[serde(skip_serializing_if = "Option::is_none")]
759 #[builder(setter(strip_option))]
760 pub base_coin: Option<String>,
761 #[serde(skip_serializing_if = "Option::is_none")]
762 #[builder(setter(strip_option))]
763 pub settle_coin: Option<String>,
764 #[serde(skip_serializing_if = "Option::is_none")]
765 #[builder(setter(strip_option))]
766 pub order_id: Option<String>,
767 #[serde(skip_serializing_if = "Option::is_none")]
768 #[builder(setter(strip_option))]
769 pub order_link_id: Option<String>,
770 #[serde(skip_serializing_if = "Option::is_none")]
771 #[builder(setter(strip_option))]
772 pub open_only: Option<BybitOpenOnly>,
773 #[serde(skip_serializing_if = "Option::is_none")]
774 #[builder(setter(strip_option))]
775 pub order_filter: Option<BybitOrderFilter>,
776 #[serde(skip_serializing_if = "Option::is_none")]
777 #[builder(setter(strip_option))]
778 pub order_status: Option<BybitOrderStatus>,
779 #[serde(skip_serializing_if = "Option::is_none")]
780 #[builder(setter(strip_option))]
781 pub start_time: Option<i64>,
782 #[serde(skip_serializing_if = "Option::is_none")]
783 #[serde(rename = "endTime")]
784 #[builder(setter(strip_option))]
785 pub end_time: Option<i64>,
786 #[serde(skip_serializing_if = "Option::is_none")]
787 #[builder(setter(strip_option))]
788 pub limit: Option<u32>,
789 #[serde(skip_serializing_if = "Option::is_none")]
790 #[builder(setter(strip_option))]
791 pub cursor: Option<String>,
792}
793
794#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
799#[serde(rename_all = "camelCase")]
800#[builder(default)]
801#[builder(setter(into))]
802pub struct BybitTradeHistoryParams {
803 pub category: BybitProductType,
804 #[serde(skip_serializing_if = "Option::is_none")]
805 #[builder(setter(strip_option))]
806 pub symbol: Option<String>,
807 #[serde(skip_serializing_if = "Option::is_none")]
808 #[builder(setter(strip_option))]
809 pub base_coin: Option<String>,
810 #[serde(skip_serializing_if = "Option::is_none")]
811 #[builder(setter(strip_option))]
812 pub order_id: Option<String>,
813 #[serde(skip_serializing_if = "Option::is_none")]
814 #[builder(setter(strip_option))]
815 pub order_link_id: Option<String>,
816 #[serde(skip_serializing_if = "Option::is_none")]
817 #[builder(setter(strip_option))]
818 pub start_time: Option<i64>,
819 #[serde(skip_serializing_if = "Option::is_none")]
820 #[serde(rename = "endTime")]
821 #[builder(setter(strip_option))]
822 pub end_time: Option<i64>,
823 #[serde(skip_serializing_if = "Option::is_none")]
824 #[builder(setter(strip_option))]
825 pub exec_type: Option<BybitExecType>,
826 #[serde(skip_serializing_if = "Option::is_none")]
827 #[builder(setter(strip_option))]
828 pub limit: Option<u32>,
829 #[serde(skip_serializing_if = "Option::is_none")]
830 #[builder(setter(strip_option))]
831 pub cursor: Option<String>,
832}
833
834#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
853#[serde(rename_all = "PascalCase")]
854#[builder(default)]
855#[builder(setter(into, strip_option))]
856pub struct BybitApiKeyPermissionUpdate {
857 #[serde(skip_serializing_if = "Option::is_none")]
858 pub contract_trade: Option<Vec<String>>,
859 #[serde(skip_serializing_if = "Option::is_none")]
860 pub spot: Option<Vec<String>>,
861 #[serde(skip_serializing_if = "Option::is_none")]
862 pub wallet: Option<Vec<String>>,
863 #[serde(skip_serializing_if = "Option::is_none")]
864 pub options: Option<Vec<String>>,
865 #[serde(skip_serializing_if = "Option::is_none")]
866 pub derivatives: Option<Vec<String>>,
867 #[serde(skip_serializing_if = "Option::is_none")]
868 pub exchange: Option<Vec<String>>,
869 #[serde(skip_serializing_if = "Option::is_none")]
870 pub earn: Option<Vec<String>>,
871 #[serde(skip_serializing_if = "Option::is_none")]
872 pub affiliate: Option<Vec<String>>,
873 #[serde(skip_serializing_if = "Option::is_none")]
874 pub block_trade: Option<Vec<String>>,
875 #[serde(skip_serializing_if = "Option::is_none")]
876 pub copy_trading: Option<Vec<String>>,
877 #[serde(rename = "NFT", skip_serializing_if = "Option::is_none")]
880 pub nft: Option<Vec<String>>,
881 #[serde(rename = "FiatP2P", skip_serializing_if = "Option::is_none")]
883 pub fiat_p2p: Option<Vec<String>>,
884 #[serde(skip_serializing_if = "Option::is_none")]
885 pub fiat_bybit_pay: Option<Vec<String>>,
886 #[serde(skip_serializing_if = "Option::is_none")]
887 pub fiat_bit_pay: Option<Vec<String>>,
888 #[serde(skip_serializing_if = "Option::is_none")]
889 pub fiat_convert_broker: Option<Vec<String>>,
890 #[serde(skip_serializing_if = "Option::is_none")]
891 pub bit_card: Option<Vec<String>>,
892 #[serde(rename = "ByXPost", skip_serializing_if = "Option::is_none")]
894 pub byx_post: Option<Vec<String>>,
895}
896
897#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
905#[serde(rename_all = "camelCase")]
906#[builder(default)]
907#[builder(setter(into))]
908pub struct BybitUpdateSubApiParams {
909 #[serde(skip_serializing_if = "Option::is_none")]
910 #[builder(setter(strip_option))]
911 pub api_key: Option<String>,
912 #[serde(skip_serializing_if = "Option::is_none", with = "opt_bool_as_int")]
915 #[builder(setter(strip_option))]
916 pub read_only: Option<bool>,
917 #[serde(skip_serializing_if = "Option::is_none")]
918 #[builder(setter(strip_option))]
919 pub ips: Option<String>,
920 #[serde(skip_serializing_if = "Option::is_none")]
921 #[builder(setter(strip_option))]
922 pub permissions: Option<BybitApiKeyPermissionUpdate>,
923}
924
925#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
936#[serde(rename_all = "camelCase")]
937#[builder(default)]
938#[builder(setter(into))]
939pub struct BybitUpdateMasterApiParams {
940 #[serde(skip_serializing_if = "Option::is_none", with = "opt_bool_as_int")]
941 #[builder(setter(strip_option))]
942 pub read_only: Option<bool>,
943 #[serde(skip_serializing_if = "Option::is_none")]
944 #[builder(setter(strip_option))]
945 pub permissions: Option<BybitApiKeyPermissionUpdate>,
946}
947
948#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
960#[serde(rename_all = "camelCase")]
961#[builder(default)]
962#[builder(setter(into))]
963pub struct BybitSubMembersPageParams {
964 #[serde(skip_serializing_if = "Option::is_none")]
965 #[builder(setter(strip_option))]
966 pub page_size: Option<u32>,
967 #[serde(skip_serializing_if = "Option::is_none")]
968 #[builder(setter(strip_option))]
969 pub next_cursor: Option<String>,
970}
971
972#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
981#[serde(rename_all = "camelCase")]
982#[builder(setter(into))]
983pub struct BybitSubApiKeysParams {
984 pub sub_member_id: String,
985 #[serde(skip_serializing_if = "Option::is_none")]
986 #[builder(setter(strip_option), default)]
987 pub limit: Option<u32>,
988 #[serde(skip_serializing_if = "Option::is_none")]
989 #[builder(setter(strip_option), default)]
990 pub cursor: Option<String>,
991}
992
993#[cfg(test)]
994mod tests {
995 use rstest::rstest;
996
997 use super::*;
998
999 #[rstest]
1000 fn test_amend_entry_builds_with_only_order_id() {
1001 let entry = BybitBatchAmendOrderEntryBuilder::default()
1002 .symbol("ETHUSDT".to_string())
1003 .order_id("12345".to_string())
1004 .price(Some("1600.0".to_string()))
1005 .build()
1006 .expect("amend entry should build with only order_id");
1007
1008 assert_eq!(entry.order_id.as_deref(), Some("12345"));
1009 assert_eq!(entry.order_link_id, None);
1010 }
1011
1012 #[rstest]
1013 fn test_amend_entry_builds_with_only_order_link_id() {
1014 let entry = BybitBatchAmendOrderEntryBuilder::default()
1015 .symbol("ETHUSDT".to_string())
1016 .order_link_id("link-1".to_string())
1017 .qty(Some("0.02".to_string()))
1018 .build()
1019 .expect("amend entry should build with only order_link_id");
1020
1021 assert_eq!(entry.order_link_id.as_deref(), Some("link-1"));
1022 assert_eq!(entry.order_id, None);
1023 }
1024
1025 #[rstest]
1026 fn test_amend_entry_builds_with_no_identifiers() {
1027 let entry = BybitBatchAmendOrderEntryBuilder::default()
1028 .symbol("ETHUSDT".to_string())
1029 .price(Some("1600.0".to_string()))
1030 .build()
1031 .expect("amend entry optional identifiers default to None");
1032
1033 assert_eq!(entry.order_id, None);
1034 assert_eq!(entry.order_link_id, None);
1035 }
1036
1037 #[rstest]
1038 fn test_cancel_entry_builds_with_only_order_id() {
1039 let entry = BybitBatchCancelOrderEntryBuilder::default()
1040 .symbol("ETHUSDT".to_string())
1041 .order_id("12345".to_string())
1042 .build()
1043 .expect("cancel entry should build with only order_id");
1044
1045 assert_eq!(entry.order_id.as_deref(), Some("12345"));
1046 assert_eq!(entry.order_link_id, None);
1047 }
1048
1049 #[rstest]
1050 fn test_cancel_entry_builds_with_only_order_link_id() {
1051 let entry = BybitBatchCancelOrderEntryBuilder::default()
1052 .symbol("ETHUSDT".to_string())
1053 .order_link_id("link-1".to_string())
1054 .build()
1055 .expect("cancel entry should build with only order_link_id");
1056
1057 assert_eq!(entry.order_link_id.as_deref(), Some("link-1"));
1058 assert_eq!(entry.order_id, None);
1059 }
1060}