apple_quant_algorithmic/order/
goal.rs1use bevy::prelude::Deref;
2use smallvec::SmallVec;
3use thiserror::Error;
4
5use crate::{backend::LocalOrderId, instrument::InstrumentSpec, volume::DirectionalIntentVolume};
6
7use super::OrderExecutionExpectation;
8
9#[derive(Debug, Error)]
10pub(crate) enum AddOrderGoalError {
11 #[error("{0:?} already exists.")]
12 AlreadyExists(OrderGoalT),
13}
14
15#[derive(Debug, Error)]
16pub(crate) enum RemoveOrderGoalError {
17 #[error("{0:?} already exists.")]
18 AlreadyExists(OrderGoalT),
19}
20
21#[derive(Debug, Error)]
22pub enum OrderGoalAsExecutionExpectationError {
23 #[error("Can not convert {0:?} to an OrderExecutionExpectation.")]
24 InvalidConversion(OrderGoalT),
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub enum OrderGoalT {
29 CancelOrder,
30 CancelRevertOrder,
31 SubmitImmediatelyExecutableRemoteOrder,
32 SubmitRestingRemoteOrder,
33}
34
35impl<IS: InstrumentSpec> From<OrderGoal<IS>> for OrderGoalT {
36 fn from(value: OrderGoal<IS>) -> Self {
37 (&value).into()
38 }
39}
40
41impl<IS: InstrumentSpec> From<&OrderGoal<IS>> for OrderGoalT {
42 fn from(value: &OrderGoal<IS>) -> Self {
43 match value {
44 OrderGoal::CancelOrder(_) => Self::CancelOrder,
45 OrderGoal::CancelRevertOrder(_) => Self::CancelRevertOrder,
46 OrderGoal::SubmitImmediatelyExecutableRemoteOrder {
47 local_order_id: _,
48 directional_intent_volume: _,
49 } => Self::SubmitImmediatelyExecutableRemoteOrder,
50 OrderGoal::SubmitRestingRemoteOrder {
51 local_order_id: _,
52 directional_intent_volume: _,
53 } => Self::SubmitRestingRemoteOrder,
54 }
55 }
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
59pub enum OrderGoal<IS: InstrumentSpec> {
60 CancelOrder(LocalOrderId),
62
63 CancelRevertOrder(LocalOrderId),
65
66 SubmitImmediatelyExecutableRemoteOrder {
68 local_order_id: LocalOrderId,
69 directional_intent_volume: DirectionalIntentVolume<IS>,
70 },
71
72 SubmitRestingRemoteOrder {
74 local_order_id: LocalOrderId,
75 directional_intent_volume: DirectionalIntentVolume<IS>,
76 },
77}
78
79impl<IS: InstrumentSpec> OrderGoal<IS> {
80 pub fn new_submit_remote_with_execution_expectation(
81 local_order_id: LocalOrderId,
82 directional_intent_volume: DirectionalIntentVolume<IS>,
83 order_execution_expectation: OrderExecutionExpectation,
84 ) -> Self {
85 match order_execution_expectation {
86 OrderExecutionExpectation::Immediate => Self::SubmitImmediatelyExecutableRemoteOrder {
87 local_order_id,
88 directional_intent_volume,
89 },
90 OrderExecutionExpectation::Resting => Self::SubmitRestingRemoteOrder {
91 local_order_id,
92 directional_intent_volume,
93 },
94 }
95 }
96
97 pub fn as_order_execution_expectation(
98 &self
99 ) -> Result<OrderExecutionExpectation, OrderGoalAsExecutionExpectationError> {
100 match self {
101 Self::CancelOrder(_) => {
102 Err(OrderGoalAsExecutionExpectationError::InvalidConversion(self.as_t()))
103 }
104 Self::CancelRevertOrder(_) => {
105 Err(OrderGoalAsExecutionExpectationError::InvalidConversion(self.as_t()))
106 }
107 Self::SubmitImmediatelyExecutableRemoteOrder {
108 local_order_id: _,
109 directional_intent_volume: _,
110 } => Ok(OrderExecutionExpectation::Immediate),
111 Self::SubmitRestingRemoteOrder {
112 local_order_id: _,
113 directional_intent_volume: _,
114 } => Ok(OrderExecutionExpectation::Resting),
115 }
116 }
117
118 pub fn as_local_order_id(&self) -> Result<&LocalOrderId, ()> {
119 match self {
120 Self::CancelOrder(local_order_id) => Ok(local_order_id),
121 Self::CancelRevertOrder(local_order_id) => Ok(local_order_id),
122 Self::SubmitImmediatelyExecutableRemoteOrder {
123 local_order_id,
124 directional_intent_volume,
125 } => Ok(local_order_id),
126 Self::SubmitRestingRemoteOrder {
127 local_order_id,
128 directional_intent_volume,
129 } => Ok(local_order_id),
130 }
131 }
132
133 pub fn as_directional_intent_volume(&self) -> Result<&DirectionalIntentVolume<IS>, ()> {
134 match self {
135 Self::CancelOrder(_) => Err(()),
136 Self::CancelRevertOrder(_) => Err(()),
137 Self::SubmitImmediatelyExecutableRemoteOrder {
138 local_order_id: _,
139 directional_intent_volume,
140 } => Ok(directional_intent_volume),
141 Self::SubmitRestingRemoteOrder {
142 local_order_id: _,
143 directional_intent_volume,
144 } => Ok(directional_intent_volume),
145 }
146 }
147
148 pub fn as_t(&self) -> OrderGoalT {
149 self.into()
150 }
151}
152
153#[derive(Debug)]
154pub struct ActiveOrderGoals<IS: InstrumentSpec>(SmallVec<[OrderGoal<IS>; 4]>);
155
156impl<IS: InstrumentSpec> ActiveOrderGoals<IS> {
157 pub(crate) fn reset(&mut self) {
158 self.0.clear()
159 }
160
161 pub(crate) fn add_order_goal(
162 &mut self,
163 order_goal: OrderGoal<IS>,
164 ) -> Result<(), AddOrderGoalError> {
165 if self
166 .0
167 .iter()
168 .find(|&iter_order_goal| iter_order_goal == &order_goal)
169 .is_some()
170 {
171 return Err(AddOrderGoalError::AlreadyExists(order_goal.as_t()));
172 }
173
174 self.0.push(order_goal);
175 Ok(())
176 }
177
178 pub(crate) fn remove_order_goal(
179 &mut self,
180 order_goal: &OrderGoal<IS>,
181 ) -> Result<(), RemoveOrderGoalError> {
182 let Some(active_order_goals_idx) = self
183 .0
184 .iter()
185 .position(|iter_order_goal| iter_order_goal == order_goal)
186 else {
187 return Err(RemoveOrderGoalError::AlreadyExists(order_goal.as_t()));
188 };
189
190 self.0
191 .swap_remove(active_order_goals_idx);
192 Ok(())
193 }
194
195 pub fn contains(
196 &self,
197 order_goal: &OrderGoal<IS>,
198 ) -> bool {
199 self.0.contains(order_goal)
200 }
201}
202
203impl<IS: InstrumentSpec> Default for ActiveOrderGoals<IS> {
204 fn default() -> Self {
205 Self(SmallVec::default())
206 }
207}
208
209#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
210pub enum StateGoal {
211 CancelAll,
212 CancelFlattenAll,
213 CancelFlattenAllShutdown,
214 CancelFlattenAllRestart,
215}
216
217impl StateGoal {
218 pub fn completed_result(&self) -> UpdateStateGoalResult {
219 match self {
220 Self::CancelAll => UpdateStateGoalResult::Inactive,
221 Self::CancelFlattenAll => UpdateStateGoalResult::Inactive,
222 Self::CancelFlattenAllShutdown => UpdateStateGoalResult::Shutdown,
223 Self::CancelFlattenAllRestart => UpdateStateGoalResult::Restart,
224 }
225 }
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
229pub enum UpdateStateGoalResult {
230 Active,
231 Inactive,
232 Shutdown,
233 Restart,
234}
235
236#[derive(Debug, Default, Deref)]
237pub struct ActiveStateGoal(Option<StateGoal>);