apple-quant-algorithmic 0.2.0

Apple Quant's algorithmic trading api
Documentation
use thiserror::Error;

use crate::{
	backend::{OrderIdError, OrderIdGenerator, OrdersBackend},
	instrument::InstrumentSpec,
	order_manager::{
		AssignRemoteOrderIdError, OrderManager, OrdersCapacitySpec, PendingClientActivateError,
		PendingRemoteProcessedError, RemoteCanceledRemoteOrderError, RemotePartialFillError,
		TransitionRemotePendingOrderError,
	},
	timestamp::TickTimestamp,
	volume::DirectionalExposure,
};

mod new_canceled;
mod new_partial_fill;
mod new_working;

pub use new_canceled::*;
pub use new_partial_fill::*;
pub use new_working::*;

use super::{ActiveOrderGoals, ActiveStateGoal, DeferredOrderActions};

#[derive(Debug, Error)]
pub(crate) enum ApplyOrderStateUpdateError {
	#[error("{0:?}")]
	AssignRemoteOrderIdError(#[from] AssignRemoteOrderIdError),

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

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

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

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

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

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

pub(crate) trait ApplyOrderStateUpdate<IS: InstrumentSpec> {
	fn apply<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>,
		deferred_order_actions: &mut DeferredOrderActions<IS>,
		active_order_goals: &mut ActiveOrderGoals<IS>,
		active_state_goal: &mut ActiveStateGoal,
	) -> impl Future<Output = Result<(), ApplyOrderStateUpdateError>>
	where
		IS: Send;
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OrderStateUpdate<IS: InstrumentSpec> {
	NewWorkingState(NewWorkingState),
	NewCanceledState(NewCanceledState),
	NewPartialFillState(NewPartialFillState<IS>),
}

impl<IS: InstrumentSpec> ApplyOrderStateUpdate<IS> for OrderStateUpdate<IS> {
	async fn apply<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>,
		deferred_order_actions: &mut DeferredOrderActions<IS>,
		active_order_goals: &mut ActiveOrderGoals<IS>,
		active_state_goal: &mut ActiveStateGoal,
	) -> Result<(), ApplyOrderStateUpdateError>
	where
		IS: Send,
	{
		match self {
			Self::NewWorkingState(state) => {
				state
					.apply(
						tick_timestamp,
						order_manager,
						orders_backend,
						order_id_generator,
						directional_exposure,
						deferred_order_actions,
						active_order_goals,
						active_state_goal,
					)
					.await
			}
			Self::NewCanceledState(state) => {
				state
					.apply(
						tick_timestamp,
						order_manager,
						orders_backend,
						order_id_generator,
						directional_exposure,
						deferred_order_actions,
						active_order_goals,
						active_state_goal,
					)
					.await
			}
			Self::NewPartialFillState(state) => {
				state
					.apply(
						tick_timestamp,
						order_manager,
						orders_backend,
						order_id_generator,
						directional_exposure,
						deferred_order_actions,
						active_order_goals,
						active_state_goal,
					)
					.await
			}
		}
	}
}