Skip to main content

apple_quant_algorithmic/
order_manager.rs

1use thiserror::Error;
2
3use crate::{
4	backend::{LocalOrderId, OrderIdError, OrdersBackendSubmitRemoteOrderError, RemoteOrderId},
5	instrument::InstrumentSpec,
6	order::{
7		DesiredVolumeOrderError, OrderGoalAsExecutionExpectationError, OrderGoalT,
8		RemoveOrderGoalError, StateGoal,
9	},
10};
11
12mod capacity_spec;
13mod client_pending;
14mod completed;
15mod remote_pending;
16mod working;
17
18pub use capacity_spec::*;
19pub use client_pending::*;
20pub use completed::*;
21pub use remote_pending::*;
22pub use working::*;
23
24#[derive(Debug, Error)]
25pub enum SubmitRemoteOrderError {
26	#[error("{0:?}")]
27	OrdersBackendSubmitRemoteOrderError(#[from] OrdersBackendSubmitRemoteOrderError),
28
29	#[error("{0:?}")]
30	DesiredVolumeOrderError(#[from] DesiredVolumeOrderError),
31}
32
33#[derive(Debug, Error)]
34pub enum TryCancelRemoteOrderError {
35	#[error("Unable to cancel order that is in a remote pending state.")]
36	Pending(RemoteOrderId),
37
38	#[error("Unable to cancel order that is partially filled at remote.")]
39	ParitallyFilled(RemoteOrderId),
40
41	#[error("{0:?}")]
42	OrderIdError(#[from] OrderIdError),
43}
44
45#[derive(Debug, Error)]
46pub(crate) enum RemotePartialFillError {
47	#[error("{0:?}")]
48	TrasitionRemoteWorkingOrderError(#[from] TrasitionRemoteWorkingOrderError),
49
50	#[error("{0:?}")]
51	OrderIdError(#[from] OrderIdError),
52}
53
54#[derive(Debug, Error)]
55pub(crate) enum TrasitionLocalOrderError {
56	#[error("{0:?}")]
57	OrderIdError(#[from] OrderIdError),
58
59	#[error("{0:?}")]
60	OrdersBackendSubmitRemoteOrderError(#[from] OrdersBackendSubmitRemoteOrderError),
61
62	#[error(
63		"{local_order_id:?} already is paired with {existing_remote_order_id:?} when attemping to transition to  {attemped_remote_order_id:?}"
64	)]
65	AlreadyTransitioned {
66		local_order_id: LocalOrderId,
67		attemped_remote_order_id: RemoteOrderId,
68		existing_remote_order_id: RemoteOrderId,
69	},
70}
71
72#[derive(Debug, Error)]
73pub(crate) enum TransitionRemotePendingOrderError {
74	#[error("{0:?}")]
75	OrderIdError(#[from] OrderIdError),
76
77	#[error("{0:?}")]
78	OrderGoalAsExecutionExpectation(#[from] OrderGoalAsExecutionExpectationError),
79
80	#[error("{0:?}")]
81	RemoveOrderGoalError(#[from] RemoveOrderGoalError),
82
83	#[error("{local_order_id:?} is already in a working state under {remote_order_id:?}.")]
84	AlreadyWorking {
85		local_order_id: LocalOrderId,
86		remote_order_id: RemoteOrderId,
87	},
88
89	#[error("Unexpected {0:?}.")]
90	UnexpectedOrderGoal(OrderGoalT),
91}
92
93#[derive(Debug, Error)]
94pub(crate) enum TrasitionRemoteWorkingOrderError {
95	#[error("{0:?}")]
96	OrderIdError(#[from] OrderIdError),
97
98	#[error("{0:?}")]
99	RemoveOrderGoalError(#[from] RemoveOrderGoalError),
100
101	#[error("{0:?} already exists in a completed state.")]
102	AlreadyCompleted(RemoteOrderId),
103
104	#[error("Unexpected {0:?}.")]
105	UnexpectedOrderGoal(OrderGoalT),
106}
107
108#[derive(Debug, Error)]
109pub enum CancelOrderError {
110	#[error("No matching remote order id for: {0:?}")]
111	NoMatchingRemoteOrderId(LocalOrderId),
112
113	#[error("{0:?}")]
114	CancelLocalOrderError(#[from] CancelClientOrderError),
115
116	#[error("{0:?}")]
117	CancelRemoteOrderError(#[from] CancelRemoteOrderError),
118}
119
120#[derive(Debug, Error)]
121pub enum CancelClientOrderError {
122	#[error("{0:?}")]
123	OrderIdError(#[from] OrderIdError),
124}
125
126#[derive(Debug, Error)]
127pub enum CancelRemoteOrderError {
128	#[error("{0:?}")]
129	OrderIdError(#[from] OrderIdError),
130
131	#[error("{0:?}")]
132	DesiredVolumeOrderError(#[from] DesiredVolumeOrderError),
133
134	#[error("{0:?} has no RemoteOrderId assigned yet.")]
135	NoRemoteOrderId(LocalOrderId),
136}
137
138#[derive(Debug, Error)]
139pub enum CancelFlattenAllError {
140	#[error("Can not cancel flatten while there is an existing: {0:?}")]
141	ExistingStateGoal(StateGoal),
142}
143
144#[derive(Debug, Error)]
145pub enum RemoteCanceledRemoteOrderError {
146	#[error("{0:?}")]
147	OrderIdError(#[from] OrderIdError),
148
149	#[error("{0:?}")]
150	OrderGoalAsExecutionExpectationError(#[from] OrderGoalAsExecutionExpectationError),
151
152	#[error("Order was already fully filled.")]
153	FullyFilled,
154}
155
156#[derive(Debug, Error)]
157pub enum AssignRemoteOrderIdError {
158	#[error("{0:?}")]
159	OrderIdError(#[from] OrderIdError),
160
161	#[error(
162		"Failed to assign {remote_order_id:?} to order with {local_order_id:?}. Already assigned {existing_remote_order_id:?}"
163	)]
164	AlreadyAssigned {
165		local_order_id: LocalOrderId,
166		remote_order_id: RemoteOrderId,
167		existing_remote_order_id: RemoteOrderId,
168	},
169}
170
171#[derive(Debug)]
172pub enum OrderGroupMut<'a, IS: InstrumentSpec, CS: OrdersCapacitySpec> {
173	PendingClient(&'a mut PendingClientOrders<IS, CS>),
174	PendingRemote(&'a mut PendingRemoteOrders<IS, CS>),
175	WorkingRemote(&'a mut WorkingRemoteOrders<IS, CS>),
176	CompletedRemote(&'a mut CompletedRemoteOrders<IS, CS>),
177}
178
179#[derive(Debug)]
180pub enum OrderRef<'a, IS: InstrumentSpec, CS: OrdersCapacitySpec> {
181	PendingClient {
182		pending_client_order: &'a PendingClientOrder<IS>,
183		pending_client_orders: &'a PendingClientOrders<IS, CS>,
184	},
185	PendingRemote {
186		pending_remote_order: &'a PendingRemoteOrder<IS, CS>,
187		pending_remote_orders: &'a PendingRemoteOrders<IS, CS>,
188	},
189	WorkingRemote {
190		working_remote_order: &'a WorkingRemoteOrder<IS, CS>,
191		working_remote_orders: &'a WorkingRemoteOrders<IS, CS>,
192	},
193	CompletedRemote {
194		completed_remote_order: &'a CompletedRemoteOrder<IS, CS>,
195		completed_remote_orders: &'a CompletedRemoteOrders<IS, CS>,
196	},
197}
198
199#[derive(Debug)]
200pub enum OrderMut<'a, IS: InstrumentSpec, CS: OrdersCapacitySpec> {
201	PendingClient(&'a mut PendingClientOrder<IS>),
202	PendingRemote(&'a mut PendingRemoteOrder<IS, CS>),
203	WorkingRemote(&'a mut WorkingRemoteOrder<IS, CS>),
204	CompletedRemote(&'a mut CompletedRemoteOrder<IS, CS>),
205}
206
207#[derive(Debug)]
208pub struct OrderManager<IS: InstrumentSpec, CS: OrdersCapacitySpec> {
209	pub(crate) pending_client_orders: PendingClientOrders<IS, CS>,
210	pub(crate) pending_remote_orders: PendingRemoteOrders<IS, CS>,
211	pub(crate) working_remote_orders: WorkingRemoteOrders<IS, CS>,
212	pub(crate) completed_remote_orders: CompletedRemoteOrders<IS, CS>,
213}
214
215impl<IS: InstrumentSpec, CS: OrdersCapacitySpec> OrderManager<IS, CS> {
216	pub fn pending_client_orders(&self) -> &PendingClientOrders<IS, CS> {
217		&self.pending_client_orders
218	}
219
220	pub fn pending_remote_orders(&self) -> &PendingRemoteOrders<IS, CS> {
221		&self.pending_remote_orders
222	}
223
224	pub fn working_remote_orders(&self) -> &WorkingRemoteOrders<IS, CS> {
225		&self.working_remote_orders
226	}
227
228	pub fn completed_remote_orders(&self) -> &CompletedRemoteOrders<IS, CS> {
229		&self.completed_remote_orders
230	}
231
232	pub fn find_order(
233		&self,
234		local_order_id: &LocalOrderId,
235	) -> Result<OrderRef<'_, IS, CS>, OrderIdError> {
236		if let Ok(pending_client_order) = self
237			.pending_client_orders
238			.get(local_order_id)
239		{
240			return Ok(OrderRef::PendingClient {
241				pending_client_order,
242				pending_client_orders: &self.pending_client_orders,
243			});
244		}
245
246		if let Ok(pending_remote_order) = self
247			.pending_remote_orders
248			.get(local_order_id)
249		{
250			return Ok(OrderRef::PendingRemote {
251				pending_remote_order,
252				pending_remote_orders: &self.pending_remote_orders,
253			});
254		}
255
256		if let Ok(working_remote_order) = self
257			.working_remote_orders
258			.get(local_order_id)
259		{
260			return Ok(OrderRef::WorkingRemote {
261				working_remote_order,
262				working_remote_orders: &self.working_remote_orders,
263			});
264		}
265
266		if let Ok(completed_remote_order) = self
267			.completed_remote_orders
268			.get(local_order_id)
269		{
270			return Ok(OrderRef::CompletedRemote {
271				completed_remote_order,
272				completed_remote_orders: &self.completed_remote_orders,
273			});
274		}
275
276		local_order_id.err_invalid()
277	}
278
279	pub(crate) fn find_order_mut(
280		&mut self,
281		local_order_id: &LocalOrderId,
282	) -> Result<OrderMut<'_, IS, CS>, OrderIdError> {
283		if let Ok(pending_client_order) = self
284			.pending_client_orders
285			.get_mut(local_order_id)
286		{
287			return Ok(OrderMut::PendingClient(
288				pending_client_order,
289			));
290		}
291
292		if let Ok(pending_remote_order) = self
293			.pending_remote_orders
294			.get_mut(local_order_id)
295		{
296			return Ok(OrderMut::PendingRemote(
297				pending_remote_order,
298			));
299		}
300
301		if let Ok(working_remote_order) = self
302			.working_remote_orders
303			.get_mut(local_order_id)
304		{
305			return Ok(OrderMut::WorkingRemote(
306				working_remote_order,
307			));
308		}
309
310		if let Ok(completed_remote_order) = self
311			.completed_remote_orders
312			.get_mut(local_order_id)
313		{
314			return Ok(OrderMut::CompletedRemote(
315				completed_remote_order,
316			));
317		}
318
319		local_order_id.err_invalid()
320	}
321
322	pub(crate) fn find_order_group_mut(
323		&mut self,
324		local_order_id: &LocalOrderId,
325	) -> Result<OrderGroupMut<'_, IS, CS>, OrderIdError> {
326		if self
327			.pending_client_orders
328			.get(local_order_id)
329			.is_ok()
330		{
331			return Ok(OrderGroupMut::PendingClient(
332				&mut self.pending_client_orders,
333			));
334		}
335
336		if self
337			.pending_remote_orders
338			.get(local_order_id)
339			.is_ok()
340		{
341			return Ok(OrderGroupMut::PendingRemote(
342				&mut self.pending_remote_orders,
343			));
344		}
345
346		if self
347			.working_remote_orders
348			.get(local_order_id)
349			.is_ok()
350		{
351			return Ok(OrderGroupMut::WorkingRemote(
352				&mut self.working_remote_orders,
353			));
354		}
355
356		if self
357			.completed_remote_orders
358			.get(local_order_id)
359			.is_ok()
360		{
361			return Ok(OrderGroupMut::CompletedRemote(&mut self.completed_remote_orders));
362		}
363
364		local_order_id.err_invalid()
365	}
366}
367
368impl<IS: InstrumentSpec, CS: OrdersCapacitySpec> Default for OrderManager<IS, CS> {
369	fn default() -> Self {
370		Self {
371			pending_client_orders: PendingClientOrders::default(),
372			pending_remote_orders: PendingRemoteOrders::default(),
373			working_remote_orders: WorkingRemoteOrders::default(),
374			completed_remote_orders: CompletedRemoteOrders::default(),
375		}
376	}
377}