diff --git a/crates/fidc-core/src/data.rs b/crates/fidc-core/src/data.rs index 177e41b..9b9b321 100644 --- a/crates/fidc-core/src/data.rs +++ b/crates/fidc-core/src/data.rs @@ -582,8 +582,8 @@ const MAX_SERIES_END_POSITION_INDEX_BYTES: usize = 256 * 1024 * 1024; #[derive(Debug, Clone)] struct AdjustedCloseSeries { dates: Vec, - backward_factors: Vec>, - back_adjusted_closes: Vec>, + backward_factors: Vec, + back_adjusted_closes: Vec, back_adjusted_close_prefix: Vec, missing_back_adjusted_close_prefix: Vec, } @@ -622,8 +622,8 @@ impl AdjustedCloseSeries { let back_adjusted_close = factor .filter(|_| close.is_finite() && *close > 0.0) .map(|factor| close * factor); - backward_factors.push(factor); - back_adjusted_closes.push(back_adjusted_close); + backward_factors.push(factor.unwrap_or(f64::NAN)); + back_adjusted_closes.push(back_adjusted_close.unwrap_or(f64::NAN)); back_adjusted_close_prefix.push( back_adjusted_close_prefix .last() @@ -693,7 +693,11 @@ impl AdjustedCloseSeries { if lookback == 0 || end < lookback { return None; } - let base_factor = self.backward_factors.get(end - 1).copied().flatten()?; + let base_factor = self + .backward_factors + .get(end - 1) + .copied() + .filter(|factor| factor.is_finite() && *factor > 0.0)?; let start = end - lookback; if self.missing_back_adjusted_close_prefix[end] != self.missing_back_adjusted_close_prefix[start] @@ -723,20 +727,23 @@ impl AdjustedCloseSeries { return Vec::new(); } let start = end.saturating_sub(lookback); - let Some(base_factor) = self.backward_factors.get(end - 1).copied().flatten() else { + let Some(base_factor) = self + .backward_factors + .get(end - 1) + .copied() + .filter(|factor| factor.is_finite() && *factor > 0.0) + else { return Vec::new(); }; + if self.missing_back_adjusted_close_prefix[end] + != self.missing_back_adjusted_close_prefix[start] + { + return Vec::new(); + } self.back_adjusted_closes[start..end] .iter() - .copied() - .collect::>>() - .map(|values| { - values - .into_iter() - .map(|value| normalize_rolling_factor(value / base_factor, 12)) - .collect() - }) - .unwrap_or_default() + .map(|value| normalize_rolling_factor(*value / base_factor, 12)) + .collect() } fn latest_back_adjusted_close(&self, date: NaiveDate) -> Option { @@ -748,7 +755,6 @@ impl AdjustedCloseSeries { self.back_adjusted_closes .get(index) .copied() - .flatten() .filter(|value| value.is_finite() && *value > 0.0) } } @@ -6290,8 +6296,8 @@ mod tests { dates: (0..30) .map(|index| start + chrono::Duration::days(index as i64)) .collect(), - backward_factors: vec![Some(1.0); 30], - back_adjusted_closes: values.iter().copied().map(Some).collect(), + backward_factors: vec![1.0; 30], + back_adjusted_closes: values.clone(), back_adjusted_close_prefix: prefix_sums(&values), missing_back_adjusted_close_prefix: vec![0; 31], };