apple-quant-algorithmic 0.2.0

Apple Quant's algorithmic trading api
Documentation
use rust_decimal::Decimal;

use crate::{
	aggregation::Aggregator,
	aggregation_std::StdTrades,
	instrument::{InstrumentData, InstrumentSpec},
	price::AbsolutePrice,
	timestamp::{TradeTimestamp, TradeTimestamped},
	volume::AggressiveVolume,
};

#[derive(Debug)]
pub struct RuntimeTrade {
	pub price: Decimal,
	pub volume: Decimal,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Trade<IS: InstrumentSpec> {
	pub price: AbsolutePrice<IS>,
	pub aggressive_volume: AggressiveVolume<IS>,
}

impl<IS: InstrumentSpec> Trade<IS> {
	pub fn as_runtime(&self) -> RuntimeTrade {
		RuntimeTrade {
			price: self.price.as_decimal(),
			volume: self
				.aggressive_volume
				.as_directional_intent_volume()
				.directional_intent
				.as_decimal(),
		}
	}
}

/// Collection of both price and timestamp information.
#[derive(Debug, Clone, Copy, Eq)]
pub struct TradeTradeTimestamp<IS: InstrumentSpec> {
	trade: Trade<IS>,
	trade_timestamp: TradeTimestamp,
}

impl<IS: InstrumentSpec> TradeTradeTimestamp<IS> {
	pub fn new(
		trade: Trade<IS>,
		trade_timestamp: TradeTimestamp,
	) -> Self {
		Self { trade, trade_timestamp }
	}

	pub fn trade(&self) -> &Trade<IS> {
		&self.trade
	}
}

impl<IS: InstrumentSpec> TradeTimestamped for TradeTradeTimestamp<IS> {
	fn trade_timestamp(&self) -> &TradeTimestamp {
		&self.trade_timestamp
	}
}

impl<'instrument_data, 'aggregated_data, IS: InstrumentSpec + 'aggregated_data>
	Aggregator<'instrument_data, 'aggregated_data, Self, StdTrades<'instrument_data, IS>, IS>
	for TradeTradeTimestamp<IS>
{
	fn hot_data<'iter>(
		instrument_data: &'instrument_data InstrumentData<'instrument_data, 'aggregated_data, IS>,
		_recent_aggregated_data_backward: impl Iterator<Item = &'iter Self>,
	) -> StdTrades<'instrument_data, IS>
	where
		Self: 'iter,
	{
		StdTrades::<'instrument_data, IS>::new_aggregate::<Self>(instrument_data)
	}

	fn aggregate_hot(
		aggregator_data: &StdTrades<'instrument_data, IS>
	) -> impl Iterator<Item = Self> {
		aggregator_data
			.iter()
			.cloned()
	}
}

impl<IS: InstrumentSpec> Ord for TradeTradeTimestamp<IS> {
	fn cmp(
		&self,
		other: &Self,
	) -> std::cmp::Ordering {
		self.trade_timestamp
			.cmp(&other.trade_timestamp)
	}
}

impl<IS: InstrumentSpec> PartialOrd for TradeTradeTimestamp<IS> {
	fn partial_cmp(
		&self,
		other: &Self,
	) -> Option<std::cmp::Ordering> {
		self.trade_timestamp
			.partial_cmp(&other.trade_timestamp)
	}
}

impl<IS: InstrumentSpec> PartialEq for TradeTradeTimestamp<IS> {
	fn eq(
		&self,
		other: &Self,
	) -> bool {
		self.trade_timestamp
			.eq(&other.trade_timestamp)
	}
}