use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::PartsPerMillion32;
use vecdb::{Exit, VecIndex};
use super::Vecs;
use crate::{blocks, price};
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
prices: &price::Vecs,
blocks: &blocks::Vecs,
exit: &Exit,
) -> Result<()> {
let starting_height = indexer.safe_lengths().height;
let price = &prices.spot.cents.height;
for (min_vec, max_vec, starts) in [
(
&mut self.min._1w.cents.height,
&mut self.max._1w.cents.height,
blocks.lookback._1w.lazy(),
),
(
&mut self.min._2w.cents.height,
&mut self.max._2w.cents.height,
&blocks.lookback._2w,
),
(
&mut self.min._1m.cents.height,
&mut self.max._1m.cents.height,
blocks.lookback._1m.lazy(),
),
(
&mut self.min._1y.cents.height,
&mut self.max._1y.cents.height,
blocks.lookback._1y.lazy(),
),
] {
min_vec.compute_rolling_min_from_starts(starting_height, starts, price, exit)?;
max_vec.compute_rolling_max_from_starts(starting_height, starts, price, exit)?;
}
self.true_range_sum_2w.height.compute_rolling_sum(
starting_height,
&blocks.lookback._2w,
&self.true_range.height,
exit,
)?;
self.choppiness_index_2w.ppm.height.compute_transform4(
starting_height,
&self.true_range_sum_2w.height,
&self.max._2w.cents.height,
&self.min._2w.cents.height,
&blocks.lookback._2w,
|(h, tr_sum, max, min, window_start, ..)| {
let range = f64::from(max) - f64::from(min);
let n = (h.to_usize() - window_start.to_usize() + 1) as f32;
let ci = if range > 0.0 && n > 1.0 {
PartsPerMillion32::from(
(*tr_sum / range as f32).log10() as f64 / n.log10() as f64,
)
} else {
PartsPerMillion32::ZERO
};
(h, ci)
},
exit,
)?;
Ok(())
}
}