Skip to main content

apple_quant_algorithmic/binned/
fixed_time_ranged.rs

1use std::marker::PhantomData;
2
3use apple_quant_core::log::error;
4
5use crate::{
6	binned_method::{BinnedDataError, FixedBinnedData},
7	aggregation::Aggregator, instrument::InstrumentSpec,
8	timestamp::TradeTimestampRangeIncluded,
9};
10
11/// Fixed Binned - Fixed size (1); bins for each T.
12/// Time Ranged - Each T is ranged by time within each constant bin size via [`RangeTimestamped`].
13pub struct FixedBinnedTimeRangedData<
14	'instrument_data,
15	'aggregated_data,
16	IS: InstrumentSpec,
17	T: TradeTimestampRangeIncluded
18		+ Aggregator<'instrument_data, 'aggregated_data, T, AggregatorData, IS>
19		+ Clone
20		+ 'aggregated_data,
21	AggregatorData,
22	const SECTOR_DATA_COUNT: usize,
23	const SECTOR_STRIDE_NS: u64,
24	const DATA_STRIDE_NS: u64,
25> {
26	fixed_binned_data: FixedBinnedData<T, SECTOR_DATA_COUNT>,
27	_instrument_data: PhantomData<&'instrument_data ()>,
28	_aggregated_data: PhantomData<&'aggregated_data ()>,
29	_is: PhantomData<IS>,
30	_aggregator_data: PhantomData<AggregatorData>,
31}
32
33impl<
34	'instrument_data,
35	'aggregated_data,
36	IS: InstrumentSpec,
37	T: TradeTimestampRangeIncluded
38		+ Aggregator<'instrument_data, 'aggregated_data, T, AggregatorData, IS>
39		+ Clone
40		+ 'aggregated_data,
41	AggregatorData,
42	const SECTOR_DATA_COUNT: usize,
43	const SECTOR_STRIDE_NS: u64,
44	const DATA_STRIDE_NS: u64,
45> FixedBinnedTimeRangedData<
46	'instrument_data,
47	'aggregated_data,
48	IS,
49	T,
50	AggregatorData,
51	SECTOR_DATA_COUNT,
52	SECTOR_STRIDE_NS,
53	DATA_STRIDE_NS,
54> {
55	pub fn new_checked() -> Result<Self, ()> {
56		if SECTOR_STRIDE_NS / SECTOR_DATA_COUNT as u64 != DATA_STRIDE_NS {
57			error!(
58				"Invalid const generics for FixedBinnedTimeRangedData where SECTOR_STRIDE_NS: {} SECTOR_DATA_COUNT: {} DATA_STRIDE_NS: {}",
59				SECTOR_STRIDE_NS,
60				SECTOR_DATA_COUNT,
61				DATA_STRIDE_NS,
62			);
63
64			return Err(());
65		}
66
67		Ok(Self {
68			fixed_binned_data: FixedBinnedData::default(),
69			_instrument_data: PhantomData::default(),
70			_aggregated_data: PhantomData::default(),
71			_is: PhantomData::default(),
72			_aggregator_data: PhantomData::default(),
73		})
74	}
75
76	fn index_ranged_timestamp(
77		min_timestamp: u64,
78		max_timestamp: u64,
79	) -> Result<(usize, usize), BinnedDataError> {
80		let min_index = (min_timestamp / DATA_STRIDE_NS) as usize;
81		let max_index = (max_timestamp / DATA_STRIDE_NS) as usize;
82
83		#[cfg(debug_assertions)]
84		if max_index < min_index {
85			return Err(BinnedDataError::InvalidMinMax {
86				min: min_index as u64,
87				max: max_index as u64,
88			});
89		}
90
91		Ok((min_index, max_index))
92	}
93}