deribit_base/
constants.rs1pub const DERIBIT_WS_URL_PROD: &str = "wss://www.deribit.com/ws/api/v2";
19
20pub const DERIBIT_WS_URL_TEST: &str = "wss://test.deribit.com/ws/api/v2";
22
23pub const DERIBIT_HTTP_URL_PROD: &str = "https://www.deribit.com/api/v2";
25
26pub const DERIBIT_HTTP_URL_TEST: &str = "https://test.deribit.com/api/v2";
28
29pub const MAX_REQUESTS_PER_SECOND_AUTH: u32 = 20;
35
36pub const MAX_REQUESTS_PER_SECOND_UNAUTH: u32 = 10;
38
39pub const MAX_SUBSCRIPTIONS_PER_CONNECTION: u32 = 200;
41
42pub const MAX_MESSAGE_SIZE_BYTES: usize = 65536; pub const DEFAULT_CONNECTION_TIMEOUT_MS: u64 = 5000;
51
52pub const DEFAULT_REQUEST_TIMEOUT_MS: u64 = 10000;
54
55pub const HEARTBEAT_INTERVAL_MS: u64 = 10000;
57
58pub const HEARTBEAT_TIMEOUT_MS: u64 = 5000;
60
61pub const SUPPORTED_CRYPTOCURRENCIES: &[&str] = &["BTC", "ETH", "SOL", "USDC", "USDT", "EURR"];
67
68pub const CURRENCY_BTC: &str = "BTC";
70
71pub const CURRENCY_ETH: &str = "ETH";
73
74pub const CURRENCY_SOL: &str = "SOL";
76
77pub const CURRENCY_USDC: &str = "USDC";
79
80pub const CURRENCY_USDT: &str = "USDT";
82
83pub const CURRENCY_EURR: &str = "EURR";
85
86pub const INSTRUMENT_TYPE_FUTURE: &str = "future";
92
93pub const INSTRUMENT_TYPE_OPTION: &str = "option";
95
96pub const INSTRUMENT_TYPE_PERPETUAL: &str = "perpetual";
98
99pub const INSTRUMENT_TYPE_SPOT: &str = "spot";
101
102pub const INSTRUMENT_TYPE_FUTURE_COMBO: &str = "future_combo";
104
105pub const INSTRUMENT_TYPE_OPTION_COMBO: &str = "option_combo";
107
108pub const MIN_ORDER_AMOUNT_BTC: f64 = 0.0001;
114
115pub const MIN_ORDER_AMOUNT_ETH: f64 = 0.001;
117
118pub const MIN_ORDER_AMOUNT_SOL: f64 = 0.1;
120
121pub const MAX_ORDER_AMOUNT: f64 = 1_000_000.0;
123
124pub const MAX_OPEN_ORDERS_PER_INSTRUMENT: u32 = 500;
126
127pub const MAX_OPEN_ORDERS_TOTAL: u32 = 2000;
129
130pub const PRICE_PRECISION_BTC: u8 = 8;
136
137pub const PRICE_PRECISION_ETH: u8 = 4;
139
140pub const PRICE_PRECISION_SOL: u8 = 4;
142
143pub const AMOUNT_PRECISION_BTC: u8 = 4;
145
146pub const AMOUNT_PRECISION_ETH: u8 = 3;
148
149pub const AMOUNT_PRECISION_SOL: u8 = 1;
151
152pub const JSONRPC_VERSION: &str = "2.0";
158
159pub const DEFAULT_REQUEST_ID: u64 = 1;
161
162pub const CHANNEL_BOOK: &str = "book";
168
169pub const CHANNEL_TRADES: &str = "trades";
171
172pub const CHANNEL_TICKER: &str = "ticker";
174
175pub const CHANNEL_QUOTE: &str = "quote";
177
178pub const CHANNEL_USER_ORDERS: &str = "user.orders";
180
181pub const CHANNEL_USER_TRADES: &str = "user.trades";
183
184pub const CHANNEL_USER_PORTFOLIO: &str = "user.portfolio";
186
187pub const FIX_VERSION: &str = "FIX.4.4";
193
194pub const FIX_DELIMITER: char = '\x01';
196
197pub const FIX_DELIMITER_STR: &str = "\x01";
199
200pub const FIX_HEARTBEAT_INTERVAL: u32 = 30;
202
203pub const MAX_RETRY_ATTEMPTS: u8 = 3;
209
210pub const RETRY_BASE_DELAY_MS: u64 = 1000;
212
213pub const RETRY_MAX_DELAY_MS: u64 = 30000;
215
216pub const MAX_ORDER_BOOK_DEPTH: u32 = 10000;
222
223pub const DEFAULT_ORDER_BOOK_DEPTH: u32 = 20;
225
226pub const MAX_RECENT_TRADES: u32 = 10000;
228
229pub const DEFAULT_RECENT_TRADES: u32 = 100;
231
232pub const ACCESS_TOKEN_EXPIRATION_SEC: u64 = 28800;
238
239pub const REFRESH_TOKEN_EXPIRATION_SEC: u64 = 2592000;
241
242pub const TOKEN_REFRESH_BUFFER_SEC: u64 = 300;
244
245pub fn get_min_order_amount(currency: &str) -> f64 {
251 match currency {
252 CURRENCY_BTC => MIN_ORDER_AMOUNT_BTC,
253 CURRENCY_ETH => MIN_ORDER_AMOUNT_ETH,
254 CURRENCY_SOL => MIN_ORDER_AMOUNT_SOL,
255 _ => MIN_ORDER_AMOUNT_BTC, }
257}
258
259pub fn get_price_precision(currency: &str) -> u8 {
261 match currency {
262 CURRENCY_BTC => PRICE_PRECISION_BTC,
263 CURRENCY_ETH => PRICE_PRECISION_ETH,
264 CURRENCY_SOL => PRICE_PRECISION_SOL,
265 _ => PRICE_PRECISION_BTC, }
267}
268
269pub fn get_amount_precision(currency: &str) -> u8 {
271 match currency {
272 CURRENCY_BTC => AMOUNT_PRECISION_BTC,
273 CURRENCY_ETH => AMOUNT_PRECISION_ETH,
274 CURRENCY_SOL => AMOUNT_PRECISION_SOL,
275 _ => AMOUNT_PRECISION_BTC, }
277}
278
279pub fn is_supported_currency(currency: &str) -> bool {
281 matches!(
282 currency,
283 CURRENCY_BTC | CURRENCY_ETH | CURRENCY_SOL | CURRENCY_USDC | CURRENCY_USDT | CURRENCY_EURR
284 )
285}
286
287#[cfg(test)]
288mod tests {
289 use super::*;
290
291 #[test]
292 fn test_api_urls() {
293 assert!(DERIBIT_WS_URL_PROD.starts_with("wss://"));
294 assert!(DERIBIT_WS_URL_TEST.starts_with("wss://"));
295 assert!(DERIBIT_HTTP_URL_PROD.starts_with("https://"));
296 assert!(DERIBIT_HTTP_URL_TEST.starts_with("https://"));
297
298 assert!(DERIBIT_WS_URL_PROD.contains("www.deribit.com"));
299 assert!(DERIBIT_WS_URL_TEST.contains("test.deribit.com"));
300 }
301
302 #[test]
303 fn test_supported_currencies() {
304 assert!(is_supported_currency(CURRENCY_BTC));
305 assert!(is_supported_currency(CURRENCY_ETH));
306 assert!(is_supported_currency(CURRENCY_SOL));
307 assert!(is_supported_currency(CURRENCY_USDC));
308 assert!(is_supported_currency(CURRENCY_USDT));
309 assert!(is_supported_currency(CURRENCY_EURR));
310
311 assert!(!is_supported_currency("INVALID"));
312 assert!(!is_supported_currency("XRP"));
313 }
314
315 #[test]
316 fn test_min_order_amounts() {
317 assert_eq!(get_min_order_amount(CURRENCY_BTC), MIN_ORDER_AMOUNT_BTC);
318 assert_eq!(get_min_order_amount(CURRENCY_ETH), MIN_ORDER_AMOUNT_ETH);
319 assert_eq!(get_min_order_amount(CURRENCY_SOL), MIN_ORDER_AMOUNT_SOL);
320
321 assert_eq!(get_min_order_amount("UNKNOWN"), MIN_ORDER_AMOUNT_BTC);
323 }
324
325 #[test]
326 fn test_precision_functions() {
327 assert_eq!(get_price_precision(CURRENCY_BTC), PRICE_PRECISION_BTC);
328 assert_eq!(get_price_precision(CURRENCY_ETH), PRICE_PRECISION_ETH);
329 assert_eq!(get_price_precision(CURRENCY_SOL), PRICE_PRECISION_SOL);
330
331 assert_eq!(get_amount_precision(CURRENCY_BTC), AMOUNT_PRECISION_BTC);
332 assert_eq!(get_amount_precision(CURRENCY_ETH), AMOUNT_PRECISION_ETH);
333 assert_eq!(get_amount_precision(CURRENCY_SOL), AMOUNT_PRECISION_SOL);
334 }
335
336 #[test]
337 fn test_rate_limits() {
338 #[allow(clippy::assertions_on_constants)]
340 {
341 assert!(MAX_REQUESTS_PER_SECOND_AUTH > MAX_REQUESTS_PER_SECOND_UNAUTH);
342 assert!(MAX_SUBSCRIPTIONS_PER_CONNECTION > 0);
343 assert!(MAX_MESSAGE_SIZE_BYTES > 0);
344 }
345
346 assert_eq!(MAX_REQUESTS_PER_SECOND_AUTH, 20);
348 assert_eq!(MAX_REQUESTS_PER_SECOND_UNAUTH, 10);
349 assert_eq!(MAX_SUBSCRIPTIONS_PER_CONNECTION, 200);
350 assert_eq!(MAX_MESSAGE_SIZE_BYTES, 65536);
351 }
352
353 #[test]
354 fn test_timeouts() {
355 #[allow(clippy::assertions_on_constants)]
357 {
358 assert!(DEFAULT_CONNECTION_TIMEOUT_MS > 0);
359 assert!(DEFAULT_REQUEST_TIMEOUT_MS > DEFAULT_CONNECTION_TIMEOUT_MS);
360 assert!(HEARTBEAT_INTERVAL_MS > HEARTBEAT_TIMEOUT_MS);
361 }
362
363 assert_eq!(DEFAULT_CONNECTION_TIMEOUT_MS, 5000);
365 assert_eq!(DEFAULT_REQUEST_TIMEOUT_MS, 10000);
366 assert_eq!(HEARTBEAT_INTERVAL_MS, 10000);
367 assert_eq!(HEARTBEAT_TIMEOUT_MS, 5000);
368 }
369
370 #[test]
371 fn test_order_limits() {
372 #[allow(clippy::assertions_on_constants)]
374 {
375 assert!(MIN_ORDER_AMOUNT_BTC > 0.0);
376 assert!(MIN_ORDER_AMOUNT_ETH > 0.0);
377 assert!(MIN_ORDER_AMOUNT_SOL > 0.0);
378 assert!(MAX_ORDER_AMOUNT > MIN_ORDER_AMOUNT_BTC);
379 assert!(MAX_OPEN_ORDERS_TOTAL > MAX_OPEN_ORDERS_PER_INSTRUMENT);
380 }
381
382 assert_eq!(get_min_order_amount(CURRENCY_BTC), MIN_ORDER_AMOUNT_BTC);
384 assert_eq!(get_min_order_amount(CURRENCY_ETH), MIN_ORDER_AMOUNT_ETH);
385 assert_eq!(get_min_order_amount(CURRENCY_SOL), MIN_ORDER_AMOUNT_SOL);
386 }
387
388 #[test]
389 fn test_jsonrpc_constants() {
390 assert_eq!(JSONRPC_VERSION, "2.0");
391
392 #[allow(clippy::assertions_on_constants)]
394 {
395 assert!(DEFAULT_REQUEST_ID > 0);
396 }
397
398 assert_eq!(DEFAULT_REQUEST_ID, 1);
400 }
401
402 #[test]
403 fn test_fix_constants() {
404 assert_eq!(FIX_VERSION, "FIX.4.4");
405 assert_eq!(FIX_DELIMITER, '\x01');
406 assert_eq!(FIX_DELIMITER_STR, "\x01");
407
408 #[allow(clippy::assertions_on_constants)]
410 {
411 assert!(FIX_HEARTBEAT_INTERVAL > 0);
412 }
413
414 assert_eq!(FIX_HEARTBEAT_INTERVAL, 30);
416 }
417
418 #[test]
419 fn test_channel_names() {
420 #[allow(clippy::const_is_empty)]
422 {
423 assert!(!CHANNEL_BOOK.is_empty());
424 assert!(!CHANNEL_TRADES.is_empty());
425 assert!(!CHANNEL_TICKER.is_empty());
426 assert!(!CHANNEL_QUOTE.is_empty());
427 }
428
429 assert_eq!(CHANNEL_BOOK, "book");
431 assert_eq!(CHANNEL_TRADES, "trades");
432 assert_eq!(CHANNEL_TICKER, "ticker");
433 assert_eq!(CHANNEL_QUOTE, "quote");
434
435 assert!(CHANNEL_USER_ORDERS.starts_with("user."));
437 assert!(CHANNEL_USER_TRADES.starts_with("user."));
438 assert!(CHANNEL_USER_PORTFOLIO.starts_with("user."));
439 }
440
441 #[test]
442 fn test_instrument_types() {
443 let types = [
444 INSTRUMENT_TYPE_FUTURE,
445 INSTRUMENT_TYPE_OPTION,
446 INSTRUMENT_TYPE_PERPETUAL,
447 INSTRUMENT_TYPE_SPOT,
448 INSTRUMENT_TYPE_FUTURE_COMBO,
449 INSTRUMENT_TYPE_OPTION_COMBO,
450 ];
451
452 for instrument_type in types {
453 assert!(!instrument_type.is_empty());
454 }
455 }
456
457 #[test]
458 fn test_authentication_constants() {
459 #[allow(clippy::assertions_on_constants)]
461 {
462 assert!(ACCESS_TOKEN_EXPIRATION_SEC > 0);
463 assert!(REFRESH_TOKEN_EXPIRATION_SEC > ACCESS_TOKEN_EXPIRATION_SEC);
464 assert!(TOKEN_REFRESH_BUFFER_SEC < ACCESS_TOKEN_EXPIRATION_SEC);
465 }
466
467 assert_eq!(ACCESS_TOKEN_EXPIRATION_SEC, 28800); assert_eq!(REFRESH_TOKEN_EXPIRATION_SEC, 2592000); assert_eq!(TOKEN_REFRESH_BUFFER_SEC, 300); }
472
473 #[test]
474 fn test_market_data_constants() {
475 #[allow(clippy::assertions_on_constants)]
477 {
478 assert!(MAX_ORDER_BOOK_DEPTH > DEFAULT_ORDER_BOOK_DEPTH);
479 assert!(MAX_RECENT_TRADES > DEFAULT_RECENT_TRADES);
480 assert!(DEFAULT_ORDER_BOOK_DEPTH > 0);
481 assert!(DEFAULT_RECENT_TRADES > 0);
482 }
483
484 assert_eq!(MAX_ORDER_BOOK_DEPTH, 10000);
486 assert_eq!(DEFAULT_ORDER_BOOK_DEPTH, 20);
487 assert_eq!(MAX_RECENT_TRADES, 10000);
488 assert_eq!(DEFAULT_RECENT_TRADES, 100);
489 }
490
491 #[test]
492 fn test_error_handling_constants() {
493 #[allow(clippy::assertions_on_constants)]
495 {
496 assert!(MAX_RETRY_ATTEMPTS > 0);
497 assert!(RETRY_BASE_DELAY_MS > 0);
498 assert!(RETRY_MAX_DELAY_MS > RETRY_BASE_DELAY_MS);
499 }
500
501 assert_eq!(MAX_RETRY_ATTEMPTS, 3);
503 assert_eq!(RETRY_BASE_DELAY_MS, 1000);
504 assert_eq!(RETRY_MAX_DELAY_MS, 30000);
505 }
506}