nautilus_deribit/
config.rs1use nautilus_model::identifiers::{AccountId, TraderId};
19
20use crate::{
21 common::urls::{get_http_base_url, get_ws_url},
22 http::models::DeribitProductType,
23};
24
25#[derive(Clone, Debug)]
27pub struct DeribitDataClientConfig {
28 pub api_key: Option<String>,
30 pub api_secret: Option<String>,
32 pub product_types: Vec<DeribitProductType>,
34 pub base_url_http: Option<String>,
36 pub base_url_ws: Option<String>,
38 pub use_testnet: bool,
40 pub http_timeout_secs: Option<u64>,
42 pub max_retries: Option<u32>,
44 pub retry_delay_initial_ms: Option<u64>,
46 pub retry_delay_max_ms: Option<u64>,
48 pub heartbeat_interval_secs: Option<u64>,
50 pub update_instruments_interval_mins: Option<u64>,
52}
53
54impl Default for DeribitDataClientConfig {
55 fn default() -> Self {
56 Self {
57 api_key: None,
58 api_secret: None,
59 product_types: vec![DeribitProductType::Future],
60 base_url_http: None,
61 base_url_ws: None,
62 use_testnet: false,
63 http_timeout_secs: Some(60),
64 max_retries: Some(3),
65 retry_delay_initial_ms: Some(1_000),
66 retry_delay_max_ms: Some(10_000),
67 heartbeat_interval_secs: Some(30),
68 update_instruments_interval_mins: Some(60),
69 }
70 }
71}
72
73impl DeribitDataClientConfig {
74 #[must_use]
76 pub fn new() -> Self {
77 Self::default()
78 }
79
80 #[must_use]
82 pub fn has_api_credentials(&self) -> bool {
83 let (key_env, secret_env) = if self.use_testnet {
84 ("DERIBIT_TESTNET_API_KEY", "DERIBIT_TESTNET_API_SECRET")
85 } else {
86 ("DERIBIT_API_KEY", "DERIBIT_API_SECRET")
87 };
88
89 let has_key = self.api_key.is_some() || std::env::var(key_env).is_ok();
90 let has_secret = self.api_secret.is_some() || std::env::var(secret_env).is_ok();
91 has_key && has_secret
92 }
93
94 #[must_use]
96 pub fn http_base_url(&self) -> String {
97 self.base_url_http
98 .clone()
99 .unwrap_or_else(|| get_http_base_url(self.use_testnet).to_string())
100 }
101
102 #[must_use]
104 pub fn ws_url(&self) -> String {
105 self.base_url_ws
106 .clone()
107 .unwrap_or_else(|| get_ws_url(self.use_testnet).to_string())
108 }
109}
110
111#[derive(Clone, Debug)]
113pub struct DeribitExecClientConfig {
114 pub trader_id: TraderId,
116 pub account_id: AccountId,
118 pub api_key: Option<String>,
120 pub api_secret: Option<String>,
122 pub product_types: Vec<DeribitProductType>,
124 pub base_url_http: Option<String>,
126 pub base_url_ws: Option<String>,
128 pub use_testnet: bool,
130 pub http_timeout_secs: Option<u64>,
132 pub max_retries: Option<u32>,
134 pub retry_delay_initial_ms: Option<u64>,
136 pub retry_delay_max_ms: Option<u64>,
138}
139
140impl Default for DeribitExecClientConfig {
141 fn default() -> Self {
142 Self {
143 trader_id: TraderId::default(),
144 account_id: AccountId::from("DERIBIT-001"),
145 api_key: None,
146 api_secret: None,
147 product_types: vec![DeribitProductType::Future],
148 base_url_http: None,
149 base_url_ws: None,
150 use_testnet: false,
151 http_timeout_secs: Some(60),
152 max_retries: Some(3),
153 retry_delay_initial_ms: Some(1_000),
154 retry_delay_max_ms: Some(10_000),
155 }
156 }
157}
158
159impl DeribitExecClientConfig {
160 #[must_use]
162 pub fn new(trader_id: TraderId, account_id: AccountId) -> Self {
163 Self {
164 trader_id,
165 account_id,
166 ..Default::default()
167 }
168 }
169
170 #[must_use]
172 pub fn has_api_credentials(&self) -> bool {
173 let (key_env, secret_env) = if self.use_testnet {
174 ("DERIBIT_TESTNET_API_KEY", "DERIBIT_TESTNET_API_SECRET")
175 } else {
176 ("DERIBIT_API_KEY", "DERIBIT_API_SECRET")
177 };
178
179 let has_key = self.api_key.is_some() || std::env::var(key_env).is_ok();
180 let has_secret = self.api_secret.is_some() || std::env::var(secret_env).is_ok();
181 has_key && has_secret
182 }
183
184 #[must_use]
186 pub fn http_base_url(&self) -> String {
187 self.base_url_http
188 .clone()
189 .unwrap_or_else(|| get_http_base_url(self.use_testnet).to_string())
190 }
191
192 #[must_use]
194 pub fn ws_url(&self) -> String {
195 self.base_url_ws
196 .clone()
197 .unwrap_or_else(|| get_ws_url(self.use_testnet).to_string())
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use rstest::rstest;
204
205 use super::*;
206
207 #[rstest]
208 fn test_default_config() {
209 let config = DeribitDataClientConfig::default();
210 assert!(!config.use_testnet);
211 assert_eq!(config.product_types.len(), 1);
212 assert_eq!(config.http_timeout_secs, Some(60));
213 }
214
215 #[rstest]
216 fn test_http_base_url_default() {
217 let config = DeribitDataClientConfig::default();
218 assert_eq!(config.http_base_url(), "https://www.deribit.com");
219 }
220
221 #[rstest]
222 fn test_http_base_url_testnet() {
223 let config = DeribitDataClientConfig {
224 use_testnet: true,
225 ..Default::default()
226 };
227 assert_eq!(config.http_base_url(), "https://test.deribit.com");
228 }
229
230 #[rstest]
231 fn test_ws_url_default() {
232 let config = DeribitDataClientConfig::default();
233 assert_eq!(config.ws_url(), "wss://www.deribit.com/ws/api/v2");
234 }
235
236 #[rstest]
237 fn test_ws_url_testnet() {
238 let config = DeribitDataClientConfig {
239 use_testnet: true,
240 ..Default::default()
241 };
242 assert_eq!(config.ws_url(), "wss://test.deribit.com/ws/api/v2");
243 }
244
245 #[rstest]
246 fn test_has_api_credentials_in_config() {
247 let config = DeribitDataClientConfig {
248 api_key: Some("test_key".to_string()),
249 api_secret: Some("test_secret".to_string()),
250 ..Default::default()
251 };
252 assert!(config.has_api_credentials());
253 }
254}