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}