Skip to main content

apple_quant_algorithmic/order_manager/
completed.rs

1use smallvec::SmallVec;
2use tracing::instrument;
3
4#[allow(unused_imports)]
5use tracing::trace;
6
7use crate::{
8	backend::{LocalOrderId, OrderIdError, OrdersBackend, RemoteOrderId},
9	timestamp::{TickTimestamp, Timestamp, Timestamped},
10	instrument::InstrumentSpec, order::PartialOrderFill,
11};
12
13use super::{working::WorkingRemoteOrder, OrdersCapacitySpec};
14
15pub struct CompletedRemoteOrder<
16	IS: InstrumentSpec,
17	CS: OrdersCapacitySpec,
18> {
19	pub(crate) completed_timestamp: Timestamp,
20	pub(crate) local_order_id: LocalOrderId,
21	pub(crate) remote_order_id: RemoteOrderId,
22
23	pub(crate) partial_order_fills: SmallVec<[PartialOrderFill<IS>; core::direct_const_arg!(
24		CS::PARTIAL_FILL
25	)]>,
26}
27
28impl<
29	IS: InstrumentSpec,
30	CS: OrdersCapacitySpec,
31> CompletedRemoteOrder<IS, CS> {
32	pub(crate) fn new(
33		completed_timestamp: Timestamp,
34		local_order_id: LocalOrderId,
35		remote_order_id: RemoteOrderId,
36		partial_order_fills: impl IntoIterator<Item = PartialOrderFill<IS>>,
37	) -> Self {
38		Self {
39			completed_timestamp,
40			local_order_id,
41			remote_order_id,
42			partial_order_fills: partial_order_fills.into_iter().collect(),
43		}
44	}
45}
46
47/// Unordered collection of completed remote orders. Only when the client has confirmed these orders have either been 100% filled by the matching engine or canceled will it transition state to [`filled_remote_orders`].
48pub struct CompletedRemoteOrders<
49	IS: InstrumentSpec,
50	CS: OrdersCapacitySpec,
51>(SmallVec<[CompletedRemoteOrder<IS, CS>; core::direct_const_arg!(
52		CS::COMPLETED_REMOTE
53	)]>);
54
55impl<
56	IS: InstrumentSpec,
57	CS: OrdersCapacitySpec,
58> CompletedRemoteOrders<IS, CS> {
59	#[instrument(skip_all)]
60	pub fn submit<OB: OrdersBackend<IS>>(
61		&mut self,
62		tick_timestamp: &TickTimestamp,
63		working_remote_order: WorkingRemoteOrder<IS, CS>,
64	)
65	where
66		IS: Send,
67	{
68		#[cfg(feature = "log-trace-order-manager")]
69		trace!("Adding id: `{:?}`.", working_remote_order.local_order_id);
70
71		let completed_timestamp = tick_timestamp.timestamp();
72
73		let completed_remote_order = CompletedRemoteOrder::new(
74			completed_timestamp,
75			working_remote_order.local_order_id,
76			working_remote_order.remote_order_id,
77			working_remote_order.partial_order_fills,
78		);
79
80		self.0.push(completed_remote_order);
81	}
82
83	#[instrument(skip_all)]
84	pub fn get(
85		&self,
86		local_order_id: &LocalOrderId,
87	) -> Result<&CompletedRemoteOrder<IS, CS>, OrderIdError> {
88		let Some(
89			completed_remote_order,
90		) = self.0.iter().find(|
91			completed_remote_order,
92		| &completed_remote_order.local_order_id == local_order_id) else {
93			return local_order_id.err_invalid();
94		};
95
96		Ok(completed_remote_order)
97	}
98
99	#[instrument(skip_all)]
100	pub(crate) fn get_mut(
101		&mut self,
102		local_order_id: &LocalOrderId,
103	) -> Result<&mut CompletedRemoteOrder<IS, CS>, OrderIdError> {
104		let Some(
105			completed_remote_order,
106		) = self.0.iter_mut().find(|
107			completed_remote_order,
108		| &completed_remote_order.local_order_id == local_order_id) else {
109			return local_order_id.err_invalid();
110		};
111
112		Ok(completed_remote_order)
113	}
114}
115
116impl<
117	IS: InstrumentSpec,
118	CS: OrdersCapacitySpec,
119> Default for CompletedRemoteOrders<IS, CS> {
120	fn default() -> Self {
121		Self(SmallVec::default())
122	}
123}