apple_quant_algorithmic/order/dependency/client/
submit.rs1use 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}