优化复权与成交量滚动窗口

This commit is contained in:
boris
2026-08-01 21:23:11 +08:00
parent 40e4c12cdd
commit faa8ac7c13
+32 -9
View File
@@ -493,6 +493,8 @@ struct AdjustedCloseSeries {
dates: Vec<NaiveDate>, dates: Vec<NaiveDate>,
backward_factors: Vec<Option<f64>>, backward_factors: Vec<Option<f64>>,
back_adjusted_closes: Vec<Option<f64>>, back_adjusted_closes: Vec<Option<f64>>,
back_adjusted_close_prefix: Vec<f64>,
missing_back_adjusted_close_prefix: Vec<u32>,
} }
impl AdjustedCloseSeries { impl AdjustedCloseSeries {
@@ -502,6 +504,10 @@ impl AdjustedCloseSeries {
) -> Option<Self> { ) -> Option<Self> {
let mut backward_factors = Vec::with_capacity(market.dates.len()); let mut backward_factors = Vec::with_capacity(market.dates.len());
let mut back_adjusted_closes = Vec::with_capacity(market.dates.len()); let mut back_adjusted_closes = Vec::with_capacity(market.dates.len());
let mut back_adjusted_close_prefix = Vec::with_capacity(market.dates.len() + 1);
let mut missing_back_adjusted_close_prefix = Vec::with_capacity(market.dates.len() + 1);
back_adjusted_close_prefix.push(0.0);
missing_back_adjusted_close_prefix.push(0);
for (date, close) in market.dates.iter().zip(&market.closes) { for (date, close) in market.dates.iter().zip(&market.closes) {
let factor = factor_by_date let factor = factor_by_date
.get(date) .get(date)
@@ -515,11 +521,27 @@ impl AdjustedCloseSeries {
.map(|factor| close * factor); .map(|factor| close * factor);
backward_factors.push(factor); backward_factors.push(factor);
back_adjusted_closes.push(back_adjusted_close); back_adjusted_closes.push(back_adjusted_close);
back_adjusted_close_prefix.push(
back_adjusted_close_prefix
.last()
.copied()
.unwrap_or_default()
+ back_adjusted_close.unwrap_or_default(),
);
missing_back_adjusted_close_prefix.push(
missing_back_adjusted_close_prefix
.last()
.copied()
.unwrap_or_default()
+ u32::from(back_adjusted_close.is_none()),
);
} }
Some(Self { Some(Self {
dates: market.dates.clone(), dates: market.dates.clone(),
backward_factors, backward_factors,
back_adjusted_closes, back_adjusted_closes,
back_adjusted_close_prefix,
missing_back_adjusted_close_prefix,
}) })
} }
@@ -537,10 +559,12 @@ impl AdjustedCloseSeries {
} }
let base_factor = self.backward_factors.get(end - 1).copied().flatten()?; let base_factor = self.backward_factors.get(end - 1).copied().flatten()?;
let start = end - lookback; let start = end - lookback;
let sum = self.back_adjusted_closes[start..end] if self.missing_back_adjusted_close_prefix[end]
.iter() != self.missing_back_adjusted_close_prefix[start]
.copied() {
.try_fold(0.0, |sum, value| value.map(|value| sum + value))?; return None;
}
let sum = self.back_adjusted_close_prefix[end] - self.back_adjusted_close_prefix[start];
if !sum.is_finite() { if !sum.is_finite() {
return None; return None;
} }
@@ -779,10 +803,7 @@ impl SymbolPriceSeries {
return None; return None;
} }
let start = end - lookback; let start = end - lookback;
let sum = self.volumes[start..end] let sum = self.volume_prefix[end] - self.volume_prefix[start];
.iter()
.map(|value| *value as f64)
.sum::<f64>();
if !sum.is_finite() { if !sum.is_finite() {
return None; return None;
} }
@@ -3705,7 +3726,9 @@ mod tests {
.map(|index| start + chrono::Duration::days(index as i64)) .map(|index| start + chrono::Duration::days(index as i64))
.collect(), .collect(),
backward_factors: vec![Some(1.0); 30], backward_factors: vec![Some(1.0); 30],
back_adjusted_closes: values.into_iter().map(Some).collect(), back_adjusted_closes: values.iter().copied().map(Some).collect(),
back_adjusted_close_prefix: prefix_sums(&values),
missing_back_adjusted_close_prefix: vec![0; 31],
}; };
let date = *series.dates.last().expect("last date"); let date = *series.dates.last().expect("last date");