1use crate::util::{build_signed_request, is_start_time_valid};
2use crate::model::{
3 AccountInformation, Balance, Empty, Order, OrderCanceled, TradeHistory, Transaction,
4};
5use crate::client::Client;
6use crate::errors::{Result, Error};
7use std::collections::BTreeMap;
8use std::fmt::Display;
9use crate::api::API;
10use crate::api::Spot;
11
12#[derive(Clone)]
13pub struct Account {
14 pub client: Client,
15 pub recv_window: u64,
16}
17
18struct OrderRequest {
19 pub symbol: String,
20 pub qty: f64,
21 pub price: f64,
22 pub stop_price: Option<f64>,
23 pub order_side: OrderSide,
24 pub order_type: OrderType,
25 pub time_in_force: TimeInForce,
26 pub new_client_order_id: Option<String>,
27}
28
29struct OrderQuoteQuantityRequest {
30 pub symbol: String,
31 pub quote_order_qty: f64,
32 pub price: f64,
33 pub order_side: OrderSide,
34 pub order_type: OrderType,
35 pub time_in_force: TimeInForce,
36 pub new_client_order_id: Option<String>,
37}
38
39#[derive(PartialEq, Eq, Debug, Clone, Copy)]
40pub enum OrderType {
41 Limit,
42 Market,
43 StopLossLimit,
44}
45
46impl OrderType {
47 pub fn from_int(value: i32) -> Option<Self> {
48 match value {
49 1 => Some(OrderType::Limit),
50 2 => Some(OrderType::Market),
51 3 => Some(OrderType::StopLossLimit),
52 _ => None,
53 }
54 }
55}
56
57impl Display for OrderType {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 match self {
60 Self::Limit => write!(f, "LIMIT"),
61 Self::Market => write!(f, "MARKET"),
62 Self::StopLossLimit => write!(f, "STOP_LOSS_LIMIT"),
63 }
64 }
65}
66
67#[derive(PartialEq, Eq, Debug, Clone, Copy)]
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)]
93#[derive(PartialEq, Eq, Debug, Clone, Copy)]
94pub enum TimeInForce {
95 GTC,
96 IOC,
97 FOK,
98}
99
100impl TimeInForce {
101 pub fn from_int(value: i32) -> Option<Self> {
102 match value {
103 1 => Some(TimeInForce::GTC),
104 2 => Some(TimeInForce::IOC),
105 3 => Some(TimeInForce::FOK),
106 _ => None,
107 }
108 }
109}
110
111impl Display for TimeInForce {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 match self {
114 Self::GTC => write!(f, "GTC"),
115 Self::IOC => write!(f, "IOC"),
116 Self::FOK => write!(f, "FOK"),
117 }
118 }
119}
120
121impl Account {
122 pub async fn get_account(&self) -> Result<AccountInformation> {
124 let request = build_signed_request(BTreeMap::new(), self.recv_window)?;
125 self.client
126 .get_signed(API::Spot(Spot::Account), Some(request))
127 .await
128 }
129
130 pub async fn get_balance<S>(&self, asset: S) -> Result<Balance>
132 where
133 S: Into<String>,
134 {
135 match self.get_account().await {
136 Ok(account) => {
137 let cmp_asset = asset.into();
138 for balance in account.balances {
139 if balance.asset == cmp_asset {
140 return Ok(balance);
141 }
142 }
143 Err(Error::Custom("Asset not found".to_string()))
144 }
145 Err(e) => Err(e),
146 }
147 }
148
149 pub async fn get_open_orders<S>(&self, symbol: S) -> Result<Vec<Order>>
151 where
152 S: Into<String>,
153 {
154 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
155 parameters.insert("symbol".into(), symbol.into());
156
157 let request = build_signed_request(parameters, self.recv_window)?;
158 self.client
159 .get_signed(API::Spot(Spot::OpenOrders), Some(request))
160 .await
161 }
162
163 pub async fn get_all_open_orders(&self) -> Result<Vec<Order>> {
165 let parameters: BTreeMap<String, String> = BTreeMap::new();
166
167 let request = build_signed_request(parameters, self.recv_window)?;
168 self.client
169 .get_signed(API::Spot(Spot::OpenOrders), Some(request))
170 .await
171 }
172
173 pub async fn cancel_all_open_orders<S>(&self, symbol: S) -> Result<Vec<OrderCanceled>>
175 where
176 S: Into<String>,
177 {
178 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
179 parameters.insert("symbol".into(), symbol.into());
180 let request = build_signed_request(parameters, self.recv_window)?;
181 self.client
182 .delete_signed(API::Spot(Spot::OpenOrders), Some(request))
183 .await
184 }
185
186 pub async fn order_status<S>(&self, symbol: S, order_id: u64) -> Result<Order>
188 where
189 S: Into<String>,
190 {
191 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
192 parameters.insert("symbol".into(), symbol.into());
193 parameters.insert("orderId".into(), order_id.to_string());
194
195 let request = build_signed_request(parameters, self.recv_window)?;
196 self.client
197 .get_signed(API::Spot(Spot::Order), Some(request))
198 .await
199 }
200
201 pub async fn test_order_status<S>(&self, symbol: S, order_id: u64) -> Result<()>
205 where
206 S: Into<String>,
207 {
208 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
209 parameters.insert("symbol".into(), symbol.into());
210 parameters.insert("orderId".into(), order_id.to_string());
211
212 let request = build_signed_request(parameters, self.recv_window)?;
213 self.client
214 .get_signed::<Empty>(API::Spot(Spot::OrderTest), Some(request))
215 .await?;
216 Ok(())
217 }
218
219 pub async fn limit_buy<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<Transaction>
221 where
222 S: Into<String>,
223 F: Into<f64>,
224 {
225 let buy = OrderRequest {
226 symbol: symbol.into(),
227 qty: qty.into(),
228 price,
229 stop_price: None,
230 order_side: OrderSide::Buy,
231 order_type: OrderType::Limit,
232 time_in_force: TimeInForce::GTC,
233 new_client_order_id: None,
234 };
235 let order = self.build_order(buy);
236 let request = build_signed_request(order, self.recv_window)?;
237 self.client
238 .post_signed(API::Spot(Spot::Order), request)
239 .await
240 }
241
242 pub async fn test_limit_buy<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<()>
246 where
247 S: Into<String>,
248 F: Into<f64>,
249 {
250 let buy = OrderRequest {
251 symbol: symbol.into(),
252 qty: qty.into(),
253 price,
254 stop_price: None,
255 order_side: OrderSide::Buy,
256 order_type: OrderType::Limit,
257 time_in_force: TimeInForce::GTC,
258 new_client_order_id: None,
259 };
260 let order = self.build_order(buy);
261 let request = build_signed_request(order, self.recv_window)?;
262 self.client
263 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
264 .await?;
265 Ok(())
266 }
267
268 pub async fn limit_sell<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<Transaction>
270 where
271 S: Into<String>,
272 F: Into<f64>,
273 {
274 let sell = OrderRequest {
275 symbol: symbol.into(),
276 qty: qty.into(),
277 price,
278 stop_price: None,
279 order_side: OrderSide::Sell,
280 order_type: OrderType::Limit,
281 time_in_force: TimeInForce::GTC,
282 new_client_order_id: None,
283 };
284 let order = self.build_order(sell);
285 let request = build_signed_request(order, self.recv_window)?;
286 self.client
287 .post_signed(API::Spot(Spot::Order), request)
288 .await
289 }
290
291 pub async fn test_limit_sell<S, F>(&self, symbol: S, qty: F, price: f64) -> Result<()>
295 where
296 S: Into<String>,
297 F: Into<f64>,
298 {
299 let sell = OrderRequest {
300 symbol: symbol.into(),
301 qty: qty.into(),
302 price,
303 stop_price: None,
304 order_side: OrderSide::Sell,
305 order_type: OrderType::Limit,
306 time_in_force: TimeInForce::GTC,
307 new_client_order_id: None,
308 };
309 let order = self.build_order(sell);
310 let request = build_signed_request(order, self.recv_window)?;
311 self.client
312 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
313 .await?;
314 Ok(())
315 }
316
317 pub async fn market_buy<S, F>(&self, symbol: S, qty: F) -> Result<Transaction>
319 where
320 S: Into<String>,
321 F: Into<f64>,
322 {
323 let buy = OrderRequest {
324 symbol: symbol.into(),
325 qty: qty.into(),
326 price: 0.0,
327 stop_price: None,
328 order_side: OrderSide::Buy,
329 order_type: OrderType::Market,
330 time_in_force: TimeInForce::GTC,
331 new_client_order_id: None,
332 };
333 let order = self.build_order(buy);
334 let request = build_signed_request(order, self.recv_window)?;
335 self.client
336 .post_signed(API::Spot(Spot::Order), request)
337 .await
338 }
339
340 pub async fn test_market_buy<S, F>(&self, symbol: S, qty: F) -> Result<()>
344 where
345 S: Into<String>,
346 F: Into<f64>,
347 {
348 let buy = OrderRequest {
349 symbol: symbol.into(),
350 qty: qty.into(),
351 price: 0.0,
352 stop_price: None,
353 order_side: OrderSide::Buy,
354 order_type: OrderType::Market,
355 time_in_force: TimeInForce::GTC,
356 new_client_order_id: None,
357 };
358 let order = self.build_order(buy);
359 let request = build_signed_request(order, self.recv_window)?;
360 self.client
361 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
362 .await?;
363 Ok(())
364 }
365
366 pub async fn market_buy_using_quote_quantity<S, F>(
368 &self, symbol: S, quote_order_qty: F,
369 ) -> Result<Transaction>
370 where
371 S: Into<String>,
372 F: Into<f64>,
373 {
374 let buy = OrderQuoteQuantityRequest {
375 symbol: symbol.into(),
376 quote_order_qty: quote_order_qty.into(),
377 price: 0.0,
378 order_side: OrderSide::Buy,
379 order_type: OrderType::Market,
380 time_in_force: TimeInForce::GTC,
381 new_client_order_id: None,
382 };
383 let order = self.build_quote_quantity_order(buy);
384 let request = build_signed_request(order, self.recv_window)?;
385 self.client
386 .post_signed(API::Spot(Spot::Order), request)
387 .await
388 }
389
390 pub async fn test_market_buy_using_quote_quantity<S, F>(
394 &self, symbol: S, quote_order_qty: F,
395 ) -> Result<()>
396 where
397 S: Into<String>,
398 F: Into<f64>,
399 {
400 let buy = OrderQuoteQuantityRequest {
401 symbol: symbol.into(),
402 quote_order_qty: quote_order_qty.into(),
403 price: 0.0,
404 order_side: OrderSide::Buy,
405 order_type: OrderType::Market,
406 time_in_force: TimeInForce::GTC,
407 new_client_order_id: None,
408 };
409 let order = self.build_quote_quantity_order(buy);
410 let request = build_signed_request(order, self.recv_window)?;
411 self.client
412 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
413 .await?;
414 Ok(())
415 }
416
417 pub async fn market_sell<S, F>(&self, symbol: S, qty: F) -> Result<Transaction>
419 where
420 S: Into<String>,
421 F: Into<f64>,
422 {
423 let sell = OrderRequest {
424 symbol: symbol.into(),
425 qty: qty.into(),
426 price: 0.0,
427 stop_price: None,
428 order_side: OrderSide::Sell,
429 order_type: OrderType::Market,
430 time_in_force: TimeInForce::GTC,
431 new_client_order_id: None,
432 };
433 let order = self.build_order(sell);
434 let request = build_signed_request(order, self.recv_window)?;
435 self.client
436 .post_signed(API::Spot(Spot::Order), request)
437 .await
438 }
439
440 pub async fn test_market_sell<S, F>(&self, symbol: S, qty: F) -> Result<()>
444 where
445 S: Into<String>,
446 F: Into<f64>,
447 {
448 let sell = OrderRequest {
449 symbol: symbol.into(),
450 qty: qty.into(),
451 price: 0.0,
452 stop_price: None,
453 order_side: OrderSide::Sell,
454 order_type: OrderType::Market,
455 time_in_force: TimeInForce::GTC,
456 new_client_order_id: None,
457 };
458 let order = self.build_order(sell);
459 let request = build_signed_request(order, self.recv_window)?;
460 self.client
461 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
462 .await?;
463 Ok(())
464 }
465
466 pub async fn market_sell_using_quote_quantity<S, F>(
468 &self, symbol: S, quote_order_qty: F,
469 ) -> Result<Transaction>
470 where
471 S: Into<String>,
472 F: Into<f64>,
473 {
474 let sell = OrderQuoteQuantityRequest {
475 symbol: symbol.into(),
476 quote_order_qty: quote_order_qty.into(),
477 price: 0.0,
478 order_side: OrderSide::Sell,
479 order_type: OrderType::Market,
480 time_in_force: TimeInForce::GTC,
481 new_client_order_id: None,
482 };
483 let order = self.build_quote_quantity_order(sell);
484 let request = build_signed_request(order, self.recv_window)?;
485 self.client
486 .post_signed(API::Spot(Spot::Order), request)
487 .await
488 }
489
490 pub async fn test_market_sell_using_quote_quantity<S, F>(
494 &self, symbol: S, quote_order_qty: F,
495 ) -> Result<()>
496 where
497 S: Into<String>,
498 F: Into<f64>,
499 {
500 let sell = OrderQuoteQuantityRequest {
501 symbol: symbol.into(),
502 quote_order_qty: quote_order_qty.into(),
503 price: 0.0,
504 order_side: OrderSide::Sell,
505 order_type: OrderType::Market,
506 time_in_force: TimeInForce::GTC,
507 new_client_order_id: None,
508 };
509 let order = self.build_quote_quantity_order(sell);
510 let request = build_signed_request(order, self.recv_window)?;
511 self.client
512 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
513 .await?;
514 Ok(())
515 }
516
517 pub async fn stop_limit_buy_order<S, F>(
538 &self, symbol: S, qty: F, price: f64, stop_price: f64,
539 ) -> Result<Transaction>
540 where
541 S: Into<String>,
542 F: Into<f64>,
543 {
544 let buy = OrderRequest {
545 symbol: symbol.into(),
546 qty: qty.into(),
547 price,
548 stop_price: Some(stop_price),
549 order_side: OrderSide::Buy,
550 order_type: OrderType::StopLossLimit,
551 time_in_force: TimeInForce::GTC,
552 new_client_order_id: None,
553 };
554 let order = self.build_order(buy);
555 let request = build_signed_request(order, self.recv_window)?;
556 self.client
557 .post_signed(API::Spot(Spot::Order), request)
558 .await
559 }
560
561 pub async fn test_stop_limit_buy_order<S, F>(
583 &self, symbol: S, qty: F, price: f64, stop_price: f64,
584 ) -> Result<()>
585 where
586 S: Into<String>,
587 F: Into<f64>,
588 {
589 let buy = OrderRequest {
590 symbol: symbol.into(),
591 qty: qty.into(),
592 price,
593 stop_price: Some(stop_price),
594 order_side: OrderSide::Buy,
595 order_type: OrderType::StopLossLimit,
596 time_in_force: TimeInForce::GTC,
597 new_client_order_id: None,
598 };
599 let order = self.build_order(buy);
600 let request = build_signed_request(order, self.recv_window)?;
601 self.client
602 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
603 .await?;
604 Ok(())
605 }
606
607 pub async fn stop_limit_sell_order<S, F>(
628 &self, symbol: S, qty: F, price: f64, stop_price: f64,
629 ) -> Result<Transaction>
630 where
631 S: Into<String>,
632 F: Into<f64>,
633 {
634 let sell = OrderRequest {
635 symbol: symbol.into(),
636 qty: qty.into(),
637 price,
638 stop_price: Some(stop_price),
639 order_side: OrderSide::Sell,
640 order_type: OrderType::StopLossLimit,
641 time_in_force: TimeInForce::GTC,
642 new_client_order_id: None,
643 };
644 let order = self.build_order(sell);
645 let request = build_signed_request(order, self.recv_window)?;
646 self.client
647 .post_signed(API::Spot(Spot::Order), request)
648 .await
649 }
650
651 pub async fn test_stop_limit_sell_order<S, F>(
673 &self, symbol: S, qty: F, price: f64, stop_price: f64,
674 ) -> Result<()>
675 where
676 S: Into<String>,
677 F: Into<f64>,
678 {
679 let sell = OrderRequest {
680 symbol: symbol.into(),
681 qty: qty.into(),
682 price,
683 stop_price: Some(stop_price),
684 order_side: OrderSide::Sell,
685 order_type: OrderType::StopLossLimit,
686 time_in_force: TimeInForce::GTC,
687 new_client_order_id: None,
688 };
689 let order = self.build_order(sell);
690 let request = build_signed_request(order, self.recv_window)?;
691 self.client
692 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
693 .await?;
694 Ok(())
695 }
696
697 pub async fn custom_order<S, F>(
699 &self, symbol: S, qty: F, price: f64, order_side: OrderSide, order_type: OrderType,
700 time_in_force: TimeInForce, new_client_order_id: Option<String>,
701 ) -> Result<Transaction>
702 where
703 S: Into<String>,
704 F: Into<f64>,
705 {
706 let custom_order = OrderRequest {
707 symbol: symbol.into(),
708 qty: qty.into(),
709 price,
710 stop_price: None,
711 order_side,
712 order_type,
713 time_in_force,
714 new_client_order_id,
715 };
716 let order = self.build_order(custom_order);
717 let request = build_signed_request(order, self.recv_window)?;
718 self.client
719 .post_signed(API::Spot(Spot::Order), request)
720 .await
721 }
722
723 pub async fn test_custom_order<S, F>(
727 &self, symbol: S, qty: F, price: f64, order_side: OrderSide, order_type: OrderType,
728 time_in_force: TimeInForce, new_client_order_id: Option<String>,
729 ) -> Result<()>
730 where
731 S: Into<String>,
732 F: Into<f64>,
733 {
734 let custom_order = OrderRequest {
735 symbol: symbol.into(),
736 qty: qty.into(),
737 price,
738 stop_price: None,
739 order_side,
740 order_type,
741 time_in_force,
742 new_client_order_id,
743 };
744 let order = self.build_order(custom_order);
745 let request = build_signed_request(order, self.recv_window)?;
746 self.client
747 .post_signed::<Empty>(API::Spot(Spot::OrderTest), request)
748 .await?;
749 Ok(())
750 }
751
752 pub async fn cancel_order<S>(&self, symbol: S, order_id: u64) -> Result<OrderCanceled>
754 where
755 S: Into<String>,
756 {
757 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
758 parameters.insert("symbol".into(), symbol.into());
759 parameters.insert("orderId".into(), order_id.to_string());
760
761 let request = build_signed_request(parameters, self.recv_window)?;
762 self.client
763 .delete_signed(API::Spot(Spot::Order), Some(request))
764 .await
765 }
766 pub async fn cancel_order_with_client_id<S>(
767 &self, symbol: S, client_order_id: String,
768 ) -> Result<OrderCanceled>
769 where
770 S: Into<String>,
771 {
772 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
773 parameters.insert("symbol".into(), symbol.into());
774 parameters.insert("origClientOrderId".into(), client_order_id);
775
776 let request = build_signed_request(parameters, self.recv_window)?;
777 self.client
778 .delete_signed(API::Spot(Spot::Order), Some(request))
779 .await
780 }
781
782 pub async fn test_cancel_order<S>(&self, symbol: S, order_id: u64) -> Result<()>
786 where
787 S: Into<String>,
788 {
789 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
790 parameters.insert("symbol".into(), symbol.into());
791 parameters.insert("orderId".into(), order_id.to_string());
792
793 let request = build_signed_request(parameters, self.recv_window)?;
794 self.client
795 .delete_signed::<Empty>(API::Spot(Spot::OrderTest), Some(request))
796 .await?;
797 Ok(())
798 }
799
800 pub async fn trade_history<S>(&self, symbol: S) -> Result<Vec<TradeHistory>>
802 where
803 S: Into<String>,
804 {
805 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
806 parameters.insert("symbol".into(), symbol.into());
807
808 let request = build_signed_request(parameters, self.recv_window)?;
809 self.client
810 .get_signed(API::Spot(Spot::MyTrades), Some(request))
811 .await
812 }
813
814 pub async fn trade_history_from<S>(
816 &self, symbol: S, start_time: u64,
817 ) -> Result<Vec<TradeHistory>>
818 where
819 S: Into<String>,
820 {
821 let mut parameters: BTreeMap<String, String> = BTreeMap::new();
822 parameters.insert("symbol".into(), symbol.into());
823 parameters.insert("startTime".into(), start_time.to_string());
824
825 let request = build_signed_request(parameters, self.recv_window)?;
826 self.client
827 .get_signed(API::Spot(Spot::MyTrades), Some(request))
828 .await
829 }
830
831 pub async fn trade_history_from_to<S>(
833 &self, symbol: S, start_time: u64, end_time: u64,
834 ) -> Result<Vec<TradeHistory>>
835 where
836 S: Into<String>,
837 {
838 if is_start_time_valid(&start_time) && (start_time < end_time) {
839 self.get_trades(symbol.into(), start_time, end_time).await
840 } else {
841 Err(Error::Custom(
842 "The given start or end time is invalid.".to_string(),
843 ))
844 }
845 }
846 async fn get_trades<S>(
847 &self, symbol: S, start_time: u64, end_time: u64,
848 ) -> Result<Vec<TradeHistory>>
849 where
850 S: Into<String>,
851 {
852 let symbol_string = symbol.into(); let mut trades = match self
854 .trade_history_from(symbol_string.clone(), start_time)
855 .await
856 {
857 Ok(trades_vec) => trades_vec,
858 Err(e) => return Err(e),
859 };
860
861 trades.retain(|trade| trade.time <= end_time);
862 Ok(trades)
863 }
864
865 fn build_order(&self, order: OrderRequest) -> BTreeMap<String, String> {
866 let mut open_order: BTreeMap<String, String> = BTreeMap::new();
867
868 open_order.insert("symbol".into(), order.symbol);
869 open_order.insert("quantity".into(), format!("{}", order.qty));
870 open_order.insert("side".into(), order.order_side.to_string());
871 open_order.insert("type".into(), order.order_type.to_string());
872 if order.order_type == OrderType::Limit || order.order_type == OrderType::StopLossLimit {
873 open_order.insert("timeInForce".into(), order.time_in_force.to_string());
874 open_order.insert("price".into(), format!("{}", order.price));
875 }
876 if order.order_type == OrderType::StopLossLimit {
877 if let Some(stop_price) = order.stop_price {
878 open_order.insert("stopPrice".into(), format!("{}", stop_price));
879 }
880 }
881 if let Some(ref new_client_order_id) = order.new_client_order_id {
882 open_order.insert("newClientOrderId".into(), new_client_order_id.clone());
883 }
884
885 open_order
886 }
887
888 fn build_quote_quantity_order(
889 &self, order: OrderQuoteQuantityRequest,
890 ) -> BTreeMap<String, String> {
891 let mut open_order: BTreeMap<String, String> = BTreeMap::new();
892
893 open_order.insert("symbol".into(), order.symbol);
894 open_order.insert("quoteOrderQty".into(), format!("{}", order.quote_order_qty));
895 open_order.insert("side".into(), order.order_side.to_string());
896 open_order.insert("type".into(), order.order_type.to_string());
897 if order.order_type == OrderType::Limit {
898 open_order.insert("timeInForce".into(), order.time_in_force.to_string());
899 open_order.insert("price".into(), format!("{}", order.price));
900 }
901 if let Some(ref new_client_order_id) = order.new_client_order_id {
902 open_order.insert("newClientOrderId".into(), new_client_order_id.clone());
903 }
904
905 open_order
906 }
907}