apple-quant-algorithmic 0.4.0

Apple Quant's algorithmic library.
Documentation
use smallvec::SmallVec;
use tracing::instrument;

#[allow(unused_imports)]
use tracing::trace;

use crate::{
	backend::{LocalOrderId, OrderIdError, OrdersBackend, RemoteOrderId},
	timestamp::{TickTimestamp, Timestamp, Timestamped},
	instrument::InstrumentSpec, order::PartialOrderFill,
};

use super::{working::WorkingRemoteOrder, OrdersCapacitySpec};

pub struct CompletedRemoteOrder<
	IS: InstrumentSpec,
	CS: OrdersCapacitySpec,
> {
	pub(crate) completed_timestamp: Timestamp,
	pub(crate) local_order_id: LocalOrderId,
	pub(crate) remote_order_id: RemoteOrderId,

	pub(crate) partial_order_fills: SmallVec<[PartialOrderFill<IS>; core::direct_const_arg!(
		CS::PARTIAL_FILL
	)]>,
}

impl<
	IS: InstrumentSpec,
	CS: OrdersCapacitySpec,
> CompletedRemoteOrder<IS, CS> {
	pub(crate) fn new(
		completed_timestamp: Timestamp,
		local_order_id: LocalOrderId,
		remote_order_id: RemoteOrderId,
		partial_order_fills: impl IntoIterator<Item = PartialOrderFill<IS>>,
	) -> Self {
		Self {
			completed_timestamp,
			local_order_id,
			remote_order_id,
			partial_order_fills: partial_order_fills.into_iter().collect(),
		}
	}
}

/// Unordered collection of completed remote orders. Only when the client has confirmed these orders have either been 100% filled by the matching engine or canceled will it transition state to [`filled_remote_orders`].
pub struct CompletedRemoteOrders<
	IS: InstrumentSpec,
	CS: OrdersCapacitySpec,
>(SmallVec<[CompletedRemoteOrder<IS, CS>; core::direct_const_arg!(
		CS::COMPLETED_REMOTE
	)]>);

impl<
	IS: InstrumentSpec,
	CS: OrdersCapacitySpec,
> CompletedRemoteOrders<IS, CS> {
	#[instrument(skip_all)]
	pub fn submit<OB: OrdersBackend<IS>>(
		&mut self,
		tick_timestamp: &TickTimestamp,
		working_remote_order: WorkingRemoteOrder<IS, CS>,
	)
	where
		IS: Send,
	{
		#[cfg(feature = "log-trace-order-manager")]
		trace!("Adding id: `{:?}`.", working_remote_order.local_order_id);

		let completed_timestamp = tick_timestamp.timestamp();

		let completed_remote_order = CompletedRemoteOrder::new(
			completed_timestamp,
			working_remote_order.local_order_id,
			working_remote_order.remote_order_id,
			working_remote_order.partial_order_fills,
		);

		self.0.push(completed_remote_order);
	}

	#[instrument(skip_all)]
	pub fn get(
		&self,
		local_order_id: &LocalOrderId,
	) -> Result<&CompletedRemoteOrder<IS, CS>, OrderIdError> {
		let Some(
			completed_remote_order,
		) = self.0.iter().find(|
			completed_remote_order,
		| &completed_remote_order.local_order_id == local_order_id) else {
			return local_order_id.err_invalid();
		};

		Ok(completed_remote_order)
	}

	#[instrument(skip_all)]
	pub(crate) fn get_mut(
		&mut self,
		local_order_id: &LocalOrderId,
	) -> Result<&mut CompletedRemoteOrder<IS, CS>, OrderIdError> {
		let Some(
			completed_remote_order,
		) = self.0.iter_mut().find(|
			completed_remote_order,
		| &completed_remote_order.local_order_id == local_order_id) else {
			return local_order_id.err_invalid();
		};

		Ok(completed_remote_order)
	}
}

impl<
	IS: InstrumentSpec,
	CS: OrdersCapacitySpec,
> Default for CompletedRemoteOrders<IS, CS> {
	fn default() -> Self {
		Self(SmallVec::default())
	}
}