apple-quant-algorithmic 0.2.0

Apple Quant's algorithmic trading api
Documentation
use smallvec::SmallVec;

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

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

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
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>; 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`].
#[derive(Debug)]
pub struct CompletedRemoteOrders<IS: InstrumentSpec, CS: OrdersCapacitySpec>(
	SmallVec<[CompletedRemoteOrder<IS, CS>; CS::COMPLETED_REMOTE]>,
);

impl<IS: InstrumentSpec, CS: OrdersCapacitySpec> CompletedRemoteOrders<IS, CS> {
	pub fn submit<OB: OrdersBackend<IS>>(
		&mut self,
		tick_timestamp: &TickTimestamp,
		working_remote_order: WorkingRemoteOrder<IS, CS>,
	) where
		IS: Send,
	{
		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);
	}

	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)
	}

	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())
	}
}