apple-quant-algorithmic 0.4.0

Apple Quant's algorithmic library.
Documentation
use std::marker::PhantomData;

use apple_quant_core::log::error;

use crate::{
	binned_method::{BinnedDataError, FixedBinnedData},
	aggregation::Aggregator, instrument::InstrumentSpec,
	timestamp::TradeTimestampRangeIncluded,
};

/// Fixed Binned - Fixed size (1); bins for each T.
/// Time Ranged - Each T is ranged by time within each constant bin size via [`RangeTimestamped`].
pub struct FixedBinnedTimeRangedData<
	'instrument_data,
	'aggregated_data,
	IS: InstrumentSpec,
	T: TradeTimestampRangeIncluded
		+ Aggregator<'instrument_data, 'aggregated_data, T, AggregatorData, IS>
		+ Clone
		+ 'aggregated_data,
	AggregatorData,
	const SECTOR_DATA_COUNT: usize,
	const SECTOR_STRIDE_NS: u64,
	const DATA_STRIDE_NS: u64,
> {
	fixed_binned_data: FixedBinnedData<T, SECTOR_DATA_COUNT>,
	_instrument_data: PhantomData<&'instrument_data ()>,
	_aggregated_data: PhantomData<&'aggregated_data ()>,
	_is: PhantomData<IS>,
	_aggregator_data: PhantomData<AggregatorData>,
}

impl<
	'instrument_data,
	'aggregated_data,
	IS: InstrumentSpec,
	T: TradeTimestampRangeIncluded
		+ Aggregator<'instrument_data, 'aggregated_data, T, AggregatorData, IS>
		+ Clone
		+ 'aggregated_data,
	AggregatorData,
	const SECTOR_DATA_COUNT: usize,
	const SECTOR_STRIDE_NS: u64,
	const DATA_STRIDE_NS: u64,
> FixedBinnedTimeRangedData<
	'instrument_data,
	'aggregated_data,
	IS,
	T,
	AggregatorData,
	SECTOR_DATA_COUNT,
	SECTOR_STRIDE_NS,
	DATA_STRIDE_NS,
> {
	pub fn new_checked() -> Result<Self, ()> {
		if SECTOR_STRIDE_NS / SECTOR_DATA_COUNT as u64 != DATA_STRIDE_NS {
			error!(
				"Invalid const generics for FixedBinnedTimeRangedData where SECTOR_STRIDE_NS: {} SECTOR_DATA_COUNT: {} DATA_STRIDE_NS: {}",
				SECTOR_STRIDE_NS,
				SECTOR_DATA_COUNT,
				DATA_STRIDE_NS,
			);

			return Err(());
		}

		Ok(Self {
			fixed_binned_data: FixedBinnedData::default(),
			_instrument_data: PhantomData::default(),
			_aggregated_data: PhantomData::default(),
			_is: PhantomData::default(),
			_aggregator_data: PhantomData::default(),
		})
	}

	fn index_ranged_timestamp(
		min_timestamp: u64,
		max_timestamp: u64,
	) -> Result<(usize, usize), BinnedDataError> {
		let min_index = (min_timestamp / DATA_STRIDE_NS) as usize;
		let max_index = (max_timestamp / DATA_STRIDE_NS) as usize;

		#[cfg(debug_assertions)]
		if max_index < min_index {
			return Err(BinnedDataError::InvalidMinMax {
				min: min_index as u64,
				max: max_index as u64,
			});
		}

		Ok((min_index, max_index))
	}
}