use thiserror::Error;
use crate::{
backend::{LocalOrderId, OrderIdError, OrdersBackendSubmitRemoteOrderError, RemoteOrderId},
instrument::InstrumentSpec,
order::{
DesiredVolumeOrderError, OrderGoalAsExecutionExpectationError, OrderGoalT,
RemoveOrderGoalError, StateGoal,
},
};
mod capacity_spec;
mod client_pending;
mod completed;
mod remote_pending;
mod working;
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("{0:?}")]
OrderGoalAsExecutionExpectation(#[from] OrderGoalAsExecutionExpectationError),
#[error("{0:?}")]
RemoveOrderGoalError(#[from] RemoveOrderGoalError),
#[error("{local_order_id:?} is already in a working state under {remote_order_id:?}.")]
AlreadyWorking {
local_order_id: LocalOrderId,
remote_order_id: RemoteOrderId,
},
#[error("Unexpected {0:?}.")]
UnexpectedOrderGoal(OrderGoalT),
}
#[derive(Debug, Error)]
pub(crate) enum TrasitionRemoteWorkingOrderError {
#[error("{0:?}")]
OrderIdError(#[from] OrderIdError),
#[error("{0:?}")]
RemoveOrderGoalError(#[from] RemoveOrderGoalError),
#[error("{0:?} already exists in a completed state.")]
AlreadyCompleted(RemoteOrderId),
#[error("Unexpected {0:?}.")]
UnexpectedOrderGoal(OrderGoalT),
}
#[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("{0:?}")]
OrderGoalAsExecutionExpectationError(#[from] OrderGoalAsExecutionExpectationError),
#[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
}
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()
}
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()
}
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(),
}
}
}