1use crate::model::order::{OrderSide, OrderType, TimeInForce};
7use pretty_simple_display::{DebugPretty, DisplaySimple};
8
9use serde::{Deserialize, Serialize};
10
11pub mod fix {
13 use super::*;
14
15 #[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
17 pub struct NewOrderRequest {
18 pub symbol: String,
20 pub side: OrderSide,
22 pub order_type: OrderType,
24 pub quantity: f64,
26 pub price: Option<f64>,
28 pub time_in_force: TimeInForce,
30 pub client_order_id: Option<String>,
32 }
33
34 impl NewOrderRequest {
35 pub fn market_buy(symbol: String, quantity: f64) -> Self {
37 Self {
38 symbol,
39 side: OrderSide::Buy,
40 order_type: OrderType::Market,
41 quantity,
42 price: None,
43 time_in_force: TimeInForce::ImmediateOrCancel,
44 client_order_id: None,
45 }
46 }
47
48 pub fn market_sell(symbol: String, quantity: f64) -> Self {
50 Self {
51 symbol,
52 side: OrderSide::Sell,
53 order_type: OrderType::Market,
54 quantity,
55 price: None,
56 time_in_force: TimeInForce::ImmediateOrCancel,
57 client_order_id: None,
58 }
59 }
60
61 pub fn limit_buy(symbol: String, quantity: f64, price: f64) -> Self {
63 Self {
64 symbol,
65 side: OrderSide::Buy,
66 order_type: OrderType::Limit,
67 quantity,
68 price: Some(price),
69 time_in_force: TimeInForce::GoodTilCancelled,
70 client_order_id: None,
71 }
72 }
73
74 pub fn limit_sell(symbol: String, quantity: f64, price: f64) -> Self {
76 Self {
77 symbol,
78 side: OrderSide::Sell,
79 order_type: OrderType::Limit,
80 quantity,
81 price: Some(price),
82 time_in_force: TimeInForce::GoodTilCancelled,
83 client_order_id: None,
84 }
85 }
86
87 pub fn with_client_order_id(mut self, client_order_id: String) -> Self {
89 self.client_order_id = Some(client_order_id);
90 self
91 }
92
93 pub fn with_time_in_force(mut self, tif: TimeInForce) -> Self {
95 self.time_in_force = tif;
96 self
97 }
98 }
99
100 impl From<super::NewOrderRequest> for NewOrderRequest {
102 fn from(rest_order: super::NewOrderRequest) -> Self {
103 Self {
104 symbol: rest_order.instrument_name,
105 side: rest_order.side,
106 order_type: rest_order.order_type,
107 quantity: rest_order.amount,
108 price: rest_order.price,
109 time_in_force: rest_order.time_in_force,
110 client_order_id: rest_order.client_order_id,
111 }
112 }
113 }
114
115 impl From<NewOrderRequest> for super::NewOrderRequest {
117 fn from(fix_order: NewOrderRequest) -> Self {
118 Self {
119 instrument_name: fix_order.symbol,
120 amount: fix_order.quantity,
121 order_type: fix_order.order_type,
122 side: fix_order.side,
123 price: fix_order.price,
124 time_in_force: fix_order.time_in_force,
125 post_only: None,
126 reduce_only: None,
127 label: None,
128 stop_price: None,
129 trigger: None,
130 advanced: None,
131 max_show: None,
132 reject_post_only: None,
133 valid_until: None,
134 client_order_id: fix_order.client_order_id,
135 }
136 }
137 }
138}
139
140#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
142pub struct NewOrderRequest {
143 pub instrument_name: String,
145 pub amount: f64,
147 #[serde(rename = "type")]
149 pub order_type: OrderType,
150 pub side: OrderSide,
152 pub price: Option<f64>,
154 pub time_in_force: TimeInForce,
156 pub post_only: Option<bool>,
158 pub reduce_only: Option<bool>,
160 pub label: Option<String>,
162 pub stop_price: Option<f64>,
164 pub trigger: Option<TriggerType>,
166 pub advanced: Option<AdvancedOrderType>,
168 pub max_show: Option<f64>,
170 pub reject_post_only: Option<bool>,
172 pub valid_until: Option<i64>,
174 pub client_order_id: Option<String>,
176}
177
178impl NewOrderRequest {
179 pub fn market_buy(instrument_name: String, amount: f64) -> Self {
181 Self {
182 instrument_name,
183 amount,
184 order_type: OrderType::Market,
185 side: OrderSide::Buy,
186 price: None,
187 time_in_force: TimeInForce::ImmediateOrCancel,
188 post_only: None,
189 reduce_only: None,
190 label: None,
191 stop_price: None,
192 trigger: None,
193 advanced: None,
194 max_show: None,
195 reject_post_only: None,
196 valid_until: None,
197 client_order_id: None,
198 }
199 }
200
201 pub fn market_sell(instrument_name: String, amount: f64) -> Self {
203 Self {
204 instrument_name,
205 amount,
206 order_type: OrderType::Market,
207 side: OrderSide::Sell,
208 price: None,
209 time_in_force: TimeInForce::ImmediateOrCancel,
210 post_only: None,
211 reduce_only: None,
212 label: None,
213 stop_price: None,
214 trigger: None,
215 advanced: None,
216 max_show: None,
217 reject_post_only: None,
218 valid_until: None,
219 client_order_id: None,
220 }
221 }
222
223 pub fn limit_buy(instrument_name: String, amount: f64, price: f64) -> Self {
225 Self {
226 instrument_name,
227 amount,
228 order_type: OrderType::Limit,
229 side: OrderSide::Buy,
230 price: Some(price),
231 time_in_force: TimeInForce::GoodTilCancelled,
232 post_only: None,
233 reduce_only: None,
234 label: None,
235 stop_price: None,
236 trigger: None,
237 advanced: None,
238 max_show: None,
239 reject_post_only: None,
240 valid_until: None,
241 client_order_id: None,
242 }
243 }
244
245 pub fn limit_sell(instrument_name: String, amount: f64, price: f64) -> Self {
247 Self {
248 instrument_name,
249 amount,
250 order_type: OrderType::Limit,
251 side: OrderSide::Sell,
252 price: Some(price),
253 time_in_force: TimeInForce::GoodTilCancelled,
254 post_only: None,
255 reduce_only: None,
256 label: None,
257 stop_price: None,
258 trigger: None,
259 advanced: None,
260 max_show: None,
261 reject_post_only: None,
262 valid_until: None,
263 client_order_id: None,
264 }
265 }
266
267 pub fn with_post_only(mut self, post_only: bool) -> Self {
269 self.post_only = Some(post_only);
270 self
271 }
272
273 pub fn with_reduce_only(mut self, reduce_only: bool) -> Self {
275 self.reduce_only = Some(reduce_only);
276 self
277 }
278
279 pub fn with_label(mut self, label: String) -> Self {
281 self.label = Some(label);
282 self
283 }
284
285 pub fn with_time_in_force(mut self, tif: TimeInForce) -> Self {
287 self.time_in_force = tif;
288 self
289 }
290}
291
292#[derive(DebugPretty, DisplaySimple, Clone, PartialEq, Eq, Serialize, Deserialize)]
294#[serde(rename_all = "snake_case")]
295pub enum TriggerType {
296 IndexPrice,
298 MarkPrice,
300 LastPrice,
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
306#[serde(rename_all = "lowercase")]
307pub enum AdvancedOrderType {
308 Usd,
310 Implv,
312}
313
314#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
316pub struct ModifyOrderRequest {
317 pub order_id: String,
319 pub amount: Option<f64>,
321 pub price: Option<f64>,
323 pub stop_price: Option<f64>,
325 pub post_only: Option<bool>,
327 pub reduce_only: Option<bool>,
329 pub reject_post_only: Option<bool>,
331 pub advanced: Option<AdvancedOrderType>,
333}
334
335#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
337pub struct CancelOrderRequest {
338 pub order_id: String,
340}
341
342#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
344pub struct CancelAllOrdersRequest {
345 pub currency: Option<String>,
347 pub kind: Option<String>,
349 #[serde(rename = "type")]
351 pub instrument_type: Option<String>,
352}
353
354#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
356pub struct ClosePositionRequest {
357 pub instrument_name: String,
359 #[serde(rename = "type")]
361 pub order_type: OrderType,
362 pub price: Option<f64>,
364}
365
366#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
368pub struct AuthRequest {
369 pub grant_type: String,
371 pub client_id: String,
373 pub client_secret: String,
375 pub refresh_token: Option<String>,
377 pub scope: Option<String>,
379}
380
381impl AuthRequest {
382 pub fn client_credentials(client_id: String, client_secret: String) -> Self {
384 Self {
385 grant_type: "client_credentials".to_string(),
386 client_id,
387 client_secret,
388 refresh_token: None,
389 scope: None,
390 }
391 }
392
393 pub fn refresh_token(client_id: String, client_secret: String, refresh_token: String) -> Self {
395 Self {
396 grant_type: "refresh_token".to_string(),
397 client_id,
398 client_secret,
399 refresh_token: Some(refresh_token),
400 scope: None,
401 }
402 }
403}
404
405#[cfg(test)]
406mod tests {
407 use super::*;
408
409 #[test]
410 fn test_fix_new_order_request_market_buy() {
411 let order = fix::NewOrderRequest::market_buy("BTC-PERPETUAL".to_string(), 1.0);
412 assert_eq!(order.symbol, "BTC-PERPETUAL");
413 assert_eq!(order.side, OrderSide::Buy);
414 assert_eq!(order.order_type, OrderType::Market);
415 assert_eq!(order.quantity, 1.0);
416 assert_eq!(order.price, None);
417 assert_eq!(order.time_in_force, TimeInForce::ImmediateOrCancel);
418 assert_eq!(order.client_order_id, None);
419 }
420
421 #[test]
422 fn test_fix_new_order_request_market_sell() {
423 let order = fix::NewOrderRequest::market_sell("ETH-PERPETUAL".to_string(), 2.0);
424 assert_eq!(order.symbol, "ETH-PERPETUAL");
425 assert_eq!(order.side, OrderSide::Sell);
426 assert_eq!(order.order_type, OrderType::Market);
427 assert_eq!(order.quantity, 2.0);
428 assert_eq!(order.price, None);
429 assert_eq!(order.time_in_force, TimeInForce::ImmediateOrCancel);
430 }
431
432 #[test]
433 fn test_fix_new_order_request_limit_buy() {
434 let order = fix::NewOrderRequest::limit_buy("BTC-PERPETUAL".to_string(), 1.0, 50000.0);
435 assert_eq!(order.symbol, "BTC-PERPETUAL");
436 assert_eq!(order.side, OrderSide::Buy);
437 assert_eq!(order.order_type, OrderType::Limit);
438 assert_eq!(order.quantity, 1.0);
439 assert_eq!(order.price, Some(50000.0));
440 assert_eq!(order.time_in_force, TimeInForce::GoodTilCancelled);
441 }
442
443 #[test]
444 fn test_fix_new_order_request_limit_sell() {
445 let order = fix::NewOrderRequest::limit_sell("ETH-PERPETUAL".to_string(), 2.0, 3500.0);
446 assert_eq!(order.symbol, "ETH-PERPETUAL");
447 assert_eq!(order.side, OrderSide::Sell);
448 assert_eq!(order.order_type, OrderType::Limit);
449 assert_eq!(order.quantity, 2.0);
450 assert_eq!(order.price, Some(3500.0));
451 assert_eq!(order.time_in_force, TimeInForce::GoodTilCancelled);
452 }
453
454 #[test]
455 fn test_fix_new_order_request_with_client_order_id() {
456 let order = fix::NewOrderRequest::market_buy("BTC-PERPETUAL".to_string(), 1.0)
457 .with_client_order_id("CLIENT_ORDER_123".to_string());
458 assert_eq!(order.client_order_id, Some("CLIENT_ORDER_123".to_string()));
459 }
460
461 #[test]
462 fn test_fix_new_order_request_with_time_in_force() {
463 let order = fix::NewOrderRequest::limit_buy("BTC-PERPETUAL".to_string(), 1.0, 50000.0)
464 .with_time_in_force(TimeInForce::FillOrKill);
465 assert_eq!(order.time_in_force, TimeInForce::FillOrKill);
466 }
467
468 #[test]
469 fn test_new_order_request_market_buy() {
470 let order = NewOrderRequest::market_buy("BTC-PERPETUAL".to_string(), 1.0);
471 assert_eq!(order.instrument_name, "BTC-PERPETUAL");
472 assert_eq!(order.amount, 1.0);
473 assert_eq!(order.order_type, OrderType::Market);
474 assert_eq!(order.side, OrderSide::Buy);
475 assert_eq!(order.price, None);
476 assert_eq!(order.time_in_force, TimeInForce::ImmediateOrCancel);
477 assert_eq!(order.post_only, None);
478 assert_eq!(order.reduce_only, None);
479 }
480
481 #[test]
482 fn test_new_order_request_market_sell() {
483 let order = NewOrderRequest::market_sell("ETH-PERPETUAL".to_string(), 2.0);
484 assert_eq!(order.instrument_name, "ETH-PERPETUAL");
485 assert_eq!(order.amount, 2.0);
486 assert_eq!(order.order_type, OrderType::Market);
487 assert_eq!(order.side, OrderSide::Sell);
488 assert_eq!(order.price, None);
489 assert_eq!(order.time_in_force, TimeInForce::ImmediateOrCancel);
490 }
491
492 #[test]
493 fn test_new_order_request_limit_buy() {
494 let order = NewOrderRequest::limit_buy("BTC-PERPETUAL".to_string(), 1.0, 50000.0);
495 assert_eq!(order.instrument_name, "BTC-PERPETUAL");
496 assert_eq!(order.amount, 1.0);
497 assert_eq!(order.order_type, OrderType::Limit);
498 assert_eq!(order.side, OrderSide::Buy);
499 assert_eq!(order.price, Some(50000.0));
500 assert_eq!(order.time_in_force, TimeInForce::GoodTilCancelled);
501 }
502
503 #[test]
504 fn test_new_order_request_limit_sell() {
505 let order = NewOrderRequest::limit_sell("ETH-PERPETUAL".to_string(), 2.0, 3500.0);
506 assert_eq!(order.instrument_name, "ETH-PERPETUAL");
507 assert_eq!(order.amount, 2.0);
508 assert_eq!(order.order_type, OrderType::Limit);
509 assert_eq!(order.side, OrderSide::Sell);
510 assert_eq!(order.price, Some(3500.0));
511 assert_eq!(order.time_in_force, TimeInForce::GoodTilCancelled);
512 }
513
514 #[test]
515 fn test_new_order_request_with_post_only() {
516 let order = NewOrderRequest::limit_buy("BTC-PERPETUAL".to_string(), 1.0, 50000.0)
517 .with_post_only(true);
518 assert_eq!(order.post_only, Some(true));
519 }
520
521 #[test]
522 fn test_new_order_request_with_reduce_only() {
523 let order = NewOrderRequest::limit_sell("BTC-PERPETUAL".to_string(), 1.0, 50000.0)
524 .with_reduce_only(true);
525 assert_eq!(order.reduce_only, Some(true));
526 }
527
528 #[test]
529 fn test_new_order_request_with_label() {
530 let order = NewOrderRequest::market_buy("BTC-PERPETUAL".to_string(), 1.0)
531 .with_label("test_order".to_string());
532 assert_eq!(order.label, Some("test_order".to_string()));
533 }
534
535 #[test]
536 fn test_new_order_request_with_time_in_force() {
537 let order = NewOrderRequest::limit_buy("BTC-PERPETUAL".to_string(), 1.0, 50000.0)
538 .with_time_in_force(TimeInForce::FillOrKill);
539 assert_eq!(order.time_in_force, TimeInForce::FillOrKill);
540 }
541
542 #[test]
543 fn test_trigger_type_serialization() {
544 let trigger_types = vec![
545 TriggerType::IndexPrice,
546 TriggerType::MarkPrice,
547 TriggerType::LastPrice,
548 ];
549
550 for trigger_type in trigger_types {
551 let json = serde_json::to_string(&trigger_type).unwrap();
552 let deserialized: TriggerType = serde_json::from_str(&json).unwrap();
553 assert_eq!(trigger_type, deserialized);
554 }
555 }
556
557 #[test]
558 fn test_advanced_order_type_serialization() {
559 let advanced_types = vec![AdvancedOrderType::Usd, AdvancedOrderType::Implv];
560
561 for advanced_type in advanced_types {
562 let json = serde_json::to_string(&advanced_type).unwrap();
563 let deserialized: AdvancedOrderType = serde_json::from_str(&json).unwrap();
564 assert_eq!(advanced_type, deserialized);
565 }
566 }
567
568 #[test]
569 fn test_modify_order_request() {
570 let modify_request = ModifyOrderRequest {
571 order_id: "ORDER_123".to_string(),
572 amount: Some(2.0),
573 price: Some(51000.0),
574 stop_price: None,
575 post_only: Some(true),
576 reduce_only: Some(false),
577 reject_post_only: None,
578 advanced: Some(AdvancedOrderType::Usd),
579 };
580
581 assert_eq!(modify_request.order_id, "ORDER_123");
582 assert_eq!(modify_request.amount, Some(2.0));
583 assert_eq!(modify_request.price, Some(51000.0));
584 assert_eq!(modify_request.post_only, Some(true));
585 assert_eq!(modify_request.advanced, Some(AdvancedOrderType::Usd));
586 }
587
588 #[test]
589 fn test_cancel_order_request() {
590 let cancel_request = CancelOrderRequest {
591 order_id: "ORDER_123".to_string(),
592 };
593 assert_eq!(cancel_request.order_id, "ORDER_123");
594 }
595
596 #[test]
597 fn test_cancel_all_orders_request() {
598 let cancel_all_request = CancelAllOrdersRequest {
599 currency: Some("BTC".to_string()),
600 kind: Some("future".to_string()),
601 instrument_type: Some("perpetual".to_string()),
602 };
603
604 assert_eq!(cancel_all_request.currency, Some("BTC".to_string()));
605 assert_eq!(cancel_all_request.kind, Some("future".to_string()));
606 assert_eq!(
607 cancel_all_request.instrument_type,
608 Some("perpetual".to_string())
609 );
610 }
611
612 #[test]
613 fn test_cancel_all_orders_request_empty() {
614 let cancel_all_request = CancelAllOrdersRequest {
615 currency: None,
616 kind: None,
617 instrument_type: None,
618 };
619
620 assert_eq!(cancel_all_request.currency, None);
621 assert_eq!(cancel_all_request.kind, None);
622 assert_eq!(cancel_all_request.instrument_type, None);
623 }
624
625 #[test]
626 fn test_close_position_request() {
627 let close_request = ClosePositionRequest {
628 instrument_name: "BTC-PERPETUAL".to_string(),
629 order_type: OrderType::Market,
630 price: None,
631 };
632
633 assert_eq!(close_request.instrument_name, "BTC-PERPETUAL");
634 assert_eq!(close_request.order_type, OrderType::Market);
635 assert_eq!(close_request.price, None);
636
637 let close_limit_request = ClosePositionRequest {
638 instrument_name: "ETH-PERPETUAL".to_string(),
639 order_type: OrderType::Limit,
640 price: Some(3500.0),
641 };
642
643 assert_eq!(close_limit_request.price, Some(3500.0));
644 }
645
646 #[test]
647 fn test_auth_request_client_credentials() {
648 let auth_request = AuthRequest::client_credentials(
649 "client_id_123".to_string(),
650 "client_secret_456".to_string(),
651 );
652
653 assert_eq!(auth_request.grant_type, "client_credentials");
654 assert_eq!(auth_request.client_id, "client_id_123");
655 assert_eq!(auth_request.client_secret, "client_secret_456");
656 assert_eq!(auth_request.refresh_token, None);
657 assert_eq!(auth_request.scope, None);
658 }
659
660 #[test]
661 fn test_auth_request_refresh_token() {
662 let auth_request = AuthRequest::refresh_token(
663 "client_id_123".to_string(),
664 "client_secret_456".to_string(),
665 "refresh_token_789".to_string(),
666 );
667
668 assert_eq!(auth_request.grant_type, "refresh_token");
669 assert_eq!(auth_request.client_id, "client_id_123");
670 assert_eq!(auth_request.client_secret, "client_secret_456");
671 assert_eq!(
672 auth_request.refresh_token,
673 Some("refresh_token_789".to_string())
674 );
675 assert_eq!(auth_request.scope, None);
676 }
677
678 #[test]
679 fn test_fix_to_rest_conversion() {
680 let fix_order = fix::NewOrderRequest::limit_buy("BTC-PERPETUAL".to_string(), 1.0, 50000.0)
681 .with_client_order_id("CLIENT_ORDER_123".to_string());
682
683 let rest_order: NewOrderRequest = fix_order.into();
684
685 assert_eq!(rest_order.instrument_name, "BTC-PERPETUAL");
686 assert_eq!(rest_order.amount, 1.0);
687 assert_eq!(rest_order.order_type, OrderType::Limit);
688 assert_eq!(rest_order.side, OrderSide::Buy);
689 assert_eq!(rest_order.price, Some(50000.0));
690 assert_eq!(
691 rest_order.client_order_id,
692 Some("CLIENT_ORDER_123".to_string())
693 );
694 assert_eq!(rest_order.post_only, None);
695 assert_eq!(rest_order.reduce_only, None);
696 }
697
698 #[test]
699 fn test_rest_to_fix_conversion() {
700 let rest_order = NewOrderRequest::limit_sell("ETH-PERPETUAL".to_string(), 2.0, 3500.0)
701 .with_label("test_order".to_string())
702 .with_post_only(true);
703
704 let fix_order: fix::NewOrderRequest = rest_order.into();
705
706 assert_eq!(fix_order.symbol, "ETH-PERPETUAL");
707 assert_eq!(fix_order.quantity, 2.0);
708 assert_eq!(fix_order.order_type, OrderType::Limit);
709 assert_eq!(fix_order.side, OrderSide::Sell);
710 assert_eq!(fix_order.price, Some(3500.0));
711 assert_eq!(fix_order.time_in_force, TimeInForce::GoodTilCancelled);
712 }
713
714 #[test]
715 fn test_serialization_roundtrip() {
716 let order = NewOrderRequest::limit_buy("BTC-PERPETUAL".to_string(), 1.0, 50000.0)
717 .with_post_only(true)
718 .with_label("test_order".to_string());
719
720 let json = serde_json::to_string(&order).unwrap();
721 let deserialized: NewOrderRequest = serde_json::from_str(&json).unwrap();
722
723 assert_eq!(order.instrument_name, deserialized.instrument_name);
724 assert_eq!(order.amount, deserialized.amount);
725 assert_eq!(order.order_type, deserialized.order_type);
726 assert_eq!(order.side, deserialized.side);
727 assert_eq!(order.price, deserialized.price);
728 assert_eq!(order.post_only, deserialized.post_only);
729 assert_eq!(order.label, deserialized.label);
730 }
731
732 #[test]
733 fn test_debug_and_display_implementations() {
734 let order = NewOrderRequest::market_buy("BTC-PERPETUAL".to_string(), 1.0);
735 let debug_str = format!("{:?}", order);
736 let display_str = format!("{}", order);
737
738 assert!(debug_str.contains("BTC-PERPETUAL"));
739 assert!(display_str.contains("BTC-PERPETUAL"));
740
741 let auth_request =
742 AuthRequest::client_credentials("client_id".to_string(), "client_secret".to_string());
743 let auth_debug = format!("{:?}", auth_request);
744 let auth_display = format!("{}", auth_request);
745
746 assert!(auth_debug.contains("client_credentials"));
747 assert!(auth_display.contains("client_credentials"));
748 }
749
750 #[test]
751 fn test_enum_equality_and_cloning() {
752 let trigger1 = TriggerType::IndexPrice;
753 let trigger2 = trigger1.clone();
754 assert_eq!(trigger1, trigger2);
755
756 let advanced1 = AdvancedOrderType::Usd;
757 let advanced2 = advanced1.clone();
758 assert_eq!(advanced1, advanced2);
759 }
760
761 #[test]
762 fn test_complex_order_with_all_fields() {
763 let order = NewOrderRequest {
764 instrument_name: "BTC-PERPETUAL".to_string(),
765 amount: 1.5,
766 order_type: OrderType::StopLimit,
767 side: OrderSide::Buy,
768 price: Some(50000.0),
769 time_in_force: TimeInForce::GoodTilDay,
770 post_only: Some(true),
771 reduce_only: Some(false),
772 label: Some("complex_order".to_string()),
773 stop_price: Some(49000.0),
774 trigger: Some(TriggerType::MarkPrice),
775 advanced: Some(AdvancedOrderType::Implv),
776 max_show: Some(0.5),
777 reject_post_only: Some(false),
778 valid_until: Some(1640995200000),
779 client_order_id: Some("CLIENT_ORDER_COMPLEX".to_string()),
780 };
781
782 assert_eq!(order.instrument_name, "BTC-PERPETUAL");
783 assert_eq!(order.amount, 1.5);
784 assert_eq!(order.order_type, OrderType::StopLimit);
785 assert_eq!(order.stop_price, Some(49000.0));
786 assert_eq!(order.trigger, Some(TriggerType::MarkPrice));
787 assert_eq!(order.advanced, Some(AdvancedOrderType::Implv));
788 assert_eq!(order.max_show, Some(0.5));
789 assert_eq!(order.valid_until, Some(1640995200000));
790 }
791}