From 6820b63d5649664028060da88c293b1bdd77541f Mon Sep 17 00:00:00 2001 From: boris Date: Mon, 6 Jul 2026 08:26:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B9=B3=E5=8F=B0=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E6=AF=8F=E6=97=A5=E8=B0=83=E4=BB=93=E5=92=8C=E6=AD=A2?= =?UTF-8?q?=E6=8D=9F=E4=B8=8B=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fidc-core/src/platform_expr_strategy.rs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 73c9370..98e3b89 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -7766,9 +7766,6 @@ impl Strategy for PlatformExprStrategy { } else { 0.0 }; - let previous_trading_ratio = self.last_trading_ratio.unwrap_or(1.0); - let weak_market_shrink_due = - trading_ratio.is_finite() && trading_ratio < previous_trading_ratio - 1e-9; let marked_total_value = self.marked_total_value(ctx, projection_date); let mut aiquant_total_value = if marked_total_value.is_finite() && marked_total_value > 0.0 { @@ -7850,6 +7847,7 @@ impl Strategy for PlatformExprStrategy { let mut intraday_attempted_buys = BTreeSet::::new(); let mut delayed_sold_symbols = BTreeSet::::new(); let mut unresolved_stop_loss_symbols = BTreeSet::::new(); + let mut pre_detected_stop_take_exit_symbols = BTreeSet::::new(); let mut pending_risk_level_forced_exit_symbols = BTreeSet::::new(); let delayed_limit_exit_time = self .config @@ -8101,11 +8099,11 @@ impl Strategy for PlatformExprStrategy { let (stop_hit, profit_hit) = self.stop_take_action_for_position(ctx, signal_date, &day, position)?; if stop_hit { - pending_full_close_symbols.insert(position.symbol.clone()); + pre_detected_stop_take_exit_symbols.insert(position.symbol.clone()); continue; } if profit_hit { - pending_full_close_symbols.insert(position.symbol.clone()); + pre_detected_stop_take_exit_symbols.insert(position.symbol.clone()); continue; } let can_sell = defer_execution_risk @@ -8168,7 +8166,6 @@ impl Strategy for PlatformExprStrategy { && self.config.rotation_enabled && trading_ratio > 0.0 && trading_ratio < 1.0 - && weak_market_shrink_due && selection_limit > 0 && !ctx.portfolio.positions().is_empty() { @@ -8189,6 +8186,9 @@ impl Strategy for PlatformExprStrategy { if pending_full_close_symbols.contains(&position.symbol) { continue; } + if pre_detected_stop_take_exit_symbols.contains(&position.symbol) { + continue; + } let current_value = self.projected_position_value_at_execution_price( ctx, &projected, @@ -15122,7 +15122,7 @@ mod tests { } #[test] - fn platform_aiquant_weak_market_does_not_retarget_same_ratio_every_day() { + fn platform_aiquant_weak_market_retargets_same_ratio_every_day() { let first_date = d(2023, 5, 4); let second_date = d(2023, 5, 5); let symbol = "300621.SZ"; @@ -15225,7 +15225,7 @@ mod tests { let mut held_portfolio = PortfolioState::new(1_000_000.0); held_portfolio .position_mut(symbol) - .buy(first_date, 4_000, 10.52); + .buy(first_date, 400, 10.52); let second_ctx = StrategyContext { execution_date: second_date, decision_date: second_date, @@ -15269,9 +15269,13 @@ mod tests { .expect("second platform decision"); assert!( - !second_decision.order_intents.iter().any(|intent| matches!( + second_decision.order_intents.iter().any(|intent| matches!( intent, - OrderIntent::Shares { reason, .. } if reason == "daily_position_target_adjust" + OrderIntent::Shares { + reason, + quantity, + .. + } if reason == "daily_position_target_adjust" && *quantity > 0 )), "{:?}", second_decision.order_intents