Skip to main content

apple_quant_algorithmic/order/
builder.rs

1pub mod fill_policy;
2mod dependency;
3
4use dependency::{
5	ClientOrderBuilderDependency, OrderBuilderDependencies, RemoteOrderBuilderDependency,
6};
7
8use fill_policy::{FillPolicy, FillPolicyEnum};
9
10use crate::{
11	volume::{
12		AggressiveVolume, AggressorSide, DirectionalIntent, DirectionlessVolume,
13		RestingSide, RestingVolume,
14	},
15	backend::OrderIdGenerator, instrument::InstrumentSpec, points::Subpoints,
16	price::ProtoabsolutePrice,
17};
18
19use super::{
20	dependency::{client::SubmitClientOrder, remote::SubmitRemoteOrder},
21	ClientOrder, ClientOrderTracker, ClientStopOrder, ComplexOrderTracker,
22	DeferredOrderActions, DesiredVolumeOrderError, LimitOrder, MarketOrder, OrderAction,
23	OrderExecutionExpectation, OrderTracker, RemoteOrder, RemoteOrderTracker,
24	RemoteTimingCondition,
25};
26
27#[derive(Debug)]
28pub struct RemoteOrderBuilder<
29	'a,
30	IS: InstrumentSpec,
31	const INLINE_LEN: usize = 4,
32> {
33	order_id_generator: &'a mut OrderIdGenerator,
34	order: RemoteOrder<IS>,
35	tracker: RemoteOrderTracker,
36	dependencies: OrderBuilderDependencies<IS, INLINE_LEN>,
37}
38
39impl<
40	'a,
41	IS: InstrumentSpec,
42	const INLINE_LEN: usize,
43> RemoteOrderBuilder<'a, IS, INLINE_LEN> {
44	pub fn new_market(
45		order_id_generator: &'a mut OrderIdGenerator,
46		aggressive_volume: AggressiveVolume<IS>,
47	) -> Result<Self, DesiredVolumeOrderError> {
48		let (
49			order,
50			tracker,
51		) = single_remote_market(order_id_generator, aggressive_volume)?;
52
53		let dependencies = OrderBuilderDependencies::default();
54
55		Ok(Self {
56			order_id_generator,
57			order,
58			tracker,
59			dependencies,
60		})
61	}
62
63	pub fn new_market_parts(
64		order_id_generator: &'a mut OrderIdGenerator,
65		aggressor_side: AggressorSide,
66		directionless_volume: DirectionlessVolume<IS>,
67	) -> Result<Self, DesiredVolumeOrderError> {
68		let aggressive_volume = AggressiveVolume {
69			directionless_volume,
70			aggressor_side,
71		};
72
73		Self::new_market(order_id_generator, aggressive_volume)
74	}
75
76	pub fn new_market_subpoints(
77		order_id_generator: &'a mut OrderIdGenerator,
78		aggressor_side: AggressorSide,
79		subpoints: impl Into<Subpoints>,
80	) -> Result<Self, DesiredVolumeOrderError> {
81		let subpoints_volume = subpoints.into();
82		let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
83
84		Self::new_market_parts(order_id_generator, aggressor_side, directionless_volume)
85	}
86
87	pub fn new_limit(
88		order_id_generator: &'a mut OrderIdGenerator,
89		resting_volume: RestingVolume<IS>,
90		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
91		order_execution_expectation: OrderExecutionExpectation,
92	) -> Result<Self, DesiredVolumeOrderError> {
93		let (
94			order,
95			tracker,
96		) = single_remote_limit(
97			order_id_generator,
98			resting_volume,
99			protoabsolute_price.into(),
100			order_execution_expectation,
101		)?;
102
103		let dependencies = OrderBuilderDependencies::default();
104
105		Ok(Self {
106			order_id_generator,
107			order,
108			tracker,
109			dependencies,
110		})
111	}
112
113	pub fn new_limit_parts(
114		order_id_generator: &'a mut OrderIdGenerator,
115		directionless_volume: DirectionlessVolume<IS>,
116		resting_side: RestingSide,
117		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
118		order_execution_expectation: OrderExecutionExpectation,
119	) -> Result<Self, DesiredVolumeOrderError> {
120		let resting_volume = RestingVolume {
121			directionless_volume,
122			resting_side,
123		};
124
125		Self::new_limit(
126			order_id_generator,
127			resting_volume,
128			protoabsolute_price,
129			order_execution_expectation,
130		)
131	}
132
133	pub fn new_limit_subpoints(
134		order_id_generator: &'a mut OrderIdGenerator,
135		resting_side: RestingSide,
136		subpoints: impl Into<Subpoints>,
137		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
138		order_execution_expectation: OrderExecutionExpectation,
139	) -> Result<Self, DesiredVolumeOrderError> {
140		let subpoints_volume = subpoints.into();
141		let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
142
143		Self::new_limit_parts(
144			order_id_generator,
145			directionless_volume,
146			resting_side,
147			protoabsolute_price,
148			order_execution_expectation,
149		)
150	}
151
152	pub fn with_market(
153		mut self,
154		aggressive_volume: AggressiveVolume<IS>,
155		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
156	) -> Result<Self, DesiredVolumeOrderError> {
157		let fill_policy = fill_policy.into();
158
159		let (
160			order,
161			tracker,
162		) = single_remote_market(self.order_id_generator, aggressive_volume)?;
163
164		let dependency = RemoteOrderBuilderDependency { tracker, order, fill_policy };
165
166		self.dependencies.push(dependency.into());
167		Ok(self)
168	}
169
170	pub fn with_market_parts(
171		self,
172		directionless_volume: DirectionlessVolume<IS>,
173		aggressor_side: AggressorSide,
174		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
175	) -> Result<Self, DesiredVolumeOrderError> {
176		let aggressive_volume = AggressiveVolume {
177			directionless_volume,
178			aggressor_side,
179		};
180
181		self.with_market(aggressive_volume, fill_policy)
182	}
183
184	pub fn with_market_subpoints(
185		self,
186		aggressor_side: AggressorSide,
187		subpoints: impl Into<Subpoints>,
188		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
189	) -> Result<Self, DesiredVolumeOrderError> {
190		let subpoints_volume = subpoints.into();
191		let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
192
193		self.with_market_parts(directionless_volume, aggressor_side, fill_policy)
194	}
195
196	pub fn with_limit(
197		mut self,
198		resting_volume: RestingVolume<IS>,
199		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
200		order_execution_expectation: OrderExecutionExpectation,
201		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
202	) -> Result<Self, DesiredVolumeOrderError> {
203		let fill_policy = fill_policy.into();
204
205		let (
206			order,
207			tracker,
208		) = single_remote_limit(
209			self.order_id_generator,
210			resting_volume,
211			protoabsolute_price.into(),
212			order_execution_expectation,
213		)?;
214
215		let dependency = RemoteOrderBuilderDependency { tracker, order, fill_policy };
216
217		self.dependencies.push(dependency.into());
218		Ok(self)
219	}
220
221	pub fn with_limit_parts(
222		self,
223		directionless_volume: DirectionlessVolume<IS>,
224		resting_side: RestingSide,
225		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
226		order_execution_expectation: OrderExecutionExpectation,
227		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
228	) -> Result<Self, DesiredVolumeOrderError> {
229		let resting_volume = RestingVolume {
230			directionless_volume,
231			resting_side,
232		};
233
234		self.with_limit(
235			resting_volume,
236			protoabsolute_price,
237			order_execution_expectation,
238			fill_policy,
239		)
240	}
241
242	pub fn with_limit_subpoints(
243		self,
244		resting_side: RestingSide,
245		subpoints: impl Into<Subpoints>,
246		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
247		order_execution_expectation: OrderExecutionExpectation,
248		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
249	) -> Result<Self, DesiredVolumeOrderError> {
250		let subpoints_volume = subpoints.into();
251		let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
252
253		self.with_limit_parts(
254			directionless_volume,
255			resting_side,
256			protoabsolute_price,
257			order_execution_expectation,
258			fill_policy,
259		)
260	}
261
262	pub fn with_stop_market(
263		mut self,
264		aggressive_volume: AggressiveVolume<IS>,
265		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
266		cross_over_directional_intent: DirectionalIntent,
267		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
268	) -> Result<Self, DesiredVolumeOrderError> {
269		let fill_policy = fill_policy.into();
270
271		let (
272			client_order,
273			client_tracker,
274			remote_order,
275			remote_tracker,
276		) = single_client_stop_market(
277			self.order_id_generator,
278			aggressive_volume,
279			protoabsolute_price.into(),
280			cross_over_directional_intent,
281		)?;
282
283		let dependency = ClientOrderBuilderDependency {
284			client_tracker,
285			client_order,
286			remote_tracker,
287			remote_order,
288			fill_policy,
289		};
290
291		self.dependencies.push(dependency.into());
292		Ok(self)
293	}
294
295	pub fn with_stop_market_parts(
296		self,
297		directionless_volume: DirectionlessVolume<IS>,
298		aggressor_side: AggressorSide,
299		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
300		cross_over_directional_intent: DirectionalIntent,
301		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
302	) -> Result<Self, DesiredVolumeOrderError> {
303		let aggressive_volume = AggressiveVolume {
304			directionless_volume,
305			aggressor_side,
306		};
307
308		self.with_stop_market(
309			aggressive_volume,
310			protoabsolute_price,
311			cross_over_directional_intent,
312			fill_policy,
313		)
314	}
315
316	pub fn with_stop_market_subpoints(
317		self,
318		aggressor_side: AggressorSide,
319		subpoints: impl Into<Subpoints>,
320		protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
321		cross_over_directional_intent: DirectionalIntent,
322		fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
323	) -> Result<Self, DesiredVolumeOrderError> {
324		let subpoints_volume = subpoints.into();
325		let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
326
327		self.with_stop_market_parts(
328			directionless_volume,
329			aggressor_side,
330			protoabsolute_price,
331			cross_over_directional_intent,
332			fill_policy,
333		)
334	}
335
336	pub fn into_condensed(
337		self,
338	) -> CondensedOrderBuilder<IS> {
339		let Self {
340			order_id_generator: _,
341			order,
342			tracker,
343			dependencies,
344		} = self;
345
346		let dependencies = dependencies
347			.iter()
348			.map(|dependency| {
349				let submit_order_action = dependency.create_submit_order_action(
350					&dependencies,
351				);
352
353				let remote_timing_condition = RemoteTimingCondition::FullyFilled;
354
355				(remote_timing_condition, submit_order_action)
356			});
357
358		let submit_remote_order = SubmitRemoteOrder::new(tracker, order, dependencies);
359		CondensedOrderBuilder::Remote(submit_remote_order)
360	}
361
362	pub fn submit<const INLINE_COUNT: usize>(
363		self,
364		deferred_order_actions: &mut DeferredOrderActions<IS>,
365	) -> ComplexOrderTracker<INLINE_COUNT> {
366		self.into_condensed().submit(deferred_order_actions)
367	}
368}
369
370#[derive(Debug, PartialEq, Eq, Hash)]
371pub enum CondensedOrderBuilder<IS: InstrumentSpec> {
372	Remote(SubmitRemoteOrder<IS>),
373	Client(SubmitClientOrder<IS>),
374}
375
376impl<IS: InstrumentSpec> CondensedOrderBuilder<IS> {
377	pub fn submit<const INLINE_COUNT: usize>(
378		self,
379		deferred_order_actions: &mut DeferredOrderActions<IS>,
380	) -> ComplexOrderTracker<INLINE_COUNT> {
381		let (
382			order_action,
383			complex_order_tracker,
384		) = self.into_order_action();
385
386		deferred_order_actions.push(order_action);
387		complex_order_tracker
388	}
389
390	pub fn into_order_action<const INLINE_COUNT: usize>(
391		self,
392	) -> (
393		OrderAction<IS>,
394		ComplexOrderTracker<INLINE_COUNT>,
395	) {
396		match self {
397			Self::Remote(
398				dependency,
399			) => {
400				let parent = OrderTracker::Remote(dependency.remote_order_tracker);
401
402				let dependencies = dependency
403					.dependencies
404					.iter()
405					.map(|(
406						_,
407						order_action,
408					)| {
409						match order_action {
410							OrderAction::SubmitRemote(
411								submit_remote_order,
412							) => {
413								OrderTracker::Remote(submit_remote_order.remote_order_tracker)
414							},
415							OrderAction::SubmitClient(
416								submit_client_order,
417							) => {
418								OrderTracker::Client(submit_client_order.client_order_tracker)
419							},
420							_ => unreachable!(),
421						}
422					}).collect();
423
424				(
425					dependency.into_order_action(),
426					ComplexOrderTracker { parent, dependencies },
427				)
428			},
429			Self::Client(
430				dependency,
431			) => {
432				let parent = OrderTracker::Client(dependency.client_order_tracker);
433
434				let dependencies = dependency
435					.client_deployed_remote_dependency
436					.dependencies
437					.iter()
438					.map(|(
439						_,
440						order_action,
441					)| {
442						match order_action {
443							OrderAction::SubmitRemote(
444								submit_remote_order,
445							) => {
446								OrderTracker::Remote(submit_remote_order.remote_order_tracker)
447							},
448							OrderAction::SubmitClient(
449								submit_client_order,
450							) => {
451								OrderTracker::Client(submit_client_order.client_order_tracker)
452							},
453							_ => unreachable!(),
454						}
455					}).collect();
456
457				(
458					dependency.into_order_action(),
459					ComplexOrderTracker { parent, dependencies },
460				)
461			},
462		}
463	}
464}
465
466fn single_remote_market<IS: InstrumentSpec>(
467	order_id_generator: &mut OrderIdGenerator,
468	aggressive_volume: AggressiveVolume<IS>,
469) -> Result<
470	(
471		RemoteOrder<IS>,
472		RemoteOrderTracker,
473	),
474	DesiredVolumeOrderError,
475> {
476	let remote_order = MarketOrder::new(aggressive_volume).into_remote();
477	let remote_order_tracker = remote_order.register(order_id_generator)?;
478
479	Ok((remote_order, remote_order_tracker))
480}
481
482fn single_remote_limit<IS: InstrumentSpec>(
483	order_id_generator: &mut OrderIdGenerator,
484	resting_volume: RestingVolume<IS>,
485	price: ProtoabsolutePrice<IS>,
486	order_execution_expectation: OrderExecutionExpectation,
487) -> Result<
488	(
489		RemoteOrder<IS>,
490		RemoteOrderTracker,
491	),
492	DesiredVolumeOrderError,
493> {
494	let remote_order = LimitOrder::new(
495		price,
496		resting_volume,
497		order_execution_expectation,
498	).into_remote();
499
500	let remote_order_tracker = remote_order.register(order_id_generator)?;
501
502	Ok((remote_order, remote_order_tracker))
503}
504
505fn single_client_stop_market<IS: InstrumentSpec>(
506	order_id_generator: &mut OrderIdGenerator,
507	aggressive_volume: AggressiveVolume<IS>,
508	protoabsolute_price: ProtoabsolutePrice<IS>,
509	cross_over_directional_intent: DirectionalIntent,
510) -> Result<
511	(
512		ClientOrder<IS>,
513		ClientOrderTracker,
514		RemoteOrder<IS>,
515		RemoteOrderTracker,
516	),
517	DesiredVolumeOrderError,
518> {
519	let client_order = ClientStopOrder::new(
520		protoabsolute_price,
521		cross_over_directional_intent,
522	).into_client_order();
523
524	let client_order_tracker = client_order.register(order_id_generator);
525	let remote_order = MarketOrder::new(aggressive_volume).into_remote();
526	let remote_order_tracker = remote_order.register(order_id_generator)?;
527
528	Ok((client_order, client_order_tracker, remote_order, remote_order_tracker))
529}