deribit_websocket/message/
request.rs1use crate::model::{quote::*, trading::*, ws_types::JsonRpcRequest};
4
5#[derive(Debug, Clone)]
7pub struct RequestBuilder {
8 id_counter: u64,
9}
10
11impl Default for RequestBuilder {
12 fn default() -> Self {
13 Self::new()
14 }
15}
16
17impl RequestBuilder {
18 pub fn new() -> Self {
20 Self { id_counter: 1 }
21 }
22
23 pub fn build_request(
25 &mut self,
26 method: &str,
27 params: Option<serde_json::Value>,
28 ) -> JsonRpcRequest {
29 let id = self.id_counter;
30 self.id_counter += 1;
31
32 JsonRpcRequest {
33 jsonrpc: "2.0".to_string(),
34 id: serde_json::Value::Number(serde_json::Number::from(id)),
35 method: method.to_string(),
36 params,
37 }
38 }
39
40 pub fn build_auth_request(&mut self, client_id: &str, client_secret: &str) -> JsonRpcRequest {
42 let params = serde_json::json!({
43 "grant_type": "client_credentials",
44 "client_id": client_id,
45 "client_secret": client_secret
46 });
47
48 self.build_request("public/auth", Some(params))
49 }
50
51 pub fn build_subscribe_request(&mut self, channels: Vec<String>) -> JsonRpcRequest {
53 let params = serde_json::json!({
54 "channels": channels
55 });
56
57 self.build_request("public/subscribe", Some(params))
58 }
59
60 pub fn build_unsubscribe_request(&mut self, channels: Vec<String>) -> JsonRpcRequest {
62 let params = serde_json::json!({
63 "channels": channels
64 });
65
66 self.build_request("public/unsubscribe", Some(params))
67 }
68
69 pub fn build_public_unsubscribe_all_request(&mut self) -> JsonRpcRequest {
77 self.build_request(
78 crate::constants::methods::PUBLIC_UNSUBSCRIBE_ALL,
79 Some(serde_json::json!({})),
80 )
81 }
82
83 pub fn build_private_unsubscribe_all_request(&mut self) -> JsonRpcRequest {
92 self.build_request(
93 crate::constants::methods::PRIVATE_UNSUBSCRIBE_ALL,
94 Some(serde_json::json!({})),
95 )
96 }
97
98 pub fn build_test_request(&mut self) -> JsonRpcRequest {
100 self.build_request(crate::constants::methods::PUBLIC_TEST, None)
101 }
102
103 pub fn build_set_heartbeat_request(&mut self, interval: u64) -> JsonRpcRequest {
116 let params = serde_json::json!({
117 "interval": interval
118 });
119 self.build_request(
120 crate::constants::methods::PUBLIC_SET_HEARTBEAT,
121 Some(params),
122 )
123 }
124
125 pub fn build_disable_heartbeat_request(&mut self) -> JsonRpcRequest {
134 self.build_request(
135 crate::constants::methods::PUBLIC_DISABLE_HEARTBEAT,
136 Some(serde_json::json!({})),
137 )
138 }
139
140 pub fn build_hello_request(
154 &mut self,
155 client_name: &str,
156 client_version: &str,
157 ) -> JsonRpcRequest {
158 let params = serde_json::json!({
159 "client_name": client_name,
160 "client_version": client_version
161 });
162 self.build_request(crate::constants::methods::PUBLIC_HELLO, Some(params))
163 }
164
165 pub fn build_get_time_request(&mut self) -> JsonRpcRequest {
167 self.build_request("public/get_time", None)
168 }
169
170 pub fn build_enable_cancel_on_disconnect_request(&mut self) -> JsonRpcRequest {
180 self.build_request(
181 crate::constants::methods::PRIVATE_ENABLE_CANCEL_ON_DISCONNECT,
182 Some(serde_json::json!({})),
183 )
184 }
185
186 pub fn build_disable_cancel_on_disconnect_request(&mut self) -> JsonRpcRequest {
195 self.build_request(
196 crate::constants::methods::PRIVATE_DISABLE_CANCEL_ON_DISCONNECT,
197 Some(serde_json::json!({})),
198 )
199 }
200
201 pub fn build_get_cancel_on_disconnect_request(&mut self) -> JsonRpcRequest {
209 self.build_request(
210 crate::constants::methods::PRIVATE_GET_CANCEL_ON_DISCONNECT,
211 Some(serde_json::json!({})),
212 )
213 }
214
215 pub fn build_mass_quote_request(&mut self, request: MassQuoteRequest) -> JsonRpcRequest {
217 let params = serde_json::to_value(request).expect("Failed to serialize mass quote request");
218
219 self.build_request("private/mass_quote", Some(params))
220 }
221
222 pub fn build_cancel_quotes_request(&mut self, request: CancelQuotesRequest) -> JsonRpcRequest {
224 let params =
225 serde_json::to_value(request).expect("Failed to serialize cancel quotes request");
226
227 self.build_request("private/cancel_quotes", Some(params))
228 }
229
230 pub fn build_set_mmp_config_request(&mut self, config: MmpGroupConfig) -> JsonRpcRequest {
232 let mut params = serde_json::json!({
233 "mmp_group": config.mmp_group,
234 "quantity_limit": config.quantity_limit,
235 "delta_limit": config.delta_limit,
236 "interval": config.interval,
237 "frozen_time": config.frozen_time
238 });
239
240 if config.interval == 0 {
242 params["interval"] = serde_json::Value::Number(serde_json::Number::from(0));
243 }
244
245 self.build_request("private/set_mmp_config", Some(params))
246 }
247
248 pub fn build_get_mmp_config_request(&mut self, mmp_group: Option<String>) -> JsonRpcRequest {
250 let params = if let Some(group) = mmp_group {
251 serde_json::json!({
252 "mmp_group": group
253 })
254 } else {
255 serde_json::json!({})
256 };
257
258 self.build_request("private/get_mmp_config", Some(params))
259 }
260
261 pub fn build_reset_mmp_request(&mut self, mmp_group: Option<String>) -> JsonRpcRequest {
263 let params = if let Some(group) = mmp_group {
264 serde_json::json!({
265 "mmp_group": group
266 })
267 } else {
268 serde_json::json!({})
269 };
270
271 self.build_request("private/reset_mmp", Some(params))
272 }
273
274 pub fn build_get_open_orders_request(
276 &mut self,
277 currency: Option<String>,
278 kind: Option<String>,
279 type_filter: Option<String>,
280 ) -> JsonRpcRequest {
281 let mut params = serde_json::json!({});
282
283 if let Some(currency) = currency {
284 params["currency"] = serde_json::Value::String(currency);
285 }
286 if let Some(kind) = kind {
287 params["kind"] = serde_json::Value::String(kind);
288 }
289 if let Some(type_filter) = type_filter {
290 params["type"] = serde_json::Value::String(type_filter);
291 }
292
293 self.build_request("private/get_open_orders", Some(params))
294 }
295
296 pub fn build_buy_request(&mut self, request: &OrderRequest) -> JsonRpcRequest {
298 let mut params = serde_json::json!({
299 "instrument_name": request.instrument_name,
300 "amount": request.amount
301 });
302
303 if let Some(ref order_type) = request.order_type {
304 params["type"] = serde_json::Value::String(order_type.as_str().to_string());
305 }
306 if let Some(price) = request.price {
307 params["price"] = serde_json::Value::Number(
308 serde_json::Number::from_f64(price).unwrap_or(serde_json::Number::from(0)),
309 );
310 }
311 if let Some(ref label) = request.label {
312 params["label"] = serde_json::Value::String(label.clone());
313 }
314 if let Some(ref tif) = request.time_in_force {
315 params["time_in_force"] = serde_json::Value::String(tif.as_str().to_string());
316 }
317 if let Some(max_show) = request.max_show {
318 params["max_show"] = serde_json::Value::Number(
319 serde_json::Number::from_f64(max_show).unwrap_or(serde_json::Number::from(0)),
320 );
321 }
322 if let Some(post_only) = request.post_only {
323 params["post_only"] = serde_json::Value::Bool(post_only);
324 }
325 if let Some(reduce_only) = request.reduce_only {
326 params["reduce_only"] = serde_json::Value::Bool(reduce_only);
327 }
328 if let Some(trigger_price) = request.trigger_price {
329 params["trigger_price"] = serde_json::Value::Number(
330 serde_json::Number::from_f64(trigger_price).unwrap_or(serde_json::Number::from(0)),
331 );
332 }
333 if let Some(ref trigger) = request.trigger {
334 let trigger_str = match trigger {
335 Trigger::IndexPrice => "index_price",
336 Trigger::MarkPrice => "mark_price",
337 Trigger::LastPrice => "last_price",
338 };
339 params["trigger"] = serde_json::Value::String(trigger_str.to_string());
340 }
341 if let Some(ref advanced) = request.advanced {
342 params["advanced"] = serde_json::Value::String(advanced.clone());
343 }
344 if let Some(mmp) = request.mmp {
345 params["mmp"] = serde_json::Value::Bool(mmp);
346 }
347 if let Some(valid_until) = request.valid_until {
348 params["valid_until"] =
349 serde_json::Value::Number(serde_json::Number::from(valid_until));
350 }
351
352 self.build_request("private/buy", Some(params))
353 }
354
355 pub fn build_sell_request(&mut self, request: &OrderRequest) -> JsonRpcRequest {
357 let mut params = serde_json::json!({
358 "instrument_name": request.instrument_name,
359 "amount": request.amount
360 });
361
362 if let Some(ref order_type) = request.order_type {
363 params["type"] = serde_json::Value::String(order_type.as_str().to_string());
364 }
365 if let Some(price) = request.price {
366 params["price"] = serde_json::Value::Number(
367 serde_json::Number::from_f64(price).unwrap_or(serde_json::Number::from(0)),
368 );
369 }
370 if let Some(ref label) = request.label {
371 params["label"] = serde_json::Value::String(label.clone());
372 }
373 if let Some(ref tif) = request.time_in_force {
374 params["time_in_force"] = serde_json::Value::String(tif.as_str().to_string());
375 }
376 if let Some(max_show) = request.max_show {
377 params["max_show"] = serde_json::Value::Number(
378 serde_json::Number::from_f64(max_show).unwrap_or(serde_json::Number::from(0)),
379 );
380 }
381 if let Some(post_only) = request.post_only {
382 params["post_only"] = serde_json::Value::Bool(post_only);
383 }
384 if let Some(reduce_only) = request.reduce_only {
385 params["reduce_only"] = serde_json::Value::Bool(reduce_only);
386 }
387 if let Some(trigger_price) = request.trigger_price {
388 params["trigger_price"] = serde_json::Value::Number(
389 serde_json::Number::from_f64(trigger_price).unwrap_or(serde_json::Number::from(0)),
390 );
391 }
392 if let Some(ref trigger) = request.trigger {
393 let trigger_str = match trigger {
394 Trigger::IndexPrice => "index_price",
395 Trigger::MarkPrice => "mark_price",
396 Trigger::LastPrice => "last_price",
397 };
398 params["trigger"] = serde_json::Value::String(trigger_str.to_string());
399 }
400 if let Some(ref advanced) = request.advanced {
401 params["advanced"] = serde_json::Value::String(advanced.clone());
402 }
403 if let Some(mmp) = request.mmp {
404 params["mmp"] = serde_json::Value::Bool(mmp);
405 }
406 if let Some(valid_until) = request.valid_until {
407 params["valid_until"] =
408 serde_json::Value::Number(serde_json::Number::from(valid_until));
409 }
410
411 self.build_request("private/sell", Some(params))
412 }
413
414 pub fn build_cancel_request(&mut self, order_id: &str) -> JsonRpcRequest {
416 let params = serde_json::json!({
417 "order_id": order_id
418 });
419
420 self.build_request("private/cancel", Some(params))
421 }
422
423 pub fn build_cancel_all_request(&mut self) -> JsonRpcRequest {
425 self.build_request("private/cancel_all", Some(serde_json::json!({})))
426 }
427
428 pub fn build_cancel_all_by_currency_request(&mut self, currency: &str) -> JsonRpcRequest {
430 let params = serde_json::json!({
431 "currency": currency
432 });
433
434 self.build_request("private/cancel_all_by_currency", Some(params))
435 }
436
437 pub fn build_cancel_all_by_instrument_request(
439 &mut self,
440 instrument_name: &str,
441 ) -> JsonRpcRequest {
442 let params = serde_json::json!({
443 "instrument_name": instrument_name
444 });
445
446 self.build_request("private/cancel_all_by_instrument", Some(params))
447 }
448
449 pub fn build_edit_request(&mut self, request: &EditOrderRequest) -> JsonRpcRequest {
451 let mut params = serde_json::json!({
452 "order_id": request.order_id,
453 "amount": request.amount
454 });
455
456 if let Some(price) = request.price {
457 params["price"] = serde_json::Value::Number(
458 serde_json::Number::from_f64(price).unwrap_or(serde_json::Number::from(0)),
459 );
460 }
461 if let Some(post_only) = request.post_only {
462 params["post_only"] = serde_json::Value::Bool(post_only);
463 }
464 if let Some(reduce_only) = request.reduce_only {
465 params["reduce_only"] = serde_json::Value::Bool(reduce_only);
466 }
467 if let Some(ref advanced) = request.advanced {
468 params["advanced"] = serde_json::Value::String(advanced.clone());
469 }
470 if let Some(trigger_price) = request.trigger_price {
471 params["trigger_price"] = serde_json::Value::Number(
472 serde_json::Number::from_f64(trigger_price).unwrap_or(serde_json::Number::from(0)),
473 );
474 }
475 if let Some(mmp) = request.mmp {
476 params["mmp"] = serde_json::Value::Bool(mmp);
477 }
478 if let Some(valid_until) = request.valid_until {
479 params["valid_until"] =
480 serde_json::Value::Number(serde_json::Number::from(valid_until));
481 }
482
483 self.build_request("private/edit", Some(params))
484 }
485
486 pub fn build_get_positions_request(
499 &mut self,
500 currency: Option<&str>,
501 kind: Option<&str>,
502 ) -> JsonRpcRequest {
503 let mut params = serde_json::Map::new();
504
505 if let Some(currency) = currency {
506 params.insert(
507 "currency".to_string(),
508 serde_json::Value::String(currency.to_string()),
509 );
510 }
511
512 if let Some(kind) = kind {
513 params.insert(
514 "kind".to_string(),
515 serde_json::Value::String(kind.to_string()),
516 );
517 }
518
519 if params.is_empty() {
520 self.build_request(crate::constants::methods::PRIVATE_GET_POSITIONS, None)
521 } else {
522 self.build_request(
523 crate::constants::methods::PRIVATE_GET_POSITIONS,
524 Some(serde_json::Value::Object(params)),
525 )
526 }
527 }
528
529 pub fn build_get_account_summary_request(
540 &mut self,
541 currency: &str,
542 extended: Option<bool>,
543 ) -> JsonRpcRequest {
544 let mut params = serde_json::Map::new();
545 params.insert(
546 "currency".to_string(),
547 serde_json::Value::String(currency.to_string()),
548 );
549
550 if let Some(extended) = extended {
551 params.insert("extended".to_string(), serde_json::Value::Bool(extended));
552 }
553
554 self.build_request(
555 crate::constants::methods::PRIVATE_GET_ACCOUNT_SUMMARY,
556 Some(serde_json::Value::Object(params)),
557 )
558 }
559
560 pub fn build_get_order_state_request(&mut self, order_id: &str) -> JsonRpcRequest {
570 let params = serde_json::json!({
571 "order_id": order_id
572 });
573
574 self.build_request(
575 crate::constants::methods::PRIVATE_GET_ORDER_STATE,
576 Some(params),
577 )
578 }
579
580 pub fn build_get_order_history_by_currency_request(
592 &mut self,
593 currency: &str,
594 kind: Option<&str>,
595 count: Option<u32>,
596 ) -> JsonRpcRequest {
597 let mut params = serde_json::Map::new();
598 params.insert(
599 "currency".to_string(),
600 serde_json::Value::String(currency.to_string()),
601 );
602
603 if let Some(kind) = kind {
604 params.insert(
605 "kind".to_string(),
606 serde_json::Value::String(kind.to_string()),
607 );
608 }
609
610 if let Some(count) = count {
611 params.insert(
612 "count".to_string(),
613 serde_json::Value::Number(serde_json::Number::from(count)),
614 );
615 }
616
617 self.build_request(
618 crate::constants::methods::PRIVATE_GET_ORDER_HISTORY_BY_CURRENCY,
619 Some(serde_json::Value::Object(params)),
620 )
621 }
622
623 pub fn build_close_position_request(
637 &mut self,
638 instrument_name: &str,
639 order_type: &str,
640 price: Option<f64>,
641 ) -> JsonRpcRequest {
642 let mut params = serde_json::Map::new();
643 params.insert(
644 "instrument_name".to_string(),
645 serde_json::Value::String(instrument_name.to_string()),
646 );
647 params.insert(
648 "type".to_string(),
649 serde_json::Value::String(order_type.to_string()),
650 );
651
652 if let Some(price) = price
653 && let Some(price_num) = serde_json::Number::from_f64(price)
654 {
655 params.insert("price".to_string(), serde_json::Value::Number(price_num));
656 }
657
658 self.build_request(
659 crate::constants::methods::PRIVATE_CLOSE_POSITION,
660 Some(serde_json::Value::Object(params)),
661 )
662 }
663
664 pub fn build_move_positions_request(
677 &mut self,
678 currency: &str,
679 source_uid: u64,
680 target_uid: u64,
681 trades: &[crate::model::MovePositionTrade],
682 ) -> JsonRpcRequest {
683 let trades_json: Vec<serde_json::Value> = trades
684 .iter()
685 .map(|t| {
686 let mut trade_obj = serde_json::Map::new();
687 trade_obj.insert(
688 "instrument_name".to_string(),
689 serde_json::Value::String(t.instrument_name.clone()),
690 );
691 if let Some(amount_num) = serde_json::Number::from_f64(t.amount) {
692 trade_obj.insert("amount".to_string(), serde_json::Value::Number(amount_num));
693 }
694 if let Some(price) = t.price
695 && let Some(price_num) = serde_json::Number::from_f64(price)
696 {
697 trade_obj.insert("price".to_string(), serde_json::Value::Number(price_num));
698 }
699 serde_json::Value::Object(trade_obj)
700 })
701 .collect();
702
703 let params = serde_json::json!({
704 "currency": currency,
705 "source_uid": source_uid,
706 "target_uid": target_uid,
707 "trades": trades_json
708 });
709
710 self.build_request(
711 crate::constants::methods::PRIVATE_MOVE_POSITIONS,
712 Some(params),
713 )
714 }
715}