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)]
378#[serde(rename_all = "camelCase")]
379pub struct BybitBatchPlaceOrderEntry {
380 pub symbol: String,
381 #[builder(default)]
382 #[serde(skip_serializing_if = "Option::is_none")]
383 pub is_leverage: Option<i32>,
384 pub side: BybitOrderSide,
385 pub order_type: BybitOrderType,
386 pub qty: String,
387 #[builder(default)]
388 #[serde(skip_serializing_if = "Option::is_none")]
389 pub price: Option<String>,
390 #[builder(default)]
391 #[serde(skip_serializing_if = "Option::is_none")]
392 pub market_unit: Option<BybitMarketUnit>,
393 #[builder(default)]
394 #[serde(skip_serializing_if = "Option::is_none")]
395 pub trigger_direction: Option<BybitTriggerDirection>,
396 #[builder(default)]
397 #[serde(skip_serializing_if = "Option::is_none")]
398 pub order_filter: Option<BybitOrderFilter>,
399 #[builder(default)]
400 #[serde(skip_serializing_if = "Option::is_none")]
401 pub trigger_price: Option<String>,
402 #[builder(default)]
403 #[serde(skip_serializing_if = "Option::is_none")]
404 pub trigger_by: Option<BybitTriggerType>,
405 #[builder(default)]
406 #[serde(skip_serializing_if = "Option::is_none")]
407 pub order_iv: Option<String>,
408 #[builder(default)]
409 #[serde(skip_serializing_if = "Option::is_none")]
410 pub time_in_force: Option<BybitTimeInForce>,
411 #[builder(default)]
412 #[serde(skip_serializing_if = "Option::is_none")]
413 pub position_idx: Option<BybitPositionIdx>,
414 #[builder(default)]
415 #[serde(skip_serializing_if = "Option::is_none")]
416 #[builder(setter(strip_option))]
417 pub order_link_id: Option<String>,
418 #[builder(default)]
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub take_profit: Option<String>,
421 #[builder(default)]
422 #[serde(skip_serializing_if = "Option::is_none")]
423 pub stop_loss: Option<String>,
424 #[builder(default)]
425 #[serde(skip_serializing_if = "Option::is_none")]
426 pub tp_trigger_by: Option<BybitTriggerType>,
427 #[builder(default)]
428 #[serde(skip_serializing_if = "Option::is_none")]
429 pub sl_trigger_by: Option<BybitTriggerType>,
430 #[builder(default)]
431 #[serde(skip_serializing_if = "Option::is_none")]
432 pub reduce_only: Option<bool>,
433 #[builder(default)]
434 #[serde(skip_serializing_if = "Option::is_none")]
435 pub close_on_trigger: Option<bool>,
436 #[builder(default)]
437 #[serde(skip_serializing_if = "Option::is_none")]
438 pub smp_type: Option<BybitSmpType>,
439 #[builder(default)]
440 #[serde(skip_serializing_if = "Option::is_none")]
441 pub mmp: Option<bool>,
442 #[builder(default)]
443 #[serde(skip_serializing_if = "Option::is_none")]
444 pub tpsl_mode: Option<BybitTpSlMode>,
445 #[builder(default)]
446 #[serde(skip_serializing_if = "Option::is_none")]
447 pub tp_limit_price: Option<String>,
448 #[builder(default)]
449 #[serde(skip_serializing_if = "Option::is_none")]
450 pub sl_limit_price: Option<String>,
451 #[builder(default)]
452 #[serde(skip_serializing_if = "Option::is_none")]
453 pub tp_order_type: Option<BybitOrderType>,
454 #[builder(default)]
455 #[serde(skip_serializing_if = "Option::is_none")]
456 pub sl_order_type: Option<BybitOrderType>,
457 #[builder(default)]
458 #[serde(skip_serializing_if = "Option::is_none")]
459 pub bbo_side_type: Option<BybitBboSideType>,
460 #[builder(default)]
461 #[serde(skip_serializing_if = "Option::is_none")]
462 pub bbo_level: Option<String>,
463}
464
465#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
470#[serde(rename_all = "camelCase")]
471pub struct BybitBatchPlaceOrderParams {
472 pub category: BybitProductType,
473 pub request: Vec<BybitBatchPlaceOrderEntry>,
474}
475
476#[derive(Debug, Clone, Default)]
487pub struct BybitNativeTpSlParams {
488 pub take_profit: Option<String>,
489 pub stop_loss: Option<String>,
490 pub tp_trigger_by: Option<BybitTriggerType>,
491 pub sl_trigger_by: Option<BybitTriggerType>,
492 pub tp_order_type: Option<BybitOrderType>,
493 pub sl_order_type: Option<BybitOrderType>,
494 pub tp_limit_price: Option<String>,
495 pub sl_limit_price: Option<String>,
496 pub tpsl_mode: Option<BybitTpSlMode>,
497 pub close_on_trigger: Option<bool>,
498 pub order_iv: Option<String>,
499 pub mmp: Option<bool>,
500}
501
502impl BybitNativeTpSlParams {
503 #[must_use]
505 pub fn is_empty(&self) -> bool {
506 self.take_profit.is_none()
507 && self.stop_loss.is_none()
508 && self.tp_trigger_by.is_none()
509 && self.sl_trigger_by.is_none()
510 && self.tp_order_type.is_none()
511 && self.sl_order_type.is_none()
512 && self.tp_limit_price.is_none()
513 && self.sl_limit_price.is_none()
514 && self.tpsl_mode.is_none()
515 && self.close_on_trigger.is_none()
516 && self.order_iv.is_none()
517 && self.mmp.is_none()
518 }
519}
520
521#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
526#[serde(rename_all = "camelCase")]
527pub struct BybitPlaceOrderParams {
528 #[serde(flatten)]
529 pub order: BybitBatchPlaceOrderEntry,
530 pub category: BybitProductType,
531 #[builder(default)]
532 #[serde(skip_serializing_if = "Option::is_none")]
533 pub slippage_tolerance_type: Option<String>,
534 #[builder(default)]
535 #[serde(skip_serializing_if = "Option::is_none")]
536 pub slippage_tolerance: Option<String>,
537}
538
539#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
544#[serde(rename_all = "camelCase")]
545pub struct BybitBatchAmendOrderEntry {
546 pub symbol: String,
547 #[builder(default)]
548 #[serde(skip_serializing_if = "Option::is_none")]
549 #[builder(setter(strip_option))]
550 pub order_id: Option<String>,
551 #[builder(default)]
552 #[serde(skip_serializing_if = "Option::is_none")]
553 #[builder(setter(strip_option))]
554 pub order_link_id: Option<String>,
555 #[builder(default)]
556 #[serde(skip_serializing_if = "Option::is_none")]
557 pub order_iv: Option<String>,
558 #[builder(default)]
559 #[serde(skip_serializing_if = "Option::is_none")]
560 pub trigger_price: Option<String>,
561 #[builder(default)]
562 #[serde(skip_serializing_if = "Option::is_none")]
563 pub qty: Option<String>,
564 #[builder(default)]
565 #[serde(skip_serializing_if = "Option::is_none")]
566 pub price: Option<String>,
567 #[builder(default)]
568 #[serde(skip_serializing_if = "Option::is_none")]
569 pub tpsl_mode: Option<BybitTpSlMode>,
570 #[builder(default)]
571 #[serde(skip_serializing_if = "Option::is_none")]
572 pub take_profit: Option<String>,
573 #[builder(default)]
574 #[serde(skip_serializing_if = "Option::is_none")]
575 pub stop_loss: Option<String>,
576 #[builder(default)]
577 #[serde(skip_serializing_if = "Option::is_none")]
578 pub tp_trigger_by: Option<BybitTriggerType>,
579 #[builder(default)]
580 #[serde(skip_serializing_if = "Option::is_none")]
581 pub sl_trigger_by: Option<BybitTriggerType>,
582 #[builder(default)]
583 #[serde(skip_serializing_if = "Option::is_none")]
584 pub trigger_by: Option<BybitTriggerType>,
585 #[builder(default)]
586 #[serde(skip_serializing_if = "Option::is_none")]
587 pub tp_limit_price: Option<String>,
588 #[builder(default)]
589 #[serde(skip_serializing_if = "Option::is_none")]
590 pub sl_limit_price: Option<String>,
591}
592
593#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
598#[serde(rename_all = "camelCase")]
599pub struct BybitBatchAmendOrderParams {
600 pub category: BybitProductType,
601 pub request: Vec<BybitBatchAmendOrderEntry>,
602}
603
604#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
609#[serde(rename_all = "camelCase")]
610pub struct BybitAmendOrderParams {
611 #[serde(flatten)]
612 pub order: BybitBatchAmendOrderEntry,
613 pub category: BybitProductType,
614}
615
616#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
621#[serde(rename_all = "camelCase")]
622pub struct BybitBatchCancelOrderEntry {
623 pub symbol: String,
624 #[builder(default)]
625 #[serde(skip_serializing_if = "Option::is_none")]
626 #[builder(setter(strip_option))]
627 pub order_id: Option<String>,
628 #[builder(default)]
629 #[serde(skip_serializing_if = "Option::is_none")]
630 #[builder(setter(strip_option))]
631 pub order_link_id: Option<String>,
632 #[builder(default)]
633 #[serde(skip_serializing_if = "Option::is_none")]
634 pub order_filter: Option<BybitOrderFilter>,
635}
636
637#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
642#[serde(rename_all = "camelCase")]
643pub struct BybitBatchCancelOrderParams {
644 pub category: BybitProductType,
645 pub request: Vec<BybitBatchCancelOrderEntry>,
646}
647
648#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
653#[serde(rename_all = "camelCase")]
654pub struct BybitCancelOrderParams {
655 #[serde(flatten)]
656 pub order: BybitBatchCancelOrderEntry,
657 pub category: BybitProductType,
658}
659
660#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
665#[serde(rename_all = "camelCase")]
666#[builder(default)]
667#[builder(setter(into))]
668pub struct BybitCancelAllOrdersParams {
669 pub category: BybitProductType,
670 #[serde(skip_serializing_if = "Option::is_none")]
671 #[builder(setter(strip_option))]
672 pub symbol: Option<String>,
673 #[serde(skip_serializing_if = "Option::is_none")]
674 #[builder(setter(strip_option))]
675 pub base_coin: Option<String>,
676 #[serde(skip_serializing_if = "Option::is_none")]
677 #[builder(setter(strip_option))]
678 pub settle_coin: Option<String>,
679 #[serde(skip_serializing_if = "Option::is_none")]
680 #[builder(setter(strip_option))]
681 pub order_filter: Option<BybitOrderFilter>,
682 #[serde(skip_serializing_if = "Option::is_none")]
683 #[builder(setter(strip_option))]
684 pub stop_order_type: Option<BybitStopOrderType>,
685}
686
687#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
692#[serde(rename_all = "camelCase")]
693#[builder(default)]
694#[builder(setter(into))]
695pub struct BybitOpenOrdersParams {
696 pub category: BybitProductType,
697 #[serde(skip_serializing_if = "Option::is_none")]
698 #[builder(setter(strip_option))]
699 pub symbol: Option<String>,
700 #[serde(skip_serializing_if = "Option::is_none")]
701 #[builder(setter(strip_option))]
702 pub base_coin: Option<String>,
703 #[serde(skip_serializing_if = "Option::is_none")]
704 #[builder(setter(strip_option))]
705 pub settle_coin: Option<String>,
706 #[serde(skip_serializing_if = "Option::is_none")]
707 #[builder(setter(strip_option))]
708 pub order_id: Option<String>,
709 #[serde(skip_serializing_if = "Option::is_none")]
710 #[builder(setter(strip_option))]
711 pub order_link_id: Option<String>,
712 #[serde(skip_serializing_if = "Option::is_none")]
713 #[builder(setter(strip_option))]
714 pub open_only: Option<BybitOpenOnly>,
715 #[serde(skip_serializing_if = "Option::is_none")]
716 #[builder(setter(strip_option))]
717 pub order_filter: Option<BybitOrderFilter>,
718 #[serde(skip_serializing_if = "Option::is_none")]
719 #[builder(setter(strip_option))]
720 pub limit: Option<u32>,
721 #[serde(skip_serializing_if = "Option::is_none")]
722 #[builder(setter(strip_option))]
723 pub cursor: Option<String>,
724}
725
726#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
731#[serde(rename_all = "camelCase")]
732#[builder(default)]
733#[builder(setter(into))]
734pub struct BybitOrderHistoryParams {
735 pub category: BybitProductType,
736 #[serde(skip_serializing_if = "Option::is_none")]
737 #[builder(setter(strip_option))]
738 pub symbol: Option<String>,
739 #[serde(skip_serializing_if = "Option::is_none")]
740 #[builder(setter(strip_option))]
741 pub base_coin: Option<String>,
742 #[serde(skip_serializing_if = "Option::is_none")]
743 #[builder(setter(strip_option))]
744 pub settle_coin: Option<String>,
745 #[serde(skip_serializing_if = "Option::is_none")]
746 #[builder(setter(strip_option))]
747 pub order_id: Option<String>,
748 #[serde(skip_serializing_if = "Option::is_none")]
749 #[builder(setter(strip_option))]
750 pub order_link_id: Option<String>,
751 #[serde(skip_serializing_if = "Option::is_none")]
752 #[builder(setter(strip_option))]
753 pub open_only: Option<BybitOpenOnly>,
754 #[serde(skip_serializing_if = "Option::is_none")]
755 #[builder(setter(strip_option))]
756 pub order_filter: Option<BybitOrderFilter>,
757 #[serde(skip_serializing_if = "Option::is_none")]
758 #[builder(setter(strip_option))]
759 pub order_status: Option<BybitOrderStatus>,
760 #[serde(skip_serializing_if = "Option::is_none")]
761 #[builder(setter(strip_option))]
762 pub start_time: Option<i64>,
763 #[serde(skip_serializing_if = "Option::is_none")]
764 #[serde(rename = "endTime")]
765 #[builder(setter(strip_option))]
766 pub end_time: Option<i64>,
767 #[serde(skip_serializing_if = "Option::is_none")]
768 #[builder(setter(strip_option))]
769 pub limit: Option<u32>,
770 #[serde(skip_serializing_if = "Option::is_none")]
771 #[builder(setter(strip_option))]
772 pub cursor: Option<String>,
773}
774
775#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
780#[serde(rename_all = "camelCase")]
781#[builder(default)]
782#[builder(setter(into))]
783pub struct BybitTradeHistoryParams {
784 pub category: BybitProductType,
785 #[serde(skip_serializing_if = "Option::is_none")]
786 #[builder(setter(strip_option))]
787 pub symbol: Option<String>,
788 #[serde(skip_serializing_if = "Option::is_none")]
789 #[builder(setter(strip_option))]
790 pub base_coin: Option<String>,
791 #[serde(skip_serializing_if = "Option::is_none")]
792 #[builder(setter(strip_option))]
793 pub order_id: Option<String>,
794 #[serde(skip_serializing_if = "Option::is_none")]
795 #[builder(setter(strip_option))]
796 pub order_link_id: Option<String>,
797 #[serde(skip_serializing_if = "Option::is_none")]
798 #[builder(setter(strip_option))]
799 pub start_time: Option<i64>,
800 #[serde(skip_serializing_if = "Option::is_none")]
801 #[serde(rename = "endTime")]
802 #[builder(setter(strip_option))]
803 pub end_time: Option<i64>,
804 #[serde(skip_serializing_if = "Option::is_none")]
805 #[builder(setter(strip_option))]
806 pub exec_type: Option<BybitExecType>,
807 #[serde(skip_serializing_if = "Option::is_none")]
808 #[builder(setter(strip_option))]
809 pub limit: Option<u32>,
810 #[serde(skip_serializing_if = "Option::is_none")]
811 #[builder(setter(strip_option))]
812 pub cursor: Option<String>,
813}
814
815#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
834#[serde(rename_all = "PascalCase")]
835#[builder(default)]
836#[builder(setter(into, strip_option))]
837pub struct BybitApiKeyPermissionUpdate {
838 #[serde(skip_serializing_if = "Option::is_none")]
839 pub contract_trade: Option<Vec<String>>,
840 #[serde(skip_serializing_if = "Option::is_none")]
841 pub spot: Option<Vec<String>>,
842 #[serde(skip_serializing_if = "Option::is_none")]
843 pub wallet: Option<Vec<String>>,
844 #[serde(skip_serializing_if = "Option::is_none")]
845 pub options: Option<Vec<String>>,
846 #[serde(skip_serializing_if = "Option::is_none")]
847 pub derivatives: Option<Vec<String>>,
848 #[serde(skip_serializing_if = "Option::is_none")]
849 pub exchange: Option<Vec<String>>,
850 #[serde(skip_serializing_if = "Option::is_none")]
851 pub earn: Option<Vec<String>>,
852 #[serde(skip_serializing_if = "Option::is_none")]
853 pub affiliate: Option<Vec<String>>,
854 #[serde(skip_serializing_if = "Option::is_none")]
855 pub block_trade: Option<Vec<String>>,
856 #[serde(skip_serializing_if = "Option::is_none")]
857 pub copy_trading: Option<Vec<String>>,
858 #[serde(rename = "NFT", skip_serializing_if = "Option::is_none")]
861 pub nft: Option<Vec<String>>,
862 #[serde(rename = "FiatP2P", skip_serializing_if = "Option::is_none")]
864 pub fiat_p2p: Option<Vec<String>>,
865 #[serde(skip_serializing_if = "Option::is_none")]
866 pub fiat_bybit_pay: Option<Vec<String>>,
867 #[serde(skip_serializing_if = "Option::is_none")]
868 pub fiat_bit_pay: Option<Vec<String>>,
869 #[serde(skip_serializing_if = "Option::is_none")]
870 pub fiat_convert_broker: Option<Vec<String>>,
871 #[serde(skip_serializing_if = "Option::is_none")]
872 pub bit_card: Option<Vec<String>>,
873 #[serde(rename = "ByXPost", skip_serializing_if = "Option::is_none")]
875 pub byx_post: Option<Vec<String>>,
876}
877
878#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
886#[serde(rename_all = "camelCase")]
887#[builder(default)]
888#[builder(setter(into))]
889pub struct BybitUpdateSubApiParams {
890 #[serde(skip_serializing_if = "Option::is_none")]
891 #[builder(setter(strip_option))]
892 pub api_key: Option<String>,
893 #[serde(skip_serializing_if = "Option::is_none", with = "opt_bool_as_int")]
896 #[builder(setter(strip_option))]
897 pub read_only: Option<bool>,
898 #[serde(skip_serializing_if = "Option::is_none")]
899 #[builder(setter(strip_option))]
900 pub ips: Option<String>,
901 #[serde(skip_serializing_if = "Option::is_none")]
902 #[builder(setter(strip_option))]
903 pub permissions: Option<BybitApiKeyPermissionUpdate>,
904}
905
906#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
917#[serde(rename_all = "camelCase")]
918#[builder(default)]
919#[builder(setter(into))]
920pub struct BybitUpdateMasterApiParams {
921 #[serde(skip_serializing_if = "Option::is_none", with = "opt_bool_as_int")]
922 #[builder(setter(strip_option))]
923 pub read_only: Option<bool>,
924 #[serde(skip_serializing_if = "Option::is_none")]
925 #[builder(setter(strip_option))]
926 pub permissions: Option<BybitApiKeyPermissionUpdate>,
927}
928
929#[derive(Clone, Debug, Deserialize, Serialize, Default, Builder)]
941#[serde(rename_all = "camelCase")]
942#[builder(default)]
943#[builder(setter(into))]
944pub struct BybitSubMembersPageParams {
945 #[serde(skip_serializing_if = "Option::is_none")]
946 #[builder(setter(strip_option))]
947 pub page_size: Option<u32>,
948 #[serde(skip_serializing_if = "Option::is_none")]
949 #[builder(setter(strip_option))]
950 pub next_cursor: Option<String>,
951}
952
953#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
962#[serde(rename_all = "camelCase")]
963#[builder(setter(into))]
964pub struct BybitSubApiKeysParams {
965 pub sub_member_id: String,
966 #[serde(skip_serializing_if = "Option::is_none")]
967 #[builder(setter(strip_option), default)]
968 pub limit: Option<u32>,
969 #[serde(skip_serializing_if = "Option::is_none")]
970 #[builder(setter(strip_option), default)]
971 pub cursor: Option<String>,
972}
973
974#[cfg(test)]
975mod tests {
976 use rstest::rstest;
977
978 use super::*;
979
980 #[rstest]
981 fn test_amend_entry_builds_with_only_order_id() {
982 let entry = BybitBatchAmendOrderEntryBuilder::default()
983 .symbol("ETHUSDT".to_string())
984 .order_id("12345".to_string())
985 .price(Some("1600.0".to_string()))
986 .build()
987 .expect("amend entry should build with only order_id");
988
989 assert_eq!(entry.order_id.as_deref(), Some("12345"));
990 assert_eq!(entry.order_link_id, None);
991 }
992
993 #[rstest]
994 fn test_amend_entry_builds_with_only_order_link_id() {
995 let entry = BybitBatchAmendOrderEntryBuilder::default()
996 .symbol("ETHUSDT".to_string())
997 .order_link_id("link-1".to_string())
998 .qty(Some("0.02".to_string()))
999 .build()
1000 .expect("amend entry should build with only order_link_id");
1001
1002 assert_eq!(entry.order_link_id.as_deref(), Some("link-1"));
1003 assert_eq!(entry.order_id, None);
1004 }
1005
1006 #[rstest]
1007 fn test_amend_entry_builds_with_no_identifiers() {
1008 let entry = BybitBatchAmendOrderEntryBuilder::default()
1009 .symbol("ETHUSDT".to_string())
1010 .price(Some("1600.0".to_string()))
1011 .build()
1012 .expect("amend entry optional identifiers default to None");
1013
1014 assert_eq!(entry.order_id, None);
1015 assert_eq!(entry.order_link_id, None);
1016 }
1017
1018 #[rstest]
1019 fn test_cancel_entry_builds_with_only_order_id() {
1020 let entry = BybitBatchCancelOrderEntryBuilder::default()
1021 .symbol("ETHUSDT".to_string())
1022 .order_id("12345".to_string())
1023 .build()
1024 .expect("cancel entry should build with only order_id");
1025
1026 assert_eq!(entry.order_id.as_deref(), Some("12345"));
1027 assert_eq!(entry.order_link_id, None);
1028 }
1029
1030 #[rstest]
1031 fn test_cancel_entry_builds_with_only_order_link_id() {
1032 let entry = BybitBatchCancelOrderEntryBuilder::default()
1033 .symbol("ETHUSDT".to_string())
1034 .order_link_id("link-1".to_string())
1035 .build()
1036 .expect("cancel entry should build with only order_link_id");
1037
1038 assert_eq!(entry.order_link_id.as_deref(), Some("link-1"));
1039 assert_eq!(entry.order_id, None);
1040 }
1041}