pub mod fill_policy;
mod dependency;
use dependency::{
ClientOrderBuilderDependency, OrderBuilderDependencies, RemoteOrderBuilderDependency,
};
use fill_policy::{FillPolicy, FillPolicyEnum};
use crate::{
volume::{
AggressiveVolume, AggressorSide, DirectionalIntent, DirectionlessVolume,
RestingSide, RestingVolume,
},
backend::OrderIdGenerator, instrument::InstrumentSpec, points::Subpoints,
price::ProtoabsolutePrice,
};
use super::{
dependency::{client::SubmitClientOrder, remote::SubmitRemoteOrder},
ClientOrder, ClientOrderTracker, ClientStopOrder, ComplexOrderTracker,
DeferredOrderActions, DesiredVolumeOrderError, LimitOrder, MarketOrder, OrderAction,
OrderExecutionExpectation, OrderTracker, RemoteOrder, RemoteOrderTracker,
RemoteTimingCondition,
};
#[derive(Debug)]
pub struct RemoteOrderBuilder<
'a,
IS: InstrumentSpec,
const INLINE_LEN: usize = 4,
> {
order_id_generator: &'a mut OrderIdGenerator,
order: RemoteOrder<IS>,
tracker: RemoteOrderTracker,
dependencies: OrderBuilderDependencies<IS, INLINE_LEN>,
}
impl<
'a,
IS: InstrumentSpec,
const INLINE_LEN: usize,
> RemoteOrderBuilder<'a, IS, INLINE_LEN> {
pub fn new_market(
order_id_generator: &'a mut OrderIdGenerator,
aggressive_volume: AggressiveVolume<IS>,
) -> Result<Self, DesiredVolumeOrderError> {
let (
order,
tracker,
) = single_remote_market(order_id_generator, aggressive_volume)?;
let dependencies = OrderBuilderDependencies::default();
Ok(Self {
order_id_generator,
order,
tracker,
dependencies,
})
}
pub fn new_market_parts(
order_id_generator: &'a mut OrderIdGenerator,
aggressor_side: AggressorSide,
directionless_volume: DirectionlessVolume<IS>,
) -> Result<Self, DesiredVolumeOrderError> {
let aggressive_volume = AggressiveVolume {
directionless_volume,
aggressor_side,
};
Self::new_market(order_id_generator, aggressive_volume)
}
pub fn new_market_subpoints(
order_id_generator: &'a mut OrderIdGenerator,
aggressor_side: AggressorSide,
subpoints: impl Into<Subpoints>,
) -> Result<Self, DesiredVolumeOrderError> {
let subpoints_volume = subpoints.into();
let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
Self::new_market_parts(order_id_generator, aggressor_side, directionless_volume)
}
pub fn new_limit(
order_id_generator: &'a mut OrderIdGenerator,
resting_volume: RestingVolume<IS>,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
order_execution_expectation: OrderExecutionExpectation,
) -> Result<Self, DesiredVolumeOrderError> {
let (
order,
tracker,
) = single_remote_limit(
order_id_generator,
resting_volume,
protoabsolute_price.into(),
order_execution_expectation,
)?;
let dependencies = OrderBuilderDependencies::default();
Ok(Self {
order_id_generator,
order,
tracker,
dependencies,
})
}
pub fn new_limit_parts(
order_id_generator: &'a mut OrderIdGenerator,
directionless_volume: DirectionlessVolume<IS>,
resting_side: RestingSide,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
order_execution_expectation: OrderExecutionExpectation,
) -> Result<Self, DesiredVolumeOrderError> {
let resting_volume = RestingVolume {
directionless_volume,
resting_side,
};
Self::new_limit(
order_id_generator,
resting_volume,
protoabsolute_price,
order_execution_expectation,
)
}
pub fn new_limit_subpoints(
order_id_generator: &'a mut OrderIdGenerator,
resting_side: RestingSide,
subpoints: impl Into<Subpoints>,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
order_execution_expectation: OrderExecutionExpectation,
) -> Result<Self, DesiredVolumeOrderError> {
let subpoints_volume = subpoints.into();
let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
Self::new_limit_parts(
order_id_generator,
directionless_volume,
resting_side,
protoabsolute_price,
order_execution_expectation,
)
}
pub fn with_market(
mut self,
aggressive_volume: AggressiveVolume<IS>,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let fill_policy = fill_policy.into();
let (
order,
tracker,
) = single_remote_market(self.order_id_generator, aggressive_volume)?;
let dependency = RemoteOrderBuilderDependency { tracker, order, fill_policy };
self.dependencies.push(dependency.into());
Ok(self)
}
pub fn with_market_parts(
self,
directionless_volume: DirectionlessVolume<IS>,
aggressor_side: AggressorSide,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let aggressive_volume = AggressiveVolume {
directionless_volume,
aggressor_side,
};
self.with_market(aggressive_volume, fill_policy)
}
pub fn with_market_subpoints(
self,
aggressor_side: AggressorSide,
subpoints: impl Into<Subpoints>,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let subpoints_volume = subpoints.into();
let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
self.with_market_parts(directionless_volume, aggressor_side, fill_policy)
}
pub fn with_limit(
mut self,
resting_volume: RestingVolume<IS>,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
order_execution_expectation: OrderExecutionExpectation,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let fill_policy = fill_policy.into();
let (
order,
tracker,
) = single_remote_limit(
self.order_id_generator,
resting_volume,
protoabsolute_price.into(),
order_execution_expectation,
)?;
let dependency = RemoteOrderBuilderDependency { tracker, order, fill_policy };
self.dependencies.push(dependency.into());
Ok(self)
}
pub fn with_limit_parts(
self,
directionless_volume: DirectionlessVolume<IS>,
resting_side: RestingSide,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
order_execution_expectation: OrderExecutionExpectation,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let resting_volume = RestingVolume {
directionless_volume,
resting_side,
};
self.with_limit(
resting_volume,
protoabsolute_price,
order_execution_expectation,
fill_policy,
)
}
pub fn with_limit_subpoints(
self,
resting_side: RestingSide,
subpoints: impl Into<Subpoints>,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
order_execution_expectation: OrderExecutionExpectation,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let subpoints_volume = subpoints.into();
let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
self.with_limit_parts(
directionless_volume,
resting_side,
protoabsolute_price,
order_execution_expectation,
fill_policy,
)
}
pub fn with_stop_market(
mut self,
aggressive_volume: AggressiveVolume<IS>,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
cross_over_directional_intent: DirectionalIntent,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let fill_policy = fill_policy.into();
let (
client_order,
client_tracker,
remote_order,
remote_tracker,
) = single_client_stop_market(
self.order_id_generator,
aggressive_volume,
protoabsolute_price.into(),
cross_over_directional_intent,
)?;
let dependency = ClientOrderBuilderDependency {
client_tracker,
client_order,
remote_tracker,
remote_order,
fill_policy,
};
self.dependencies.push(dependency.into());
Ok(self)
}
pub fn with_stop_market_parts(
self,
directionless_volume: DirectionlessVolume<IS>,
aggressor_side: AggressorSide,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
cross_over_directional_intent: DirectionalIntent,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let aggressive_volume = AggressiveVolume {
directionless_volume,
aggressor_side,
};
self.with_stop_market(
aggressive_volume,
protoabsolute_price,
cross_over_directional_intent,
fill_policy,
)
}
pub fn with_stop_market_subpoints(
self,
aggressor_side: AggressorSide,
subpoints: impl Into<Subpoints>,
protoabsolute_price: impl Into<ProtoabsolutePrice<IS>>,
cross_over_directional_intent: DirectionalIntent,
fill_policy: impl FillPolicy + Into<FillPolicyEnum>,
) -> Result<Self, DesiredVolumeOrderError> {
let subpoints_volume = subpoints.into();
let directionless_volume = subpoints_volume.into_directionless_volume::<IS>();
self.with_stop_market_parts(
directionless_volume,
aggressor_side,
protoabsolute_price,
cross_over_directional_intent,
fill_policy,
)
}
pub fn into_condensed(
self,
) -> CondensedOrderBuilder<IS> {
let Self {
order_id_generator: _,
order,
tracker,
dependencies,
} = self;
let dependencies = dependencies
.iter()
.map(|dependency| {
let submit_order_action = dependency.create_submit_order_action(
&dependencies,
);
let remote_timing_condition = RemoteTimingCondition::FullyFilled;
(remote_timing_condition, submit_order_action)
});
let submit_remote_order = SubmitRemoteOrder::new(tracker, order, dependencies);
CondensedOrderBuilder::Remote(submit_remote_order)
}
pub fn submit<const INLINE_COUNT: usize>(
self,
deferred_order_actions: &mut DeferredOrderActions<IS>,
) -> ComplexOrderTracker<INLINE_COUNT> {
self.into_condensed().submit(deferred_order_actions)
}
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum CondensedOrderBuilder<IS: InstrumentSpec> {
Remote(SubmitRemoteOrder<IS>),
Client(SubmitClientOrder<IS>),
}
impl<IS: InstrumentSpec> CondensedOrderBuilder<IS> {
pub fn submit<const INLINE_COUNT: usize>(
self,
deferred_order_actions: &mut DeferredOrderActions<IS>,
) -> ComplexOrderTracker<INLINE_COUNT> {
let (
order_action,
complex_order_tracker,
) = self.into_order_action();
deferred_order_actions.push(order_action);
complex_order_tracker
}
pub fn into_order_action<const INLINE_COUNT: usize>(
self,
) -> (
OrderAction<IS>,
ComplexOrderTracker<INLINE_COUNT>,
) {
match self {
Self::Remote(
dependency,
) => {
let parent = OrderTracker::Remote(dependency.remote_order_tracker);
let dependencies = dependency
.dependencies
.iter()
.map(|(
_,
order_action,
)| {
match order_action {
OrderAction::SubmitRemote(
submit_remote_order,
) => {
OrderTracker::Remote(submit_remote_order.remote_order_tracker)
},
OrderAction::SubmitClient(
submit_client_order,
) => {
OrderTracker::Client(submit_client_order.client_order_tracker)
},
_ => unreachable!(),
}
}).collect();
(
dependency.into_order_action(),
ComplexOrderTracker { parent, dependencies },
)
},
Self::Client(
dependency,
) => {
let parent = OrderTracker::Client(dependency.client_order_tracker);
let dependencies = dependency
.client_deployed_remote_dependency
.dependencies
.iter()
.map(|(
_,
order_action,
)| {
match order_action {
OrderAction::SubmitRemote(
submit_remote_order,
) => {
OrderTracker::Remote(submit_remote_order.remote_order_tracker)
},
OrderAction::SubmitClient(
submit_client_order,
) => {
OrderTracker::Client(submit_client_order.client_order_tracker)
},
_ => unreachable!(),
}
}).collect();
(
dependency.into_order_action(),
ComplexOrderTracker { parent, dependencies },
)
},
}
}
}
fn single_remote_market<IS: InstrumentSpec>(
order_id_generator: &mut OrderIdGenerator,
aggressive_volume: AggressiveVolume<IS>,
) -> Result<
(
RemoteOrder<IS>,
RemoteOrderTracker,
),
DesiredVolumeOrderError,
> {
let remote_order = MarketOrder::new(aggressive_volume).into_remote();
let remote_order_tracker = remote_order.register(order_id_generator)?;
Ok((remote_order, remote_order_tracker))
}
fn single_remote_limit<IS: InstrumentSpec>(
order_id_generator: &mut OrderIdGenerator,
resting_volume: RestingVolume<IS>,
price: ProtoabsolutePrice<IS>,
order_execution_expectation: OrderExecutionExpectation,
) -> Result<
(
RemoteOrder<IS>,
RemoteOrderTracker,
),
DesiredVolumeOrderError,
> {
let remote_order = LimitOrder::new(
price,
resting_volume,
order_execution_expectation,
).into_remote();
let remote_order_tracker = remote_order.register(order_id_generator)?;
Ok((remote_order, remote_order_tracker))
}
fn single_client_stop_market<IS: InstrumentSpec>(
order_id_generator: &mut OrderIdGenerator,
aggressive_volume: AggressiveVolume<IS>,
protoabsolute_price: ProtoabsolutePrice<IS>,
cross_over_directional_intent: DirectionalIntent,
) -> Result<
(
ClientOrder<IS>,
ClientOrderTracker,
RemoteOrder<IS>,
RemoteOrderTracker,
),
DesiredVolumeOrderError,
> {
let client_order = ClientStopOrder::new(
protoabsolute_price,
cross_over_directional_intent,
).into_client_order();
let client_order_tracker = client_order.register(order_id_generator);
let remote_order = MarketOrder::new(aggressive_volume).into_remote();
let remote_order_tracker = remote_order.register(order_id_generator)?;
Ok((client_order, client_order_tracker, remote_order, remote_order_tracker))
}