From 3dd7b2bd5090af90442ded2f1cd0f9b70f8d4add Mon Sep 17 00:00:00 2001 From: boris Date: Thu, 10 Sep 2026 21:20:43 +0800 Subject: [PATCH] fix: distinguish signal consumption and strategy decision schedule dates --- crates/fidc-core/src/platform_expr_strategy.rs | 15 +++++++-------- crates/fidc-core/src/signal_contract.rs | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index f7441bb..a914719 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -9122,11 +9122,10 @@ impl PlatformExprStrategy { self.stock_state(ctx, date, symbol).map(Some) } - fn unscheduled_explicit_actions_are_due(&self, ctx: &StrategyContext<'_>) -> bool { + fn unscheduled_explicit_actions_are_due(&self, decision_date: NaiveDate, execution_date: NaiveDate) -> bool { if let Some(book) = &self.config.signal_book { - return book.is_due_on(ctx); + return book.is_due_on(execution_date); } - let decision_date = ctx.decision_date; self.config.signal_rebalance_dates.is_empty() || self.config.signal_rebalance_dates.contains(&decision_date) } @@ -12418,7 +12417,7 @@ impl Strategy for PlatformExprStrategy { if self.config.explicit_action_stage == PlatformExplicitActionStage::OpenAuction && !self.config.explicit_actions.is_empty() && self.config.explicit_action_schedule.is_none() - && self.unscheduled_explicit_actions_are_due(ctx) + && self.unscheduled_explicit_actions_are_due(ctx.decision_date, ctx.execution_date) { let mut decision = self.explicit_action_decision(ctx)?; self.attach_buy_denials(ctx, &mut decision)?; @@ -12559,7 +12558,7 @@ impl PlatformExprStrategy { let (explicit_action_intents, mut explicit_action_diagnostics) = if !in_skip_window && self.config.explicit_action_stage == PlatformExplicitActionStage::OnDay && self.config.explicit_action_schedule.is_none() - && self.unscheduled_explicit_actions_are_due(ctx) + && self.unscheduled_explicit_actions_are_due(decision_date, execution_date) { self.explicit_action_intents(ctx, decision_date, &day)? } else { @@ -25526,9 +25525,9 @@ mod tests { }]; let mut strategy = PlatformExprStrategy::new(config); - assert!(strategy.unscheduled_explicit_actions_are_due(first)); - assert!(!strategy.unscheduled_explicit_actions_are_due(between)); - assert!(strategy.unscheduled_explicit_actions_are_due(second)); + assert!(strategy.unscheduled_explicit_actions_are_due(first, first)); + assert!(!strategy.unscheduled_explicit_actions_are_due(between, between)); + assert!(strategy.unscheduled_explicit_actions_are_due(second, second)); let mut decide = |date, decision_index| { let ctx = StrategyContext { diff --git a/crates/fidc-core/src/signal_contract.rs b/crates/fidc-core/src/signal_contract.rs index 5b61914..5784018 100644 --- a/crates/fidc-core/src/signal_contract.rs +++ b/crates/fidc-core/src/signal_contract.rs @@ -185,9 +185,9 @@ impl ValidatedSignalBook { Ok(snapshot) } - pub fn is_due_on(&self, ctx: &StrategyContext<'_>) -> bool { - self.index.range(ctx.execution_date.and_hms_opt(0,0,0).expect("session start")..) - .next().is_some_and(|(at,_)|at.date()==ctx.execution_date) + pub fn is_due_on(&self, execution_date: NaiveDate) -> bool { + self.index.range(execution_date.and_hms_opt(0,0,0).expect("session start")..) + .next().is_some_and(|(at,_)|at.date()==execution_date) } fn snapshot_at(&self, execution_date: NaiveDate, current_time: Option, lagged: bool) -> Result<&SignalSnapshot, String> {