Skip to main content

apple_quant_algorithmic/order/dependency/client/
submit.rs

1use smallvec::SmallVec;
2use tracing::instrument;
3
4#[allow(unused_imports)]
5use tracing::trace;
6
7use crate::{
8	backend::{OrderIdGenerator, OrdersBackend},
9	order::{
10		dependency::remote::{RemoteOrderAction, SubmitRemoteOrder},
11		ClientOrder, ClientOrderTracker, ClientTimingCondition, OrderAction,
12		OrderDependency, RemoteOrder, RemoteOrderTracker, RemoteTimingCondition,
13		StateGoal, TimingCondition, TriggerError,
14	},
15	order_manager::{OrderManager, OrdersCapacitySpec},
16	instrument::InstrumentSpec, price::BidAskPriceSpread, timestamp::TickTimestamp,
17	volume::DirectionalExposure,
18};
19
20use super::{ClientDeployedRemoteDependency, ClientOrderAction};
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub struct SubmitClientOrder<IS: InstrumentSpec> {
24	pub client_order_tracker: ClientOrderTracker,
25	pub client_order: ClientOrder<IS>,
26	pub client_deployed_remote_dependency: ClientDeployedRemoteDependency<IS>,
27
28	pub dependencies: Vec<(
29		ClientTimingCondition,
30		OrderAction<IS>,
31	)>,
32}
33
34impl<IS: InstrumentSpec> SubmitClientOrder<IS> {
35	pub fn new(
36		client_order_tracker: ClientOrderTracker,
37		client_order: ClientOrder<IS>,
38		remote_order_tracker: RemoteOrderTracker,
39		remote_order: RemoteOrder<IS>,
40		dependencies: impl IntoIterator<Item = (
41			TimingCondition,
42			OrderAction<IS>,
43		)>,
44	) -> Self {
45		let mut client_order_dependencies = Vec::with_capacity(4);
46
47		let dependencies = dependencies
48			.into_iter()
49			.filter_map(|dependency| {
50				match dependency.0 {
51					TimingCondition::Remote(
52						remote_timing_condition,
53					) => Some((remote_timing_condition, dependency.1)),
54					TimingCondition::Client(
55						client_timing_condition,
56					) => {
57						client_order_dependencies.push((
58							client_timing_condition,
59							dependency.1,
60						));
61
62						None
63					},
64				}
65			});
66
67		let submit_remote_order = SubmitRemoteOrder::new(
68			remote_order_tracker,
69			remote_order,
70			dependencies,
71		);
72
73		let client_deployed_remote_dependency = ClientDeployedRemoteDependency::new(
74			submit_remote_order,
75		);
76
77		Self {
78			client_order_tracker,
79			client_order,
80			client_deployed_remote_dependency,
81			dependencies: client_order_dependencies,
82		}
83	}
84
85	pub(crate) fn parent_processed(
86		&mut self,
87		bid_ask_price_spread: &BidAskPriceSpread<IS>,
88	) {
89		#[cfg(feature = "log-trace-order-actions")]
90		trace!(
91			"`parent_processed` called for order action: `{self:#?}` with `{bid_ask_price_spread:?}`."
92		);
93
94		self.client_order.parent_processed(bid_ask_price_spread);
95	}
96
97	pub fn into_order_action(
98		self,
99	) -> OrderAction<IS> {
100		self.into()
101	}
102}
103
104impl<IS: InstrumentSpec> OrderDependency<IS> for SubmitClientOrder<IS> {
105	#[instrument(skip_all)]
106	async fn trigger<
107		OB: OrdersBackend<IS>,
108		CS: OrdersCapacitySpec,
109	>(
110		&self,
111		tick_timestamp: &TickTimestamp,
112		order_manager: &mut OrderManager<IS, CS>,
113		orders_backend: &mut OB,
114		order_id_generator: &mut OrderIdGenerator,
115		directional_exposure: &mut DirectionalExposure<IS>,
116		state_goal: &mut StateGoal,
117	) -> Result<bool, TriggerError>
118	where
119		IS: Send,
120	{
121		#[cfg(feature = "log-trace-order-actions")]
122		trace!("Triggered order action: `{self:#?}`.");
123
124		let Self {
125			client_order_tracker,
126			client_order,
127			client_deployed_remote_dependency,
128			dependencies,
129		} = self;
130
131		order_manager.pending_client_orders.submit::<OB>(
132			tick_timestamp,
133			directional_exposure,
134			client_order_tracker,
135			client_order.clone(),
136			client_deployed_remote_dependency.clone(),
137			dependencies.clone(),
138		)?;
139
140		Ok(true)
141	}
142}