1use crate::order::{
2 id::StrategyId,
3 request::{OrderRequestCancel, OrderRequestOpen, RequestCancel, RequestOpen},
4 state::UnindexedOrderState,
5};
6use barter_instrument::{
7 Side,
8 asset::{AssetIndex, name::AssetNameExchange},
9 exchange::{ExchangeId, ExchangeIndex},
10 instrument::{InstrumentIndex, name::InstrumentNameExchange},
11};
12use derive_more::{Constructor, Display};
13use id::ClientOrderId;
14use rust_decimal::Decimal;
15use serde::{Deserialize, Serialize};
16use state::{ActiveOrderState, Cancelled, InactiveOrderState, Open, OpenInFlight, OrderState};
17
18pub mod id;
20
21pub mod state;
25
26pub mod request;
30
31pub type UnindexedOrder = Order<ExchangeId, InstrumentNameExchange, UnindexedOrderState>;
33
34pub type UnindexedOrderKey = OrderKey<ExchangeId, InstrumentNameExchange>;
37
38pub type UnindexedOrderSnapshot = Order<
41 ExchangeId,
42 InstrumentNameExchange,
43 OrderState<AssetNameExchange, InstrumentNameExchange>,
44>;
45
46pub type OrderSnapshot<
48 ExchangeKey = ExchangeIndex,
49 AssetKey = AssetIndex,
50 InstrumentKey = InstrumentIndex,
51> = Order<ExchangeKey, InstrumentKey, OrderState<AssetKey, InstrumentKey>>;
52
53#[derive(
54 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
55)]
56
57pub struct OrderEvent<State, ExchangeKey = ExchangeIndex, InstrumentKey = InstrumentIndex> {
58 pub key: OrderKey<ExchangeKey, InstrumentKey>,
59 pub state: State,
60}
61
62#[derive(
63 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
64)]
65pub struct OrderKey<ExchangeKey = ExchangeIndex, InstrumentKey = InstrumentIndex> {
66 pub exchange: ExchangeKey,
67 pub instrument: InstrumentKey,
68 pub strategy: StrategyId,
69 pub cid: ClientOrderId,
70}
71
72#[derive(
73 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
74)]
75pub struct Order<ExchangeKey = ExchangeIndex, InstrumentKey = InstrumentIndex, State = OrderState> {
76 pub key: OrderKey<ExchangeKey, InstrumentKey>,
77 pub side: Side,
78 pub price: Decimal,
79 pub quantity: Decimal,
80 pub kind: OrderKind,
81 pub time_in_force: TimeInForce,
82 pub state: State,
83}
84
85impl<ExchangeKey, AssetKey, InstrumentKey>
86 Order<ExchangeKey, InstrumentKey, OrderState<AssetKey, InstrumentKey>>
87{
88 pub fn to_active(&self) -> Option<Order<ExchangeKey, InstrumentKey, ActiveOrderState>>
89 where
90 ExchangeKey: Clone,
91 InstrumentKey: Clone,
92 {
93 let OrderState::Active(state) = &self.state else {
94 return None;
95 };
96
97 Some(Order {
98 key: self.key.clone(),
99 side: self.side,
100 price: self.price,
101 quantity: self.quantity,
102 kind: self.kind,
103 time_in_force: self.time_in_force,
104 state: state.clone(),
105 })
106 }
107
108 pub fn to_inactive(
109 &self,
110 ) -> Option<Order<ExchangeKey, InstrumentKey, InactiveOrderState<AssetKey, InstrumentKey>>>
111 where
112 ExchangeKey: Clone,
113 AssetKey: Clone,
114 InstrumentKey: Clone,
115 {
116 let OrderState::Inactive(state) = &self.state else {
117 return None;
118 };
119
120 Some(Order {
121 key: self.key.clone(),
122 side: self.side,
123 price: self.price,
124 quantity: self.quantity,
125 kind: self.kind,
126 time_in_force: self.time_in_force,
127 state: state.clone(),
128 })
129 }
130}
131
132impl<ExchangeKey, InstrumentKey> Order<ExchangeKey, InstrumentKey, ActiveOrderState>
133where
134 ExchangeKey: Clone,
135 InstrumentKey: Clone,
136{
137 pub fn to_request_cancel(&self) -> Option<OrderRequestCancel<ExchangeKey, InstrumentKey>> {
138 let Order { key, state, .. } = self;
139
140 let request_cancel = match state {
141 ActiveOrderState::OpenInFlight(_) => RequestCancel { id: None },
142 ActiveOrderState::Open(open) => RequestCancel {
143 id: Some(open.id.clone()),
144 },
145 _ => return None,
146 };
147
148 Some(OrderRequestCancel {
149 key: key.clone(),
150 state: request_cancel,
151 })
152 }
153}
154
155#[derive(
156 Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Display,
157)]
158pub enum OrderKind {
159 Market,
160 Limit,
161}
162
163#[derive(
164 Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Display,
165)]
166pub enum TimeInForce {
167 GoodUntilCancelled { post_only: bool },
168 GoodUntilEndOfDay,
169 FillOrKill,
170 ImmediateOrCancel,
171}
172
173impl<ExchangeKey, InstrumentKey> From<&OrderRequestOpen<ExchangeKey, InstrumentKey>>
174 for Order<ExchangeKey, InstrumentKey, ActiveOrderState>
175where
176 ExchangeKey: Clone,
177 InstrumentKey: Clone,
178{
179 fn from(value: &OrderRequestOpen<ExchangeKey, InstrumentKey>) -> Self {
180 let OrderRequestOpen {
181 key,
182 state:
183 RequestOpen {
184 side,
185 price,
186 quantity,
187 kind,
188 time_in_force,
189 },
190 } = value;
191
192 Self {
193 key: key.clone(),
194 side: *side,
195 price: *price,
196 quantity: *quantity,
197 kind: *kind,
198 time_in_force: *time_in_force,
199 state: ActiveOrderState::OpenInFlight(OpenInFlight),
200 }
201 }
202}
203
204impl<ExchangeKey, InstrumentKey> From<Order<ExchangeKey, InstrumentKey, Open>>
205 for Order<ExchangeKey, InstrumentKey, ActiveOrderState>
206{
207 fn from(value: Order<ExchangeKey, InstrumentKey, Open>) -> Self {
208 let Order {
209 key,
210 side,
211 price,
212 quantity,
213 kind,
214 time_in_force,
215 state,
216 } = value;
217
218 Self {
219 key,
220 side,
221 price,
222 quantity,
223 kind,
224 time_in_force,
225 state: ActiveOrderState::Open(state),
226 }
227 }
228}
229
230impl<ExchangeKey, AssetKey, InstrumentKey> From<Order<ExchangeKey, InstrumentKey, Open>>
231 for Order<ExchangeKey, InstrumentKey, OrderState<AssetKey, InstrumentKey>>
232{
233 fn from(value: Order<ExchangeKey, InstrumentKey, Open>) -> Self {
234 let Order {
235 key,
236 side,
237 price,
238 quantity,
239 kind,
240 time_in_force,
241 state,
242 } = value;
243
244 Self {
245 key,
246 side,
247 price,
248 quantity,
249 kind,
250 time_in_force,
251 state: OrderState::Active(ActiveOrderState::Open(state)),
252 }
253 }
254}
255
256impl<ExchangeKey, AssetKey, InstrumentKey> From<Order<ExchangeKey, InstrumentKey, Cancelled>>
257 for Order<ExchangeKey, InstrumentKey, OrderState<AssetKey, InstrumentKey>>
258{
259 fn from(value: Order<ExchangeKey, InstrumentKey, Cancelled>) -> Self {
260 let Order {
261 key,
262 side,
263 price,
264 quantity,
265 kind,
266 time_in_force,
267 state,
268 } = value;
269
270 Self {
271 key,
272 side,
273 price,
274 quantity,
275 kind,
276 time_in_force,
277 state: OrderState::Inactive(InactiveOrderState::Cancelled(state)),
278 }
279 }
280}