diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 29a3118..8093b61 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -8483,6 +8483,47 @@ impl Strategy for PlatformExprStrategy { } } + let mut actionable_stop_take_exit_symbols = BTreeSet::::new(); + if self.config.aiquant_transaction_cost + && self.config.rotation_enabled + && trading_ratio > 0.0 + && trading_ratio < 1.0 + && selection_limit > 0 + { + for position in ctx.portfolio.positions().values() { + if position.quantity == 0 + || delayed_sold_symbols.contains(&position.symbol) + || pending_full_close_symbols.contains(&position.symbol) + || self.pending_highlimit_holdings.contains(&position.symbol) + { + continue; + } + if self.regular_sell_should_wait_due_to_highlimit( + ctx, + projection_date, + &position.symbol, + self.intraday_execution_start_time(), + )? { + continue; + } + let (stop_hit, profit_hit) = + self.stop_take_action_for_position(ctx, signal_date, &day, position)?; + if !stop_hit && !profit_hit { + continue; + } + if defer_execution_risk + || self.can_sell_position_at_time( + ctx, + execution_date, + &position.symbol, + Some(self.intraday_execution_start_time()), + ) + { + actionable_stop_take_exit_symbols.insert(position.symbol.clone()); + } + } + } + if self.config.aiquant_transaction_cost && self.config.rotation_enabled && trading_ratio > 0.0 @@ -8509,6 +8550,9 @@ impl Strategy for PlatformExprStrategy { if pending_full_close_symbols.contains(&position.symbol) { continue; } + if actionable_stop_take_exit_symbols.contains(&position.symbol) { + continue; + } let current_value = self.projected_position_value_at_execution_price( ctx, &projected,