apple-quant-algorithmic 0.3.0

Apple Quant's algorithmic library.
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(),
		}
	}
}