Revert "perf(core): reuse rolling endpoints per stock state"
This reverts commit 732c3cfbf5.
This commit is contained in:
@@ -646,22 +646,14 @@ impl AdjustedCloseSeries {
|
||||
}
|
||||
|
||||
fn decision_moving_average(&self, date: NaiveDate, lookback: usize) -> Option<f64> {
|
||||
let end = self.decision_end_index(date)?;
|
||||
self.decision_moving_average_at_end(end, lookback)
|
||||
}
|
||||
|
||||
fn decision_end_index(&self, date: NaiveDate) -> Option<usize> {
|
||||
match self.dates.binary_search(&date) {
|
||||
Ok(index) => Some(index),
|
||||
Err(0) => None,
|
||||
Err(index) => Some(index),
|
||||
}
|
||||
}
|
||||
|
||||
fn decision_moving_average_at_end(&self, end: usize, lookback: usize) -> Option<f64> {
|
||||
if lookback == 0 {
|
||||
return None;
|
||||
}
|
||||
let end = match self.dates.binary_search(&date) {
|
||||
Ok(index) => index,
|
||||
Err(0) => return None,
|
||||
Err(index) => index,
|
||||
};
|
||||
if end < lookback {
|
||||
return None;
|
||||
}
|
||||
@@ -953,14 +945,6 @@ impl SymbolPriceSeries {
|
||||
|
||||
fn decision_volume_moving_average(&self, date: NaiveDate, lookback: usize) -> Option<f64> {
|
||||
let end = self.previous_completed_end_index(date)?;
|
||||
self.decision_volume_moving_average_at_end(end, lookback)
|
||||
}
|
||||
|
||||
fn decision_volume_moving_average_at_end(
|
||||
&self,
|
||||
end: usize,
|
||||
lookback: usize,
|
||||
) -> Option<f64> {
|
||||
self.valid_volume_window(end, lookback).map(|(start, end)| {
|
||||
normalize_rolling_factor(
|
||||
(self.valid_volume_sum_prefix[end] - self.valid_volume_sum_prefix[start])
|
||||
@@ -1262,28 +1246,6 @@ pub(crate) struct SymbolSnapshotRefs<'a> {
|
||||
pub candidate: Option<&'a CandidateEligibility>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) struct DecisionRollingCursor<'a> {
|
||||
adjusted_close: Option<(&'a AdjustedCloseSeries, usize)>,
|
||||
volume: Option<(&'a SymbolPriceSeries, usize)>,
|
||||
}
|
||||
|
||||
impl DecisionRollingCursor<'_> {
|
||||
pub(crate) fn moving_average(&self, field: &str, lookback: usize) -> Option<f64> {
|
||||
match field {
|
||||
"close" => self
|
||||
.adjusted_close
|
||||
.and_then(|(series, end)| series.decision_moving_average_at_end(end, lookback)),
|
||||
"volume" => self
|
||||
.volume
|
||||
.and_then(|(series, end)| {
|
||||
series.decision_volume_moving_average_at_end(end, lookback)
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DataSet {
|
||||
pub fn with_additional_trading_dates(
|
||||
mut self,
|
||||
@@ -2919,27 +2881,6 @@ impl DataSet {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn market_decision_rolling_cursor_by_symbol_id(
|
||||
&self,
|
||||
date: NaiveDate,
|
||||
symbol_id: u32,
|
||||
) -> DecisionRollingCursor<'_> {
|
||||
let adjusted_close = self
|
||||
.adjusted_close_series_by_symbol_id(symbol_id)
|
||||
.and_then(|series| series.decision_end_index(date).map(|end| (series, end)));
|
||||
let volume = self
|
||||
.market_series_by_symbol_id(symbol_id)
|
||||
.and_then(|series| {
|
||||
series
|
||||
.previous_completed_end_index(date)
|
||||
.map(|end| (series, end))
|
||||
});
|
||||
DecisionRollingCursor {
|
||||
adjusted_close,
|
||||
volume,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn market_current_numeric_moving_average(
|
||||
&self,
|
||||
date: NaiveDate,
|
||||
@@ -4191,78 +4132,6 @@ mod tests {
|
||||
assert!(signal.candidate.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decision_rolling_cursor_matches_existing_close_and_volume_contract() {
|
||||
let dates = ["2025-01-02", "2025-01-03", "2025-01-06", "2025-01-07"];
|
||||
let market = dates
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, date)| market_row(date, 10.0 + index as f64, 1_000 + index as u64 * 100))
|
||||
.collect::<Vec<_>>();
|
||||
let factors = dates
|
||||
.iter()
|
||||
.map(|date| DailyFactorSnapshot {
|
||||
date: NaiveDate::parse_from_str(date, "%Y-%m-%d").unwrap(),
|
||||
symbol: "000001.SZ".to_string(),
|
||||
market_cap_bn: 100.0,
|
||||
free_float_cap_bn: 80.0,
|
||||
pe_ttm: 0.0,
|
||||
turnover_ratio: None,
|
||||
effective_turnover_ratio: None,
|
||||
extra_factors: NumericFactorMap::from([(
|
||||
Cow::Borrowed(BACKWARD_ADJUSTMENT_FACTOR_FIELD),
|
||||
1.0,
|
||||
)]),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let benchmarks = dates
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, date)| benchmark_row(date, 20.0 + index as f64))
|
||||
.collect::<Vec<_>>();
|
||||
let data = DataSet::from_components(
|
||||
vec![Instrument {
|
||||
symbol: "000001.SZ".to_string(),
|
||||
name: "000001.SZ".to_string(),
|
||||
board: "SZ".to_string(),
|
||||
round_lot: 100,
|
||||
listed_at: None,
|
||||
delisted_at: None,
|
||||
status: "active".to_string(),
|
||||
}],
|
||||
market,
|
||||
factors,
|
||||
Vec::new(),
|
||||
benchmarks,
|
||||
)
|
||||
.unwrap();
|
||||
let symbol_id = data.symbol_id("000001.SZ").unwrap();
|
||||
let date = NaiveDate::parse_from_str("2025-01-07", "%Y-%m-%d").unwrap();
|
||||
let cursor = data.market_decision_rolling_cursor_by_symbol_id(date, symbol_id);
|
||||
for lookback in [1, 2, 3] {
|
||||
assert_eq!(
|
||||
cursor.moving_average("close", lookback),
|
||||
data.market_decision_numeric_moving_average_by_symbol_id(
|
||||
date,
|
||||
symbol_id,
|
||||
"000001.SZ",
|
||||
"close",
|
||||
lookback,
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
cursor.moving_average("volume", lookback),
|
||||
data.market_decision_numeric_moving_average_by_symbol_id(
|
||||
date,
|
||||
symbol_id,
|
||||
"000001.SZ",
|
||||
"volume",
|
||||
lookback,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn additional_terminal_calendar_dates_are_isolated_from_shared_market_data() {
|
||||
let date = NaiveDate::parse_from_str("2025-01-02", "%Y-%m-%d").unwrap();
|
||||
|
||||
@@ -3935,15 +3935,11 @@ impl PlatformExprStrategy {
|
||||
None
|
||||
};
|
||||
let instrument = ctx.data.instrument(symbol);
|
||||
let rolling_cursor = ctx
|
||||
.data
|
||||
.market_decision_rolling_cursor_by_symbol_id(date, symbol_id);
|
||||
let rolling = |field: &'static str, lookback: usize| -> f64 {
|
||||
if !self.stock_rolling_requirements.requires(field, lookback) {
|
||||
return f64::NAN;
|
||||
}
|
||||
rolling_cursor
|
||||
.moving_average(field, lookback)
|
||||
self.stock_decision_rolling_mean(ctx, date, symbol_id, symbol, field, lookback)
|
||||
.unwrap_or(f64::NAN)
|
||||
};
|
||||
let stock_ma_short = rolling("close", self.config.stock_short_ma_days);
|
||||
|
||||
Reference in New Issue
Block a user