1use super::shared::Result;
2use super::BaseClient;
3use crate::model::MarketPair;
4use crate::model::{
5 Account, CancelAllOrders, CancelOrder, Fill, GetFillsReq, GetOrderRequest, Order, OrderRequest,
6 OrderRequestMarketType, OrderRequestType, OrderSide, OrderTimeInForce, Paginator,
7};
8use ecbt_exchange::info::MarketPairInfo;
9use rust_decimal::prelude::*;
10
11impl BaseClient {
12 pub async fn get_account(&self, paginator: Option<&Paginator>) -> Result<Vec<Account>> {
13 self.transport.signed_get("/accounts", paginator).await
14 }
15
16 pub async fn get_orders(&self, params: Option<&GetOrderRequest>) -> Result<Vec<Order>> {
17 self.transport.signed_get::<_, _>("/orders", params).await
18 }
19
20 pub async fn get_order(&self, order_id: String) -> Result<Order> {
21 self.transport
22 .signed_get::<_, ()>(&format!("/orders/{}", order_id), None)
23 .await
24 }
25
26 pub async fn market_buy(&self, pair: MarketPairInfo, size: Decimal) -> Result<Order> {
28 let data = OrderRequest {
29 product_id: pair.symbol,
30 client_oid: None,
31 side: OrderSide::Buy,
32 _type: OrderRequestType::Market {
33 _type: OrderRequestMarketType::Size {
34 size: size.round_dp(pair.base_increment.normalize().scale()),
35 },
36 },
37 stop: None,
38 };
39
40 let transaction = self
41 .transport
42 .signed_post::<_, (), _>("/orders", None, Some(&data))
43 .await?;
44
45 Ok(transaction)
46 }
47
48 pub async fn market_sell(&self, pair: MarketPairInfo, size: Decimal) -> Result<Order> {
49 let data = OrderRequest {
50 product_id: pair.symbol,
51 client_oid: None,
52 side: OrderSide::Sell,
53 _type: OrderRequestType::Market {
54 _type: OrderRequestMarketType::Size {
55 size: size.round_dp(pair.base_increment.normalize().scale()),
56 },
57 },
58 stop: None,
59 };
60
61 let transaction = self
62 .transport
63 .signed_post::<_, (), _>("/orders", None, Some(&data))
64 .await?;
65
66 Ok(transaction)
67 }
68
69 pub async fn limit_buy(
70 &self,
71 pair: MarketPairInfo,
72 size: Decimal,
73 price: Decimal,
74 time_in_force: OrderTimeInForce,
75 post_only: bool,
76 ) -> Result<Order> {
77 let data = OrderRequest {
78 product_id: pair.symbol,
79 client_oid: None,
80 side: OrderSide::Buy,
81 _type: OrderRequestType::Limit {
82 size: size.round_dp(pair.base_increment.normalize().scale()),
83 price: price.round_dp_with_strategy(
84 pair.quote_increment.normalize().scale(),
85 RoundingStrategy::ToZero,
86 ),
87 post_only,
88 time_in_force: Some(time_in_force),
89 },
90 stop: None,
91 };
92
93 let transaction = self
94 .transport
95 .signed_post::<_, (), _>("/orders", None, Some(&data))
96 .await?;
97
98 Ok(transaction)
99 }
100
101 pub async fn limit_sell(
102 &self,
103 pair: MarketPairInfo,
104 size: Decimal,
105 price: Decimal,
106 time_in_force: OrderTimeInForce,
107 post_only: bool,
108 ) -> Result<Order> {
109 let data = OrderRequest {
110 product_id: pair.symbol,
111 client_oid: None,
112 side: OrderSide::Sell,
113 _type: OrderRequestType::Limit {
114 size: size.round_dp(pair.base_increment.normalize().scale()),
115 price: price.round_dp_with_strategy(
116 pair.quote_increment.normalize().scale(),
117 RoundingStrategy::AwayFromZero,
118 ),
119 post_only,
120 time_in_force: Some(time_in_force),
121 },
122 stop: None,
123 };
124
125 let transaction = self
126 .transport
127 .signed_post::<_, (), _>("/orders", None, Some(&data))
128 .await?;
129
130 Ok(transaction)
131 }
132
133 pub async fn cancel_order(&self, order_id: String, product_id: Option<&str>) -> Result<String> {
134 let params = if let Some(product_id) = product_id {
135 CancelOrder {
136 product_id: Some(String::from(product_id)),
137 }
138 } else {
139 CancelOrder { product_id: None }
140 };
141
142 let path = format!("/orders/{}", order_id);
143 let resp = self
144 .transport
145 .signed_delete::<_, _, ()>(&path, Some(¶ms), None)
146 .await?;
147
148 Ok(resp)
149 }
150
151 pub async fn cancel_all_orders<P: Into<MarketPair>>(
152 &self,
153 product_id: Option<P>,
154 ) -> Result<Vec<String>> {
155 let params = if let Some(product_id) = product_id {
156 CancelAllOrders {
157 product_id: Some(product_id.into().0),
158 }
159 } else {
160 CancelAllOrders { product_id: None }
161 };
162
163 let resp = self
164 .transport
165 .signed_delete::<_, _, ()>("/orders", Some(¶ms), None)
166 .await?;
167
168 Ok(resp)
169 }
170
171 pub async fn get_fills(&self, params: Option<&GetFillsReq>) -> Result<Vec<Fill>> {
172 let resp = self.transport.signed_get::<_, _>("/fills", params).await?;
173
174 Ok(resp)
175 }
176}