fix: honor signal dates for explicit actions
This commit is contained in:
@@ -8636,6 +8636,11 @@ impl PlatformExprStrategy {
|
|||||||
self.stock_state(ctx, date, symbol).map(Some)
|
self.stock_state(ctx, date, symbol).map(Some)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unscheduled_explicit_actions_are_due(&self, decision_date: NaiveDate) -> bool {
|
||||||
|
self.config.signal_rebalance_dates.is_empty()
|
||||||
|
|| self.config.signal_rebalance_dates.contains(&decision_date)
|
||||||
|
}
|
||||||
|
|
||||||
fn action_when_matches(
|
fn action_when_matches(
|
||||||
&self,
|
&self,
|
||||||
ctx: &StrategyContext<'_>,
|
ctx: &StrategyContext<'_>,
|
||||||
@@ -11679,6 +11684,7 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
if self.config.explicit_action_stage == PlatformExplicitActionStage::OpenAuction
|
if self.config.explicit_action_stage == PlatformExplicitActionStage::OpenAuction
|
||||||
&& !self.config.explicit_actions.is_empty()
|
&& !self.config.explicit_actions.is_empty()
|
||||||
&& self.config.explicit_action_schedule.is_none()
|
&& self.config.explicit_action_schedule.is_none()
|
||||||
|
&& self.unscheduled_explicit_actions_are_due(ctx.decision_date)
|
||||||
{
|
{
|
||||||
return self.explicit_action_decision(ctx);
|
return self.explicit_action_decision(ctx);
|
||||||
}
|
}
|
||||||
@@ -11735,6 +11741,7 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
let (explicit_action_intents, mut explicit_action_diagnostics) = if !in_skip_window
|
let (explicit_action_intents, mut explicit_action_diagnostics) = if !in_skip_window
|
||||||
&& self.config.explicit_action_stage == PlatformExplicitActionStage::OnDay
|
&& self.config.explicit_action_stage == PlatformExplicitActionStage::OnDay
|
||||||
&& self.config.explicit_action_schedule.is_none()
|
&& self.config.explicit_action_schedule.is_none()
|
||||||
|
&& self.unscheduled_explicit_actions_are_due(decision_date)
|
||||||
{
|
{
|
||||||
self.explicit_action_intents(ctx, decision_date, &day)?
|
self.explicit_action_intents(ctx, decision_date, &day)?
|
||||||
} else {
|
} else {
|
||||||
@@ -23516,6 +23523,33 @@ mod tests {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn signal_date_explicit_actions_are_due_only_on_declared_snapshot_dates() {
|
||||||
|
let first = d(2025, 2, 3);
|
||||||
|
let between = d(2025, 2, 4);
|
||||||
|
let second = d(2025, 2, 5);
|
||||||
|
let mut config = PlatformExprStrategyConfig::generic();
|
||||||
|
config.signal_rebalance_dates = BTreeSet::from([first, second]);
|
||||||
|
config.explicit_actions = vec![PlatformTradeAction::Order {
|
||||||
|
kind: PlatformExplicitOrderKind::TargetPercent,
|
||||||
|
symbol: "000001.SZ".to_string(),
|
||||||
|
amount_expr: format!(
|
||||||
|
"if decision_date == \"{first}\" {{ 0.5 }} else if decision_date == \"{second}\" {{ 0.0 }} else {{ 0.0 }}"
|
||||||
|
),
|
||||||
|
limit_price_expr: None,
|
||||||
|
time_in_force: None,
|
||||||
|
start_time_expr: None,
|
||||||
|
end_time_expr: None,
|
||||||
|
when_expr: None,
|
||||||
|
reason: "full_target_snapshot".to_string(),
|
||||||
|
}];
|
||||||
|
let 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));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn platform_explicit_actions_keep_every_declared_trade_time() {
|
fn platform_explicit_actions_keep_every_declared_trade_time() {
|
||||||
let calendar = sample_calendar();
|
let calendar = sample_calendar();
|
||||||
|
|||||||
Reference in New Issue
Block a user