apple_quant_algorithmic/binned/
flex_time_point.rs1use std::{marker::PhantomData, range::Range};
2
3use crate::{
4 aggregation::Aggregator,
5 binned_method::{BinnedDataError, BinnedPoint, FlexBinnedData},
6 instrument::InstrumentSpec,
7 timestamp::{Timestamp, Timestamped, TradeTimestamped},
8};
9
10pub struct FlexBinnedTimePointData<
13 'instrument_data,
14 'aggregated_data,
15 IS: InstrumentSpec,
16 T: TradeTimestamped
17 + Aggregator<'instrument_data, 'aggregated_data, T, AggregatorData, IS>
18 + Ord
19 + 'aggregated_data,
20 AggregatorData,
21 const SECTOR_STRIDE_NS: u64,
22> {
23 flex_binned_data: FlexBinnedData<T>,
24
25 _instrument_data: PhantomData<&'instrument_data ()>,
26 _aggregated_data: PhantomData<&'aggregated_data ()>,
27 _is: PhantomData<IS>,
28 _aggregator_data: PhantomData<AggregatorData>,
29}
30
31impl<
41 'instrument_data,
42 'aggregated_data,
43 IS: InstrumentSpec,
44 T: TradeTimestamped
45 + Aggregator<'instrument_data, 'aggregated_data, T, AggregatorData, IS>
46 + Ord
47 + 'aggregated_data,
48 AggregatorData,
49 const SECTOR_STRIDE_NS: u64,
50> BinnedPoint<T>
51 for FlexBinnedTimePointData<
52 'instrument_data,
53 'aggregated_data,
54 IS,
55 T,
56 AggregatorData,
57 SECTOR_STRIDE_NS,
58 >
59{
60 fn insert(
61 &mut self,
62 data: impl Iterator<Item = T>,
63 ) {
64 for data in data {
65 let sector_idx =
66 data.trade_timestamp()
67 .as_utc_nanos() / SECTOR_STRIDE_NS as i128;
68
69 let sector_idx = sector_idx.cast_unsigned() as u64;
70
71 self.flex_binned_data
72 .insert_in_sector(sector_idx, [data].into_iter())
73 .unwrap();
74 }
75 }
76
77 fn get<'a>(
78 &'a self,
79 timestamp: &Timestamp,
80 ) -> Result<impl Iterator<Item = &'a T>, BinnedDataError>
81 where
82 T: 'a,
83 {
84 let sector_idx = timestamp.as_utc_nanos() / SECTOR_STRIDE_NS as i128;
85
86 let sector_idx = sector_idx.cast_unsigned() as u64;
87
88 let sector_data = self
89 .flex_binned_data
90 .get_sector(sector_idx)?;
91
92 Ok(sector_data
93 .iter()
94 .filter(move |t| {
95 t.trade_timestamp()
96 .timestamp() == timestamp
97 }))
98 }
99
100 fn get_first(
101 &self,
102 timestamp: &Timestamp,
103 ) -> Result<Option<&T>, BinnedDataError> {
104 let sector_idx = timestamp.as_utc_nanos() / SECTOR_STRIDE_NS as i128;
105
106 let sector_idx = sector_idx.cast_unsigned() as u64;
107
108 let sector_data = self
109 .flex_binned_data
110 .get_sector(sector_idx)?;
111
112 Ok(sector_data.iter().find(|t| {
113 t.trade_timestamp()
114 .timestamp() == timestamp
115 }))
116 }
117
118 fn iter<'a>(
119 &'a self,
120 range: Range<&Timestamp>,
121 ) -> Result<impl Iterator<Item = &'a T>, BinnedDataError>
122 where
123 T: 'a,
124 {
125 let start_sector_idx = range.start.as_utc_nanos() / SECTOR_STRIDE_NS as i128;
126 let last_sector_idx = range.end.as_utc_nanos() / SECTOR_STRIDE_NS as i128;
127
128 debug_assert!(start_sector_idx <= last_sector_idx);
129
130 let start_sector_idx = start_sector_idx.cast_unsigned() as u64;
131 let last_sector_idx = last_sector_idx.cast_unsigned() as u64;
132
133 self.flex_binned_data
134 .iter(
135 start_sector_idx,
136 last_sector_idx,
137 |t: &T| {
138 t.trade_timestamp()
139 .timestamp() >= range.start
140 },
141 |t: &T| {
142 t.trade_timestamp()
143 .timestamp() < range.end
144 },
145 )
146 .map_err(|_| BinnedDataError::InternalError)
147 }
148}
149
150impl<
151 'instrument_data,
152 'aggregated_data,
153 IS: InstrumentSpec,
154 T: TradeTimestamped
155 + Aggregator<'instrument_data, 'aggregated_data, T, AggregatorData, IS>
156 + Ord
157 + 'aggregated_data,
158 AggregatorData,
159 const SECTOR_STRIDE_NS: u64,
160> Default
161 for FlexBinnedTimePointData<
162 'instrument_data,
163 'aggregated_data,
164 IS,
165 T,
166 AggregatorData,
167 SECTOR_STRIDE_NS,
168 >
169{
170 fn default() -> Self {
171 Self {
172 flex_binned_data: FlexBinnedData::default(),
173 _instrument_data: PhantomData::default(),
174 _aggregated_data: PhantomData::default(),
175 _is: PhantomData::default(),
176 _aggregator_data: PhantomData::default(),
177 }
178 }
179}