1use crate::{
8 utils::{current_timestamp_millis, safe_add, safe_sub},
9 OrderStatus, OrderType, Side, TimeInForce,
10};
11use serde::{Deserialize, Serialize};
12use std::{
13 iter::Sum,
14 ops::{Add, AddAssign, Div, Sub},
15};
16
17#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize, Eq, Hash)]
18pub struct OrderId(pub u64);
19impl AddAssign<u64> for OrderId {
20 fn add_assign(&mut self, rhs: u64) {
21 self.0 += rhs;
22 }
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, PartialOrd, Ord)]
26pub struct Price(pub u64);
27impl Price {
28 pub fn value(self) -> u64 {
29 self.0
30 }
31}
32impl Add for Price {
33 type Output = Price;
34
35 fn add(self, rhs: Price) -> Price {
36 Price(safe_add(self.0, rhs.0))
37 }
38}
39
40impl Sub for Price {
41 type Output = Price;
42
43 fn sub(self, rhs: Price) -> Price {
44 Price(safe_sub(self.0, rhs.0))
45 }
46}
47
48impl Div for Price {
49 type Output = Price;
50
51 fn div(self, rhs: Price) -> Price {
52 Price(self.0.saturating_div(rhs.0))
53 }
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, PartialOrd)]
57pub struct Quantity(pub u64);
58impl Quantity {
59 pub fn value(self) -> u64 {
60 self.0
61 }
62}
63impl Add for Quantity {
64 type Output = Quantity;
65
66 fn add(self, rhs: Quantity) -> Quantity {
67 Quantity(safe_add(self.0, rhs.0))
68 }
69}
70impl Sub for Quantity {
71 type Output = Quantity;
72
73 fn sub(self, rhs: Quantity) -> Quantity {
74 Quantity(safe_sub(self.0, rhs.0))
75 }
76}
77impl AddAssign<u64> for Quantity {
78 fn add_assign(&mut self, rhs: u64) {
79 self.0 += rhs;
80 }
81}
82impl Sum for Quantity {
83 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
84 Quantity(iter.map(|q| q.0).sum())
85 }
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97pub struct MarketOrderOptions {
98 pub side: Side,
99 pub quantity: Quantity,
100}
101impl MarketOrderOptions {
102 pub fn new(side: Side, quantity: u64) -> Self {
103 Self { side, quantity: Quantity(quantity) }
104 }
105}
106
107#[derive(Debug)]
108pub(crate) struct MarketOrder {
109 pub(crate) id: OrderId,
110 pub(crate) side: Side,
111 pub(crate) orig_qty: Quantity,
112 pub(crate) executed_qty: Quantity,
113 pub(crate) status: OrderStatus,
114}
115
116impl MarketOrder {
117 pub(crate) fn new(id: OrderId, options: MarketOrderOptions) -> MarketOrder {
118 MarketOrder {
119 id,
120 side: options.side,
121 orig_qty: options.quantity,
122 executed_qty: Quantity(0),
123 status: OrderStatus::New,
124 }
125 }
126 pub(crate) fn remaining_qty(&self) -> Quantity {
127 self.orig_qty.sub(self.executed_qty)
128 }
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143pub struct LimitOrderOptions {
144 pub side: Side,
145 pub quantity: Quantity,
146 pub price: Price,
147 pub time_in_force: Option<TimeInForce>,
148 pub post_only: Option<bool>,
149}
150impl LimitOrderOptions {
151 pub fn new(
152 side: Side,
153 quantity: u64,
154 price: u64,
155 time_in_force: Option<TimeInForce>,
156 post_only: Option<bool>,
157 ) -> Self {
158 Self { side, quantity: Quantity(quantity), price: Price(price), time_in_force, post_only }
159 }
160}
161
162#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
169pub struct LimitOrder {
170 pub(crate) id: OrderId,
171 pub(crate) side: Side,
172 pub(crate) orig_qty: Quantity,
173 pub(crate) executed_qty: Quantity,
174 pub(crate) price: Price,
175 pub(crate) order_type: OrderType,
176 pub(crate) time: i64,
177 pub(crate) time_in_force: TimeInForce,
178 pub(crate) post_only: bool,
179 pub(crate) taker_qty: Quantity,
180 pub(crate) maker_qty: Quantity,
181 pub(crate) status: OrderStatus,
182}
183
184impl LimitOrder {
185 pub(crate) fn new(id: OrderId, options: LimitOrderOptions) -> LimitOrder {
186 LimitOrder {
187 id,
188 side: options.side,
189 orig_qty: options.quantity,
190 executed_qty: Quantity(0),
191 price: options.price,
192 order_type: OrderType::Limit,
193 time: current_timestamp_millis(),
194 time_in_force: get_order_time_in_force(options.time_in_force),
195 post_only: options.post_only.unwrap_or(false),
196 taker_qty: Quantity(0),
197 maker_qty: Quantity(0),
198 status: OrderStatus::New,
199 }
200 }
201
202 pub(crate) fn remaining_qty(&self) -> Quantity {
203 self.orig_qty.sub(self.executed_qty)
204 }
205}
206
207pub(crate) fn get_order_time_in_force(time_in_force: Option<TimeInForce>) -> TimeInForce {
208 time_in_force.unwrap_or(TimeInForce::GTC)
209}