apple-quant-algorithmic 0.4.0

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

use crate::{
	backend::{LocalOrderId, OrderIdError},
	order_manager::{OrderManager, OrderRef, OrdersCapacitySpec},
	instrument::InstrumentSpec,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OrderTracker {
	Remote(RemoteOrderTracker),
	Client(ClientOrderTracker),
}

impl OrderTracker {
	pub fn is_settled_neutral<
		IS: InstrumentSpec,
		CS: OrdersCapacitySpec,
	>(
		&self,
		order_manager: &OrderManager<IS, CS>,
	) -> Result<bool, OrderIdError> {
		match self {
			Self::Remote(
				tracker,
			) => tracker.is_settled_neutral(order_manager),
			Self::Client(
				tracker,
			) => tracker.is_settled_neutral(order_manager),
		}
	}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ClientOrderTracker(LocalOrderId);

impl ClientOrderTracker {
	pub(crate) fn new(
		local_order_id: LocalOrderId,
	) -> Self {
		Self(local_order_id)
	}

	pub fn as_local_order_id(
		&self,
	) -> &LocalOrderId {
		&self.0
	}

	pub fn into_local_order_id(
		self,
	) -> LocalOrderId {
		self.0
	}

	pub fn is_settled_neutral<
		IS: InstrumentSpec,
		CS: OrdersCapacitySpec,
	>(
		&self,
		order_manager: &OrderManager<IS, CS>,
	) -> Result<bool, OrderIdError> {
		let local_order_id = self.0;

		match order_manager.find_order(&local_order_id) {
			Ok(OrderRef::PendingClient {
				pending_client_order: _,
				pending_client_orders: _,
			}) => Ok(false),
			Err(_) => Ok(true),
			_ => return local_order_id.err_invalid(),
		}
	}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RemoteOrderTracker(LocalOrderId);

impl RemoteOrderTracker {
	pub(crate) fn new(
		local_order_id: LocalOrderId,
	) -> Self {
		Self(local_order_id)
	}

	pub fn as_local_order_id(
		&self,
	) -> &LocalOrderId {
		&self.0
	}

	pub fn into_local_order_id(
		self,
	) -> LocalOrderId {
		self.0
	}

	pub fn is_settled_neutral<
		IS: InstrumentSpec,
		CS: OrdersCapacitySpec,
	>(
		&self,
		order_manager: &OrderManager<IS, CS>,
	) -> Result<bool, OrderIdError> {
		let local_order_id = self.0;

		let is_settled_neutral = match order_manager.find_order(&local_order_id)? {
			OrderRef::PendingClient {
				pending_client_order: _,
				pending_client_orders: _,
			} => return local_order_id.err_invalid(),
			OrderRef::PendingRemote {
				pending_remote_order: _,
				pending_remote_orders: _,
			} => false,
			OrderRef::WorkingRemote {
				working_remote_order: _,
				working_remote_orders: _,
			} => false,
			OrderRef::CompletedRemote {
				completed_remote_order: _,
				completed_remote_orders: _,
			} => true,
		};

		Ok(is_settled_neutral)
	}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ComplexOrderTracker<const INLINE_LEN: usize> {
	pub parent: OrderTracker,
	pub dependencies: SmallVec<[OrderTracker; INLINE_LEN]>,
}

impl<const INLINE_LEN: usize> ComplexOrderTracker<INLINE_LEN> {
	pub fn is_settled_neutral<
		IS: InstrumentSpec,
		CS: OrdersCapacitySpec,
	>(
		&self,
		order_manager: &OrderManager<IS, CS>,
	) -> Result<bool, OrderIdError> {
		if !self.parent.is_settled_neutral(order_manager)? {
			return Ok(false);
		}

		for tracker in self.dependencies.iter() {
			if !tracker.is_settled_neutral(order_manager)? {
				return Ok(false);
			}
		}

		Ok(true)
	}
}