apple-quant-algorithmic 0.3.0

Apple Quant's algorithmic library.
#![allow(unused)]

pub mod client;
pub mod remote;
mod deferred;

use std::sync::Arc;

use client::{CancelClientOrder, ClientOrderAction, SubmitClientOrder};

use remote::{CancelRemoteOrder, RemoteOrderAction, SubmitRemoteOrder};

use thiserror::Error;

use crate::{
	backend::{OrderIdError, OrderIdGenerator, OrdersBackend},
	order_manager::{
		CancelRemoteOrderError, OrderManager, OrdersCapacitySpec,
		PendingClientCancelError, PendingRemoteSubmitError,
	},
	instrument::InstrumentSpec, price::BidAskPriceSpread, timestamp::TickTimestamp,
	volume::DirectionalExposure,
};

use super::{DesiredVolumeOrderError, StateGoal};

pub use deferred::*;

#[derive(Debug, Error)]
pub enum TriggerError {
	#[error("{0:?}")]
	DesiredVolumeOrder(#[from] DesiredVolumeOrderError),

	#[error("{0:?}")]
	PendingRemoteSubmitError(#[from] PendingRemoteSubmitError),

	#[error("{0:?}")]
	PendingClientCancel(#[from] PendingClientCancelError),

	#[error("{0:?}")]
	OrderId(#[from] OrderIdError),

	#[error("{0:?}")]
	CancelRemoteOrder(#[from] CancelRemoteOrderError),
}

pub(crate) trait OrderDependency<IS: InstrumentSpec> {
	/// Returns true if polling needs to be enabled.
	fn trigger<
		OB: OrdersBackend<IS>,
		CS: OrdersCapacitySpec,
	>(
		&self,
		tick_timestamp: &TickTimestamp,
		order_manager: &mut OrderManager<IS, CS>,
		orders_backend: &mut OB,
		order_id_generator: &mut OrderIdGenerator,
		directional_exposure: &mut DirectionalExposure<IS>,
		state_goal: &mut StateGoal,
	) -> impl Future<Output = Result<bool, TriggerError>>
	where
		IS: Send;
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum OrderAction<IS: InstrumentSpec> {
	SubmitRemote(SubmitRemoteOrder<IS>),
	SubmitClient(SubmitClientOrder<IS>),
	CancelRemote(CancelRemoteOrder),
	CancelClient(CancelClientOrder),
}

impl<IS: InstrumentSpec> OrderAction<IS> {
	pub(crate) fn parent_processed(
		&mut self,
		bid_ask_price_spread: &BidAskPriceSpread<IS>,
	) {
		match self {
			Self::SubmitRemote(
				submit_remote_order,
			) => submit_remote_order.parent_processed(bid_ask_price_spread),
			Self::SubmitClient(
				submit_client_order,
			) => submit_client_order.parent_processed(bid_ask_price_spread),
			_ => {},
		}
	}

	pub fn into_remote(
		self,
	) -> RemoteOrderAction<IS> {
		RemoteOrderAction::new(self)
	}

	pub fn into_client(
		self,
	) -> ClientOrderAction<IS> {
		ClientOrderAction::new(self)
	}
}

impl<IS: InstrumentSpec> OrderDependency<IS> for OrderAction<IS> {
	async fn trigger<
		OB: OrdersBackend<IS>,
		CS: OrdersCapacitySpec,
	>(
		&self,
		tick_timestamp: &TickTimestamp,
		order_manager: &mut OrderManager<IS, CS>,
		orders_backend: &mut OB,
		order_id_generator: &mut OrderIdGenerator,
		directional_exposure: &mut DirectionalExposure<IS>,
		state_goal: &mut StateGoal,
	) -> Result<bool, TriggerError>
	where
		IS: Send,
	{
		match self {
			Self::SubmitRemote(
				order,
			) => {
				order.trigger(
					tick_timestamp,
					order_manager,
					orders_backend,
					order_id_generator,
					directional_exposure,
					state_goal,
				).await
			},
			Self::SubmitClient(
				order,
			) => {
				order.trigger(
					tick_timestamp,
					order_manager,
					orders_backend,
					order_id_generator,
					directional_exposure,
					state_goal,
				).await
			},
			Self::CancelRemote(
				order,
			) => {
				order.trigger(
					tick_timestamp,
					order_manager,
					orders_backend,
					order_id_generator,
					directional_exposure,
					state_goal,
				).await
			},
			Self::CancelClient(
				order,
			) => {
				order.trigger(
					tick_timestamp,
					order_manager,
					orders_backend,
					order_id_generator,
					directional_exposure,
					state_goal,
				).await
			},
		}
	}
}

impl<IS: InstrumentSpec> From<SubmitRemoteOrder<IS>> for OrderAction<IS> {
	fn from(
		value: SubmitRemoteOrder<IS>,
	) -> Self {
		Self::SubmitRemote(value)
	}
}

impl<IS: InstrumentSpec> From<SubmitClientOrder<IS>> for OrderAction<IS> {
	fn from(
		value: SubmitClientOrder<IS>,
	) -> Self {
		Self::SubmitClient(value)
	}
}

impl<IS: InstrumentSpec> From<CancelRemoteOrder> for OrderAction<IS> {
	fn from(
		value: CancelRemoteOrder,
	) -> Self {
		Self::CancelRemote(value)
	}
}

impl<IS: InstrumentSpec> From<CancelClientOrder> for OrderAction<IS> {
	fn from(
		value: CancelClientOrder,
	) -> Self {
		Self::CancelClient(value)
	}
}