1use crate::model::order::{OrderSide, OrderType, TimeInForce};
8use crate::{impl_json_debug_pretty, impl_json_display};
9use serde::{Deserialize, Serialize};
10
11pub mod fix {
13 use super::*;
14
15 #[derive(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(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(Clone, PartialEq, Eq, Serialize, Deserialize)]
294#[serde(rename_all = "snake_case")]
295pub enum TriggerType {
296 IndexPrice,
298 MarkPrice,
300 LastPrice,
302}
303
304#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
306#[serde(rename_all = "lowercase")]
307pub enum AdvancedOrderType {
308 Usd,
310 Implv,
312}
313
314#[derive(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(Clone, Serialize, Deserialize)]
337pub struct CancelOrderRequest {
338 pub order_id: String,
340}
341
342#[derive(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(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(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
405impl_json_debug_pretty!(
407 fix::NewOrderRequest,
408 NewOrderRequest,
409 TriggerType,
410 AdvancedOrderType,
411 ModifyOrderRequest,
412 CancelOrderRequest,
413 CancelAllOrdersRequest,
414 ClosePositionRequest,
415 AuthRequest
416);
417
418impl_json_display!(
420 fix::NewOrderRequest,
421 NewOrderRequest,
422 TriggerType,
423 AdvancedOrderType,
424 ModifyOrderRequest,
425 CancelOrderRequest,
426 CancelAllOrdersRequest,
427 ClosePositionRequest,
428 AuthRequest
429);