1use error_chain::bail;
2
3use crate::util::{build_signed_request, is_start_time_valid};
4use crate::model::{
5 AccountInformation, Balance, Empty, Order, OrderCanceled, TradeHistory, Transaction,
6};
7use crate::client::Client;
8use crate::errors::Result;
9use std::collections::BTreeMap;
10use std::fmt::Display;
11use crate::api::API;
12use crate::api::Spot;
13
14#[derive(Clone)]
15pub struct Account {
16 pub client: Client,
17 pub recv_window: u64,
18}
19
20struct OrderRequest {
21 pub symbol: String,
22 pub qty: f64,
23 pub price: f64,
24 pub stop_price: Option<f64>,
25 pub order_side: OrderSide,
26 pub order_type: OrderType,
27 pub time_in_force: TimeInForce,
28 pub new_client_order_id: Option<String>,
29}
30
31struct OrderQuoteQuantityRequest {
32 pub symbol: String,
33 pub quote_order_qty: f64,
34 pub price: f64,
35 pub order_side: OrderSide,
36 pub order_type: OrderType,
37 pub time_in_force: TimeInForce,
38 pub new_client_order_id: Option<String>,
39}
40
41pub enum OrderType {
42 Limit,
43 Market,
44 StopLossLimit,
45}
46
47impl OrderType {
48 pub fn from_int(value: i32) -> Option<Self> {
49 match value {
50 1 => Some(OrderType::Limit),
51 2 => Some(OrderType::Market),
52 3 => Some(OrderType::StopLossLimit),
53 _ => None,
54 }
55 }
56}
57
58impl Display for OrderType {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 match self {
61 Self::Limit => write!(f, "LIMIT"),
62 Self::Market => write!(f, "MARKET"),
63 Self::StopLossLimit => write!(f, "STOP_LOSS_LIMIT"),
64 }
65 }
66}
67
68pub enum OrderSide {
69 Buy,
70 Sell,
71}
72
73impl OrderSide {
74 pub fn from_int(value: i32) -> Option<Self> {
75 match value {
76 1 => Some(OrderSide::Buy),
77 2 => Some(OrderSide::Sell),
78 _ => None,
79 }
80 }
81}
82
83impl Display for OrderSide {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 match self {
86 Self::Buy => write!(f, "BUY"),
87 Self::Sell => write!(f, "SELL"),
88 }
89 }
90}
91
92#[allow(clippy::all)]
93pub enum TimeInForce {
94 GTC,
95 IOC,
96 FOK,
97}
98
99impl TimeInForce {
100 pub fn from_int(value: i32) -> Option<Self> {
101 match value {
102 1 => Some(TimeInForce::GTC),
103 2 => Some(TimeInForce::IOC),
104 3 => Some(TimeInForce::FOK),
105 _ => None,
106 }
107 }
108}
109
110impl Display for TimeInForce {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 match self {
113 Self::GTC => write!(f, "GTC"),
114 Self::IOC => write!(f, "IOC"),
115 Self::FOK => write!(f, "FOK"),
116 }
117 }
118}
119
120impl Account {
121 pub fn get_account(&self) -> Result<AccountInformation> {
123 let request = build_signed_request(BTreeMap::new(), self.recv_window)?;
124 self.client
125 .get_signed(API::Spot(Spot::Account), Some(request))
126 }
127
128 pub fn get_balance<S>(&self, asset: S) -> Result<Balance>
130 where
131 S: Into<String>,
132 {
133 match self.get_account() {
134 Ok(account) => {
135 let cmp_asset = asset.into();
136 for balance in account.balances {
137 if balance.asset == cmp_asset {
138 return Ok(balance);
139 }
140 }
141 bail!("Asset not found");
142 }
143 Err(e) => Err(e),
144 }
145 }
146
147 pub fn get_open_orders<S>(&self, symbol: S) -> Result<Vec<Order>>
149 where
150 S: Into<String>,
151 {
152 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
153 parameters.insert("symbol".into(), symbol.into());
154
155 let request = build_signed_request(parameters, self.recv_window)?;
156 self.client
157 .get_signed(API::Spot(Spot::OpenOrders), Some(request))
158 }
159
160 pub fn get_all_open_orders(&self) -> Result<Vec<Order>> {
162 let parameters: BTreeMap<String, String> = BTreeMap::new();
163
164 let request = build_signed_request(parameters, self.recv_window)?;
165 self.client
166 .get_signed(API::Spot(Spot::OpenOrders), Some(request))
167 }
168
169 pub fn cancel_all_open_orders<S>(&self, symbol: S) -> Result<Vec<OrderCanceled>>
171 where
172 S: Into<String>,
173 {
174 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
175 parameters.insert("symbol".into(), symbol.into());
176 let request = build_signed_request(parameters, self.recv_window)?;
177 self.client
178 .delete_signed(API::Spot(Spot::OpenOrders), Some(request))
179 }
180
181 pub fn order_status<S>(&self, symbol: S, order_id: u64) -> Result<Order>
183 where
184 S: Into<String>,
185 {
186 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
187 parameters.insert("symbol".into(), symbol.into());
188 parameters.insert("orderId".into(), order_id.to_string());
189
190 let request = build_signed_request(parameters, self.recv_window)?;
191 self.client
192 .get_signed(API::Spot(Spot::Order), Some(request))
193 }
194
195 pub fn test_order_status<S>(&self, symbol: S, order_id: u64) -> Result<()>
199 where
200 S: Into<String>,
201 {
202 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
203 parameters.insert("symbol".into(), symbol.into());
204 parameters.insert("orderId".into(), order_id.to_string());
205
206 let request = build_signed_request(parameters, self.recv_window)?;
207 self.client
208 .get_signed::<Empty>(API::Spot(Spot::OrderTest), Some(request))
209 .map(|_| ())
210 }
211
212 pub fn limit_buy<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<Transaction>
214 where
215 S: Into<String>,
216 F: Into<f64>,
217 {
218 let buy = OrderRequest {
219 symbol: symbol.into(),
220 qty: qty.into(),
221 price,
222 stop_price: None,
223 order_side: OrderSide::Buy,
224 order_type: OrderType::Limit,
225 time_in_force: TimeInForce::GTC,
226 new_client_order_id: None,
227 };
228 let order = self.build_order(buy);
229 let request = build_signed_request(order, self.recv_window)?;
230 self.client.post_signed(API::Spot(Spot::Order), request)
231 }
232
233 pub fn test_limit_buy<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<()>
237 where
238 S: Into<String>,
239 F: Into<f64>,
240 {
241 let buy = OrderRequest {
242 symbol: symbol.into(),
243 qty: qty.into(),
244 price,
245 stop_price: None,
246 order_side: OrderSide::Buy,
247 order_type: OrderType::Limit,
248 time_in_force: TimeInForce::GTC,
249 new_client_order_id: None,
250 };
251 let order = self.build_order(buy);
252 let request = build_signed_request(order, self.recv_window)?;
253 self.client
254 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
255 .map(|_| ())
256 }
257
258 pub fn limit_sell<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<Transaction>
260 where
261 S: Into<String>,
262 F: Into<f64>,
263 {
264 let sell = OrderRequest {
265 symbol: symbol.into(),
266 qty: qty.into(),
267 price,
268 stop_price: None,
269 order_side: OrderSide::Sell,
270 order_type: OrderType::Limit,
271 time_in_force: TimeInForce::GTC,
272 new_client_order_id: None,
273 };
274 let order = self.build_order(sell);
275 let request = build_signed_request(order, self.recv_window)?;
276 self.client.post_signed(API::Spot(Spot::Order), request)
277 }
278
279 pub fn test_limit_sell<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<()>
283 where
284 S: Into<String>,
285 F: Into<f64>,
286 {
287 let sell = OrderRequest {
288 symbol: symbol.into(),
289 qty: qty.into(),
290 price,
291 stop_price: None,
292 order_side: OrderSide::Sell,
293 order_type: OrderType::Limit,
294 time_in_force: TimeInForce::GTC,
295 new_client_order_id: None,
296 };
297 let order = self.build_order(sell);
298 let request = build_signed_request(order, self.recv_window)?;
299 self.client
300 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
301 .map(|_| ())
302 }
303
304 pub fn market_buy<S, F>(&self, symbol: S, qty: F) -> Result<Transaction>
306 where
307 S: Into<String>,
308 F: Into<f64>,
309 {
310 let buy = OrderRequest {
311 symbol: symbol.into(),
312 qty: qty.into(),
313 price: 0.0,
314 stop_price: None,
315 order_side: OrderSide::Buy,
316 order_type: OrderType::Market,
317 time_in_force: TimeInForce::GTC,
318 new_client_order_id: None,
319 };
320 let order = self.build_order(buy);
321 let request = build_signed_request(order, self.recv_window)?;
322 self.client.post_signed(API::Spot(Spot::Order), request)
323 }
324
325 pub fn test_market_buy<S, F>(&self, symbol: S, qty: F) -> Result<()>
329 where
330 S: Into<String>,
331 F: Into<f64>,
332 {
333 let buy = OrderRequest {
334 symbol: symbol.into(),
335 qty: qty.into(),
336 price: 0.0,
337 stop_price: None,
338 order_side: OrderSide::Buy,
339 order_type: OrderType::Market,
340 time_in_force: TimeInForce::GTC,
341 new_client_order_id: None,
342 };
343 let order = self.build_order(buy);
344 let request = build_signed_request(order, self.recv_window)?;
345 self.client
346 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
347 .map(|_| ())
348 }
349
350 pub fn market_buy_using_quote_quantity<S, F>(
352 &self, symbol: S, quote_order_qty: F,
353 ) -> Result<Transaction>
354 where
355 S: Into<String>,
356 F: Into<f64>,
357 {
358 let buy = OrderQuoteQuantityRequest {
359 symbol: symbol.into(),
360 quote_order_qty: quote_order_qty.into(),
361 price: 0.0,
362 order_side: OrderSide::Buy,
363 order_type: OrderType::Market,
364 time_in_force: TimeInForce::GTC,
365 new_client_order_id: None,
366 };
367 let order = self.build_quote_quantity_order(buy);
368 let request = build_signed_request(order, self.recv_window)?;
369 self.client.post_signed(API::Spot(Spot::Order), request)
370 }
371
372 pub fn test_market_buy_using_quote_quantity<S, F>(
376 &self, symbol: S, quote_order_qty: F,
377 ) -> Result<()>
378 where
379 S: Into<String>,
380 F: Into<f64>,
381 {
382 let buy = OrderQuoteQuantityRequest {
383 symbol: symbol.into(),
384 quote_order_qty: quote_order_qty.into(),
385 price: 0.0,
386 order_side: OrderSide::Buy,
387 order_type: OrderType::Market,
388 time_in_force: TimeInForce::GTC,
389 new_client_order_id: None,
390 };
391 let order = self.build_quote_quantity_order(buy);
392 let request = build_signed_request(order, self.recv_window)?;
393 self.client
394 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
395 .map(|_| ())
396 }
397
398 pub fn market_sell<S, F>(&self, symbol: S, qty: F) -> Result<Transaction>
400 where
401 S: Into<String>,
402 F: Into<f64>,
403 {
404 let sell = OrderRequest {
405 symbol: symbol.into(),
406 qty: qty.into(),
407 price: 0.0,
408 stop_price: None,
409 order_side: OrderSide::Sell,
410 order_type: OrderType::Market,
411 time_in_force: TimeInForce::GTC,
412 new_client_order_id: None,
413 };
414 let order = self.build_order(sell);
415 let request = build_signed_request(order, self.recv_window)?;
416 self.client.post_signed(API::Spot(Spot::Order), request)
417 }
418
419 pub fn test_market_sell<S, F>(&self, symbol: S, qty: F) -> Result<()>
423 where
424 S: Into<String>,
425 F: Into<f64>,
426 {
427 let sell = OrderRequest {
428 symbol: symbol.into(),
429 qty: qty.into(),
430 price: 0.0,
431 stop_price: None,
432 order_side: OrderSide::Sell,
433 order_type: OrderType::Market,
434 time_in_force: TimeInForce::GTC,
435 new_client_order_id: None,
436 };
437 let order = self.build_order(sell);
438 let request = build_signed_request(order, self.recv_window)?;
439 self.client
440 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
441 .map(|_| ())
442 }
443
444 pub fn market_sell_using_quote_quantity<S, F>(
446 &self, symbol: S, quote_order_qty: F,
447 ) -> Result<Transaction>
448 where
449 S: Into<String>,
450 F: Into<f64>,
451 {
452 let sell = OrderQuoteQuantityRequest {
453 symbol: symbol.into(),
454 quote_order_qty: quote_order_qty.into(),
455 price: 0.0,
456 order_side: OrderSide::Sell,
457 order_type: OrderType::Market,
458 time_in_force: TimeInForce::GTC,
459 new_client_order_id: None,
460 };
461 let order = self.build_quote_quantity_order(sell);
462 let request = build_signed_request(order, self.recv_window)?;
463 self.client.post_signed(API::Spot(Spot::Order), request)
464 }
465
466 pub fn test_market_sell_using_quote_quantity<S, F>(
470 &self, symbol: S, quote_order_qty: F,
471 ) -> Result<()>
472 where
473 S: Into<String>,
474 F: Into<f64>,
475 {
476 let sell = OrderQuoteQuantityRequest {
477 symbol: symbol.into(),
478 quote_order_qty: quote_order_qty.into(),
479 price: 0.0,
480 order_side: OrderSide::Sell,
481 order_type: OrderType::Market,
482 time_in_force: TimeInForce::GTC,
483 new_client_order_id: None,
484 };
485 let order = self.build_quote_quantity_order(sell);
486 let request = build_signed_request(order, self.recv_window)?;
487 self.client
488 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
489 .map(|_| ())
490 }
491
492 pub fn stop_limit_buy_order<S, F>(
507 &self, symbol: S, qty: F, price: f64, stop_price: f64, time_in_force: TimeInForce,
508 ) -> Result<Transaction>
509 where
510 S: Into<String>,
511 F: Into<f64>,
512 {
513 let sell = OrderRequest {
514 symbol: symbol.into(),
515 qty: qty.into(),
516 price,
517 stop_price: Some(stop_price),
518 order_side: OrderSide::Buy,
519 order_type: OrderType::StopLossLimit,
520 time_in_force,
521 new_client_order_id: None,
522 };
523 let order = self.build_order(sell);
524 let request = build_signed_request(order, self.recv_window)?;
525 self.client.post_signed(API::Spot(Spot::Order), request)
526 }
527
528 pub fn test_stop_limit_buy_order<S, F>(
545 &self, symbol: S, qty: F, price: f64, stop_price: f64, time_in_force: TimeInForce,
546 ) -> Result<()>
547 where
548 S: Into<String>,
549 F: Into<f64>,
550 {
551 let sell = OrderRequest {
552 symbol: symbol.into(),
553 qty: qty.into(),
554 price,
555 stop_price: Some(stop_price),
556 order_side: OrderSide::Buy,
557 order_type: OrderType::StopLossLimit,
558 time_in_force,
559 new_client_order_id: None,
560 };
561 let order = self.build_order(sell);
562 let request = build_signed_request(order, self.recv_window)?;
563 self.client
564 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
565 .map(|_| ())
566 }
567
568 pub fn stop_limit_sell_order<S, F>(
583 &self, symbol: S, qty: F, price: f64, stop_price: f64, time_in_force: TimeInForce,
584 ) -> Result<Transaction>
585 where
586 S: Into<String>,
587 F: Into<f64>,
588 {
589 let sell = OrderRequest {
590 symbol: symbol.into(),
591 qty: qty.into(),
592 price,
593 stop_price: Some(stop_price),
594 order_side: OrderSide::Sell,
595 order_type: OrderType::StopLossLimit,
596 time_in_force,
597 new_client_order_id: None,
598 };
599 let order = self.build_order(sell);
600 let request = build_signed_request(order, self.recv_window)?;
601 self.client.post_signed(API::Spot(Spot::Order), request)
602 }
603
604 pub fn test_stop_limit_sell_order<S, F>(
621 &self, symbol: S, qty: F, price: f64, stop_price: f64, time_in_force: TimeInForce,
622 ) -> Result<()>
623 where
624 S: Into<String>,
625 F: Into<f64>,
626 {
627 let sell = OrderRequest {
628 symbol: symbol.into(),
629 qty: qty.into(),
630 price,
631 stop_price: Some(stop_price),
632 order_side: OrderSide::Sell,
633 order_type: OrderType::StopLossLimit,
634 time_in_force,
635 new_client_order_id: None,
636 };
637 let order = self.build_order(sell);
638 let request = build_signed_request(order, self.recv_window)?;
639 self.client
640 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
641 .map(|_| ())
642 }
643
644 #[allow(clippy::too_many_arguments)]
646 pub fn custom_order<S, F>(
647 &self, symbol: S, qty: F, price: f64, stop_price: Option<f64>, order_side: OrderSide,
648 order_type: OrderType, time_in_force: TimeInForce, new_client_order_id: Option<String>,
649 ) -> Result<Transaction>
650 where
651 S: Into<String>,
652 F: Into<f64>,
653 {
654 let sell = OrderRequest {
655 symbol: symbol.into(),
656 qty: qty.into(),
657 price,
658 stop_price,
659 order_side,
660 order_type,
661 time_in_force,
662 new_client_order_id,
663 };
664 let order = self.build_order(sell);
665 let request = build_signed_request(order, self.recv_window)?;
666 self.client.post_signed(API::Spot(Spot::Order), request)
667 }
668
669 #[allow(clippy::too_many_arguments)]
673 pub fn test_custom_order<S, F>(
674 &self, symbol: S, qty: F, price: f64, stop_price: Option<f64>, order_side: OrderSide,
675 order_type: OrderType, time_in_force: TimeInForce, new_client_order_id: Option<String>,
676 ) -> Result<()>
677 where
678 S: Into<String>,
679 F: Into<f64>,
680 {
681 let sell = OrderRequest {
682 symbol: symbol.into(),
683 qty: qty.into(),
684 price,
685 stop_price,
686 order_side,
687 order_type,
688 time_in_force,
689 new_client_order_id,
690 };
691 let order = self.build_order(sell);
692 let request = build_signed_request(order, self.recv_window)?;
693 self.client
694 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
695 .map(|_| ())
696 }
697
698 pub fn cancel_order<S>(&self, symbol: S, order_id: u64) -> Result<OrderCanceled>
700 where
701 S: Into<String>,
702 {
703 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
704 parameters.insert("symbol".into(), symbol.into());
705 parameters.insert("orderId".into(), order_id.to_string());
706
707 let request = build_signed_request(parameters, self.recv_window)?;
708 self.client
709 .delete_signed(API::Spot(Spot::Order), Some(request))
710 }
711
712 pub fn cancel_order_with_client_id<S>(
713 &self, symbol: S, orig_client_order_id: String,
714 ) -> Result<OrderCanceled>
715 where
716 S: Into<String>,
717 {
718 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
719 parameters.insert("symbol".into(), symbol.into());
720 parameters.insert("origClientOrderId".into(), orig_client_order_id);
721
722 let request = build_signed_request(parameters, self.recv_window)?;
723 self.client
724 .delete_signed(API::Spot(Spot::Order), Some(request))
725 }
726
727 pub fn cancel_order_with_client_id_rs<S>() {}
728 pub fn test_cancel_order<S>(&self, symbol: S, order_id: u64) -> Result<()>
732 where
733 S: Into<String>,
734 {
735 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
736 parameters.insert("symbol".into(), symbol.into());
737 parameters.insert("orderId".into(), order_id.to_string());
738 let request = build_signed_request(parameters, self.recv_window)?;
739 self.client
740 .delete_signed::<Empty>(API::Spot(Spot::OrderTest), Some(request))
741 .map(|_| ())
742 }
743
744 pub fn trade_history<S>(&self, symbol: S) -> Result<Vec<TradeHistory>>
746 where
747 S: Into<String>,
748 {
749 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
750 parameters.insert("symbol".into(), symbol.into());
751
752 let request = build_signed_request(parameters, self.recv_window)?;
753 self.client
754 .get_signed(API::Spot(Spot::MyTrades), Some(request))
755 }
756
757 pub fn trade_history_from<S>(&self, symbol: S, start_time: u64) -> Result<Vec<TradeHistory>>
759 where
760 S: Into<String>,
761 {
762 if !is_start_time_valid(&start_time) {
763 return bail!("Start time should be less than the current time");
764 }
765
766 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
767 parameters.insert("symbol".into(), symbol.into());
768 parameters.insert("startTime".into(), start_time.to_string());
769 let request = build_signed_request(parameters, self.recv_window)?;
770 self.client
771 .get_signed(API::Spot(Spot::MyTrades), Some(request))
772 }
773
774 pub fn trade_history_from_to<S>(
776 &self, symbol: S, start_time: u64, end_time: u64,
777 ) -> Result<Vec<TradeHistory>>
778 where
779 S: Into<String>,
780 {
781 if end_time <= start_time {
782 return bail!("End time should be greater than start time");
783 }
784 if !is_start_time_valid(&start_time) {
785 return bail!("Start time should be less than the current time");
786 }
787 self.get_trades(symbol, start_time, end_time)
788 }
789
790 fn get_trades<S>(&self, symbol: S, start_time: u64, end_time: u64) -> Result<Vec<TradeHistory>>
791 where
792 S: Into<String>,
793 {
794 let mut trades = match self.trade_history_from(symbol, start_time) {
795 Ok(trades) => trades,
796 Err(e) => return Err(e),
797 };
798 trades.retain(|trade| trade.time <= end_time);
799 Ok(trades)
800 }
801
802 fn build_order(&self, order: OrderRequest) -> BTreeMap<String, String> {
803 let mut order_parameters: BTreeMap<String, String> = BTreeMap::new();
804
805 order_parameters.insert("symbol".into(), order.symbol);
806 order_parameters.insert("side".into(), order.order_side.to_string());
807 order_parameters.insert("type".into(), order.order_type.to_string());
808 order_parameters.insert("quantity".into(), order.qty.to_string());
809
810 if let Some(stop_price) = order.stop_price {
811 order_parameters.insert("stopPrice".into(), stop_price.to_string());
812 }
813
814 if order.price != 0.0 {
815 order_parameters.insert("price".into(), order.price.to_string());
816 order_parameters.insert("timeInForce".into(), order.time_in_force.to_string());
817 }
818
819 if let Some(client_order_id) = order.new_client_order_id {
820 order_parameters.insert("newClientOrderId".into(), client_order_id);
821 }
822
823 order_parameters
824 }
825
826 fn build_quote_quantity_order(
827 &self, order: OrderQuoteQuantityRequest,
828 ) -> BTreeMap<String, String> {
829 let mut order_parameters: BTreeMap<String, String> = BTreeMap::new();
830
831 order_parameters.insert("symbol".into(), order.symbol);
832 order_parameters.insert("side".into(), order.order_side.to_string());
833 order_parameters.insert("type".into(), order.order_type.to_string());
834 order_parameters.insert("quoteOrderQty".into(), order.quote_order_qty.to_string());
835
836 if order.price != 0.0 {
837 order_parameters.insert("price".into(), order.price.to_string());
838 order_parameters.insert("timeInForce".into(), order.time_in_force.to_string());
839 }
840
841 if let Some(client_order_id) = order.new_client_order_id {
842 order_parameters.insert("newClientOrderId".into(), client_order_id);
843 }
844
845 order_parameters
846 }
847}