mod capacity_spec;
mod client_pending;
mod completed;
mod remote_pending;
mod working;
use thiserror::Error;
use tracing::instrument;
use crate::{
backend::{
LocalOrderId, OrderIdError, OrdersBackendSubmitRemoteOrderError, RemoteOrderId,
},
order::{DesiredVolumeOrderError, StateGoal},
instrument::InstrumentSpec,
};
pub use capacity_spec::*;
pub use client_pending::*;
pub use completed::*;
pub use remote_pending::*;
pub use working::*;
#[derive(Debug, Error)]
pub enum SubmitRemoteOrderError {
#[error("{0:?}")]
OrdersBackendSubmitRemoteOrderError(#[from] OrdersBackendSubmitRemoteOrderError),
#[error("{0:?}")]
DesiredVolumeOrderError(#[from] DesiredVolumeOrderError),
}
#[derive(Debug, Error)]
pub enum TryCancelRemoteOrderError {
#[error("Unable to cancel order that is in a remote pending state.")]
Pending(RemoteOrderId),
#[error("Unable to cancel order that is partially filled at remote.")]
ParitallyFilled(RemoteOrderId),
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
}
#[derive(Debug, Error)]
pub(crate) enum RemotePartialFillError {
#[error("{0:?}")]
TrasitionRemoteWorkingOrderError(#[from] TrasitionRemoteWorkingOrderError),
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
}
#[derive(Debug, Error)]
pub(crate) enum TrasitionLocalOrderError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
#[error("{0:?}")]
OrdersBackendSubmitRemoteOrderError(#[from] OrdersBackendSubmitRemoteOrderError),
#[error(
"{local_order_id:?} already is paired with {existing_remote_order_id:?} when attemping to transition to {attemped_remote_order_id:?}"
)]
AlreadyTransitioned {
local_order_id: LocalOrderId,
attemped_remote_order_id: RemoteOrderId,
existing_remote_order_id: RemoteOrderId,
},
}
#[derive(Debug, Error)]
pub(crate) enum TransitionRemotePendingOrderError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
#[error("{local_order_id:?} is already in a working state under {remote_order_id:?}.")]
AlreadyWorking {
local_order_id: LocalOrderId,
remote_order_id: RemoteOrderId,
},
}
#[derive(Debug, Error)]
pub(crate) enum TrasitionRemoteWorkingOrderError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
#[error("{0:?} already exists in a completed state.")]
AlreadyCompleted(RemoteOrderId),
}
#[derive(Debug, Error)]
pub enum CancelOrderError {
#[error("No matching remote order id for: {0:?}")]
NoMatchingRemoteOrderId(LocalOrderId),
#[error("{0:?}")]
CancelLocalOrderError(#[from] CancelClientOrderError),
#[error("{0:?}")]
CancelRemoteOrderError(#[from] CancelRemoteOrderError),
}
#[derive(Debug, Error)]
pub enum CancelClientOrderError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
}
#[derive(Debug, Error)]
pub enum CancelRemoteOrderError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
#[error("{0:?}")]
DesiredVolumeOrderError(#[from] DesiredVolumeOrderError),
#[error("{0:?} has no RemoteOrderId assigned yet.")]
NoRemoteOrderId(LocalOrderId),
}
#[derive(Debug, Error)]
pub enum CancelFlattenAllError {
#[error("Can not cancel flatten while there is an existing: {0:?}")]
ExistingStateGoal(StateGoal),
}
#[derive(Debug, Error)]
pub enum RemoteCanceledRemoteOrderError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
#[error("Order was already fully filled.")]
FullyFilled,
}
#[derive(Debug, Error)]
pub enum AssignRemoteOrderIdError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
#[error(
"Failed to assign {remote_order_id:?} to order with {local_order_id:?}. Already assigned {existing_remote_order_id:?}"
)]
AlreadyAssigned {
local_order_id: LocalOrderId,
remote_order_id: RemoteOrderId,
existing_remote_order_id: RemoteOrderId,
},
}
#[derive(Debug)]
pub enum OrderGroupMut<
'a,
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
> {
PendingClient(&'a mut PendingClientOrders<IS, CS>),
PendingRemote(&'a mut PendingRemoteOrders<IS, CS>),
WorkingRemote(&'a mut WorkingRemoteOrders<IS, CS>),
CompletedRemote(&'a mut CompletedRemoteOrders<IS, CS>),
}
#[derive(Debug)]
pub enum OrderRef<
'a,
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
> {
PendingClient {
pending_client_order: &'a PendingClientOrder<IS>,
pending_client_orders: &'a PendingClientOrders<IS, CS>,
},
PendingRemote {
pending_remote_order: &'a PendingRemoteOrder<IS, CS>,
pending_remote_orders: &'a PendingRemoteOrders<IS, CS>,
},
WorkingRemote {
working_remote_order: &'a WorkingRemoteOrder<IS, CS>,
working_remote_orders: &'a WorkingRemoteOrders<IS, CS>,
},
CompletedRemote {
completed_remote_order: &'a CompletedRemoteOrder<IS, CS>,
completed_remote_orders: &'a CompletedRemoteOrders<IS, CS>,
},
}
#[derive(Debug)]
pub enum OrderMut<
'a,
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
> {
PendingClient(&'a mut PendingClientOrder<IS>),
PendingRemote(&'a mut PendingRemoteOrder<IS, CS>),
WorkingRemote(&'a mut WorkingRemoteOrder<IS, CS>),
CompletedRemote(&'a mut CompletedRemoteOrder<IS, CS>),
}
#[derive(Debug)]
pub struct OrderManager<
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
> {
pub(crate) pending_client_orders: PendingClientOrders<IS, CS>,
pub(crate) pending_remote_orders: PendingRemoteOrders<IS, CS>,
pub(crate) working_remote_orders: WorkingRemoteOrders<IS, CS>,
pub(crate) completed_remote_orders: CompletedRemoteOrders<IS, CS>,
}
impl<
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
> OrderManager<IS, CS> {
pub fn pending_client_orders(
&self,
) -> &PendingClientOrders<IS, CS> {
&self.pending_client_orders
}
pub fn pending_remote_orders(
&self,
) -> &PendingRemoteOrders<IS, CS> {
&self.pending_remote_orders
}
pub fn working_remote_orders(
&self,
) -> &WorkingRemoteOrders<IS, CS> {
&self.working_remote_orders
}
pub fn completed_remote_orders(
&self,
) -> &CompletedRemoteOrders<IS, CS> {
&self.completed_remote_orders
}
#[instrument(skip_all)]
pub fn find_order(
&self,
local_order_id: &LocalOrderId,
) -> Result<OrderRef<'_, IS, CS>, OrderIdError> {
if let Ok(
pending_client_order,
) = self.pending_client_orders.get(
local_order_id,
) {
return Ok(OrderRef::PendingClient {
pending_client_order,
pending_client_orders: &self.pending_client_orders,
});
}
if let Ok(
pending_remote_order,
) = self.pending_remote_orders.get(
local_order_id,
) {
return Ok(OrderRef::PendingRemote {
pending_remote_order,
pending_remote_orders: &self.pending_remote_orders,
});
}
if let Ok(
working_remote_order,
) = self.working_remote_orders.get(
local_order_id,
) {
return Ok(OrderRef::WorkingRemote {
working_remote_order,
working_remote_orders: &self.working_remote_orders,
});
}
if let Ok(
completed_remote_order,
) = self.completed_remote_orders.get(
local_order_id,
) {
return Ok(OrderRef::CompletedRemote {
completed_remote_order,
completed_remote_orders: &self.completed_remote_orders,
});
}
local_order_id.err_invalid()
}
#[instrument(skip_all)]
pub(crate) fn find_order_mut(
&mut self,
local_order_id: &LocalOrderId,
) -> Result<OrderMut<'_, IS, CS>, OrderIdError> {
if let Ok(
pending_client_order,
) = self.pending_client_orders.get_mut(
local_order_id,
) {
return Ok(OrderMut::PendingClient(pending_client_order));
}
if let Ok(
pending_remote_order,
) = self.pending_remote_orders.get_mut(
local_order_id,
) {
return Ok(OrderMut::PendingRemote(pending_remote_order));
}
if let Ok(
working_remote_order,
) = self.working_remote_orders.get_mut(
local_order_id,
) {
return Ok(OrderMut::WorkingRemote(working_remote_order));
}
if let Ok(
completed_remote_order,
) = self.completed_remote_orders.get_mut(
local_order_id,
) {
return Ok(OrderMut::CompletedRemote(completed_remote_order));
}
local_order_id.err_invalid()
}
#[instrument(skip_all)]
pub(crate) fn find_order_group_mut(
&mut self,
local_order_id: &LocalOrderId,
) -> Result<OrderGroupMut<'_, IS, CS>, OrderIdError> {
if self.pending_client_orders.get(local_order_id).is_ok() {
return Ok(OrderGroupMut::PendingClient(&mut self.pending_client_orders));
}
if self.pending_remote_orders.get(local_order_id).is_ok() {
return Ok(OrderGroupMut::PendingRemote(&mut self.pending_remote_orders));
}
if self.working_remote_orders.get(local_order_id).is_ok() {
return Ok(OrderGroupMut::WorkingRemote(&mut self.working_remote_orders));
}
if self.completed_remote_orders.get(local_order_id).is_ok() {
return Ok(OrderGroupMut::CompletedRemote(&mut self.completed_remote_orders));
}
local_order_id.err_invalid()
}
}
impl<
IS: InstrumentSpec,
CS: OrdersCapacitySpec,
> Default for OrderManager<IS, CS> {
fn default() -> Self {
Self {
pending_client_orders: PendingClientOrders::default(),
pending_remote_orders: PendingRemoteOrders::default(),
working_remote_orders: WorkingRemoteOrders::default(),
completed_remote_orders: CompletedRemoteOrders::default(),
}
}
}