rustrade_execution/order/
state.rs1use crate::{error::OrderError, order::id::OrderId};
2use chrono::{DateTime, Utc};
3use derive_more::{Constructor, From};
4use rust_decimal::Decimal;
5use rustrade_instrument::{
6 asset::{AssetIndex, name::AssetNameExchange},
7 instrument::{InstrumentIndex, name::InstrumentNameExchange},
8};
9use serde::{Deserialize, Serialize};
10
11pub type UnindexedOrderState = OrderState<AssetNameExchange, InstrumentNameExchange>;
14
15#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, From)]
16pub enum OrderState<AssetKey = AssetIndex, InstrumentKey = InstrumentIndex> {
17 Active(ActiveOrderState),
18 Inactive(InactiveOrderState<AssetKey, InstrumentKey>),
19}
20
21impl<AssetKey, InstrumentKey> OrderState<AssetKey, InstrumentKey> {
22 pub fn active<S>(state: S) -> Self
23 where
24 S: Into<ActiveOrderState>,
25 {
26 OrderState::Active(state.into())
27 }
28
29 pub fn inactive<S>(state: S) -> Self
30 where
31 S: Into<InactiveOrderState<AssetKey, InstrumentKey>>,
32 {
33 OrderState::Inactive(state.into())
34 }
35
36 pub fn fully_filled(filled: Filled) -> Self {
37 Self::Inactive(InactiveOrderState::FullyFilled(filled))
38 }
39
40 pub fn expired(expired: Expired) -> Self {
41 Self::Inactive(InactiveOrderState::Expired(expired))
42 }
43
44 pub fn time_exchange(&self) -> Option<DateTime<Utc>> {
45 match self {
46 Self::Active(active) => match active {
47 ActiveOrderState::OpenInFlight(_) => None,
48 ActiveOrderState::Open(state) => Some(state.time_exchange),
49 ActiveOrderState::CancelInFlight(state) => {
50 state.order.as_ref().map(|order| order.time_exchange)
51 }
52 },
53 Self::Inactive(inactive) => match inactive {
54 InactiveOrderState::Cancelled(state) => Some(state.time_exchange),
55 InactiveOrderState::FullyFilled(state) => Some(state.time_exchange),
56 InactiveOrderState::Expired(state) => Some(state.time_exchange),
57 InactiveOrderState::OpenFailed(_) => None,
58 },
59 }
60 }
61
62 pub fn is_accepted(&self) -> bool {
72 !self.is_failed()
73 }
74
75 pub fn is_failed(&self) -> bool {
77 matches!(self, Self::Inactive(InactiveOrderState::OpenFailed(_)))
78 }
79}
80
81#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, From)]
82pub enum ActiveOrderState {
83 OpenInFlight(OpenInFlight),
84 Open(Open),
85 CancelInFlight(CancelInFlight),
86}
87
88impl ActiveOrderState {
89 pub fn open_meta(&self) -> Option<&Open> {
90 match self {
91 Self::OpenInFlight(_) => None,
92 Self::Open(open) => Some(open),
93 Self::CancelInFlight(cancel) => cancel.order.as_ref(),
94 }
95 }
96}
97
98#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
99pub struct OpenInFlight;
100
101#[derive(
102 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
103)]
104pub struct Open {
105 pub id: OrderId,
106 pub time_exchange: DateTime<Utc>,
107 pub filled_quantity: Decimal,
108}
109
110impl Open {
111 pub fn quantity_remaining(&self, initial_quantity: Decimal) -> Decimal {
112 initial_quantity - self.filled_quantity
113 }
114}
115
116#[derive(
121 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
122)]
123pub struct Filled {
124 pub id: OrderId,
125 pub time_exchange: DateTime<Utc>,
126 pub filled_quantity: Decimal,
127 pub avg_price: Option<Decimal>,
132}
133
134#[derive(
135 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default, Deserialize, Serialize, Constructor,
136)]
137pub struct CancelInFlight {
138 pub order: Option<Open>,
139}
140
141#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, From)]
142pub enum InactiveOrderState<AssetKey, InstrumentKey> {
143 Cancelled(Cancelled),
144 FullyFilled(Filled),
145 OpenFailed(OrderError<AssetKey, InstrumentKey>),
146 Expired(Expired),
147}
148
149#[derive(
154 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
155)]
156pub struct Cancelled {
157 pub id: OrderId,
158 pub time_exchange: DateTime<Utc>,
159 pub filled_quantity: Decimal,
164}
165
166#[derive(
171 Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
172)]
173pub struct Expired {
174 pub id: OrderId,
175 pub time_exchange: DateTime<Utc>,
176 pub filled_quantity: Decimal,
178}