bybit/models/dcp_request.rs
1use serde::{Deserialize, Serialize};
2use std::borrow::Cow;
3
4/// Represents a request to set Disconnection Protection (DCP) parameters on Bybit.
5///
6/// Disconnection Protection (DCP) automatically cancels all active orders if the client
7/// remains disconnected from Bybit's WebSocket for longer than the specified time window.
8/// This helps prevent unintended order execution during connection issues.
9/// Bots should configure DCP based on their reconnection strategy and risk tolerance.
10#[derive(Debug, Serialize, Deserialize, Clone, Default)]
11pub struct DcpRequest<'a> {
12 /// Product type for which DCP applies.
13 ///
14 /// Specifies which product category's orders should be cancelled on disconnection:
15 /// - `OPTIONS` (default): Options orders only
16 /// - `DERIVATIVES`: Futures and perpetual orders (Inverse Perp, Inverse Futures,
17 /// USDT Perp, USDT Futures, USDC Perp, USDC Futures)
18 /// - `SPOT`: Spot orders only
19 ///
20 /// Bots should set this based on which markets they are actively trading.
21 /// The default is "OPTIONS" if not specified.
22 #[serde(skip_serializing_if = "Option::is_none")]
23 pub product: Option<Cow<'a, str>>,
24
25 /// Disconnection timing window in seconds.
26 ///
27 /// The time window (in seconds) after disconnection before orders are cancelled.
28 /// Valid range: 3 to 300 seconds. Default is 10 seconds if not configured.
29 /// Bots should set this based on their expected reconnection time and risk appetite.
30 /// Shorter windows provide faster protection but may trigger unnecessarily during
31 /// brief network interruptions.
32 #[serde(rename = "timeWindow")]
33 pub time_window: i32,
34}
35
36impl<'a> DcpRequest<'a> {
37 /// Constructs a new DcpRequest with specified parameters.
38 ///
39 /// Creates a request to configure Disconnection Protection with a specific
40 /// time window and optional product filter.
41 ///
42 /// # Arguments
43 ///
44 /// * `time_window` - Disconnection timing window in seconds (3-300)
45 /// * `product` - Optional product type ("OPTIONS", "DERIVATIVES", or "SPOT")
46 ///
47 /// # Returns
48 ///
49 /// A new `DcpRequest` instance.
50 ///
51 /// # Panics
52 ///
53 /// This function does not panic, but Bybit API will reject time_window values
54 /// outside the 3-300 range.
55 pub fn new(time_window: i32, product: Option<&'a str>) -> Self {
56 Self {
57 product: product.map(Cow::Borrowed),
58 time_window,
59 }
60 }
61
62 /// Constructs a DcpRequest for derivatives with default 10-second window.
63 ///
64 /// Creates a request with 10-second time window for derivatives products.
65 /// This is a common configuration for futures and perpetual trading bots.
66 ///
67 /// # Returns
68 ///
69 /// A `DcpRequest` with time_window=10 and product="DERIVATIVES".
70 pub fn derivatives_default() -> Self {
71 Self {
72 product: Some(Cow::Borrowed("DERIVATIVES")),
73 time_window: 10,
74 }
75 }
76
77 /// Constructs a DcpRequest for spot with default 10-second window.
78 ///
79 /// Creates a request with 10-second time window for spot products.
80 /// This is a common configuration for spot trading bots.
81 ///
82 /// # Returns
83 ///
84 /// A `DcpRequest` with time_window=10 and product="SPOT".
85 pub fn spot_default() -> Self {
86 Self {
87 product: Some(Cow::Borrowed("SPOT")),
88 time_window: 10,
89 }
90 }
91
92 /// Constructs a DcpRequest for options with default 10-second window.
93 ///
94 /// Creates a request with 10-second time window for options products.
95 /// This is the default configuration used by Bybit.
96 ///
97 /// # Returns
98 ///
99 /// A `DcpRequest` with time_window=10 and product="OPTIONS".
100 pub fn options_default() -> Self {
101 Self {
102 product: Some(Cow::Borrowed("OPTIONS")),
103 time_window: 10,
104 }
105 }
106
107 /// Validates the DcpRequest parameters.
108 ///
109 /// Checks if the time_window is within the valid range (3-300 seconds).
110 /// Bots should call this before sending the request to avoid API errors.
111 ///
112 /// # Returns
113 ///
114 /// * `Ok(())` - If parameters are valid
115 /// * `Err(String)` - If time_window is outside valid range
116 pub fn validate(&self) -> Result<(), String> {
117 if self.time_window < 3 || self.time_window > 300 {
118 return Err(format!(
119 "time_window must be between 3 and 300 seconds, got {}",
120 self.time_window
121 ));
122 }
123 Ok(())
124 }
125}