From 7bc832f3c687ba5822ccdb2cdb41d2ab05a366b9 Mon Sep 17 00:00:00 2001 From: boris Date: Mon, 7 Sep 2026 03:29:34 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"=E7=BB=9F=E4=B8=80=E6=AF=8F=E6=97=A5?= =?UTF-8?q?=E7=9B=AE=E6=A0=87=E7=BB=84=E5=90=88=E6=89=A7=E8=A1=8C=E8=B7=AF?= =?UTF-8?q?=E5=BE=84"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 0542a44afe7c676423954b923f307ff99151a7a3. --- .../fidc-core/src/platform_expr_strategy.rs | 131 ++++++++++++------ 1 file changed, 87 insertions(+), 44 deletions(-) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index fef4e15..fcaae50 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -1225,7 +1225,6 @@ pub struct PlatformExprStrategy { rebalance_day_counter: usize, last_rebalance_date: Option, last_target_selection: Option>, - last_target_order: Option>, last_trading_ratio: Option, portfolio_drawdown_controller: Option, pending_highlimit_holdings: BTreeSet, @@ -1560,7 +1559,6 @@ impl PlatformExprStrategy { rebalance_day_counter: 0, last_rebalance_date: None, last_target_selection: None, - last_target_order: None, last_trading_ratio: None, portfolio_drawdown_controller, pending_highlimit_holdings: BTreeSet::new(), @@ -12533,22 +12531,10 @@ impl Strategy for PlatformExprStrategy { } let stop_take_exit_signal_symbols = current_stop_take_exit_symbols.clone(); - let target_portfolio_weights = + let target_portfolio_weight_bps = if self.config.target_portfolio_daily_enabled && selection_limit > 0 { let mut scales = Vec::new(); - let original_target_symbols = self - .last_target_order - .as_ref() - .filter(|symbols| !symbols.is_empty()) - .cloned() - .or_else(|| { - self.last_target_selection - .as_ref() - .filter(|symbols| !symbols.is_empty()) - .map(|symbols| symbols.iter().cloned().collect()) - }) - .unwrap_or_else(|| stock_list.iter().take(selection_limit).cloned().collect()); - for symbol in original_target_symbols.iter().take(selection_limit) { + for symbol in stock_list.iter().take(selection_limit) { let decision_stock = self.stock_state_with_factor_date( ctx, decision_date, @@ -12566,20 +12552,20 @@ impl Strategy for PlatformExprStrategy { &excluded_target_symbols, selection_limit, ) + .into_iter() + .collect::>() } else { - Vec::new() + BTreeMap::new() }; - let target_portfolio_weight_bps = target_portfolio_weights - .iter() - .cloned() - .collect::>(); if self.config.rotation_enabled && self.config.daily_position_target_adjust_enabled && trading_ratio > 0.0 && (self.config.target_portfolio_daily_enabled || trading_ratio < 1.0) && selection_limit > 0 - && !(self.config.target_portfolio_daily_enabled && daily_top_up_active) + && !(persistent_model_lifecycle + && self.config.target_portfolio_daily_enabled + && daily_top_up_active) && (!ctx.portfolio.positions().is_empty() || (persistent_model_lifecycle && !self.position_entry_dates.is_empty())) { @@ -13147,11 +13133,51 @@ impl Strategy for PlatformExprStrategy { } } - if daily_top_up_active && self.config.target_portfolio_daily_enabled { - for (symbol, weight_bps) in &target_portfolio_weights { - let target_value = - strategy_visible_total_value * trading_ratio * f64::from(*weight_bps) - / 10_000.0; + if daily_top_up_active + && self.config.target_portfolio_daily_enabled + && persistent_model_lifecycle + { + let mut target_symbols = self + .position_entry_dates + .keys() + .filter(|symbol| !exit_symbols.contains(*symbol)) + .filter(|symbol| !factor_position_action_symbols.contains(*symbol)) + .cloned() + .collect::>(); + for symbol in &stock_list { + if target_symbols.len() >= selection_limit { + break; + } + if target_symbols.contains(symbol) || exit_symbols.contains(symbol) { + continue; + } + if ctx + .data + .market_latest_back_adjusted_close(signal_date, symbol) + .is_none() + { + continue; + } + self.remember_position_entry_date(symbol, signal_date); + target_symbols.insert(symbol.clone()); + } + + for symbol in target_symbols { + let decision_stock = self.stock_state_with_factor_date( + ctx, + decision_date, + selection_factor_date, + &symbol, + )?; + let stock_scale = self.buy_scale(ctx, &day, &decision_stock)?; + let target_value = if let Some(weight_bps) = + target_portfolio_weight_bps.get(&symbol) + { + strategy_visible_total_value * trading_ratio * f64::from(*weight_bps) / 10_000.0 + } else { + strategy_visible_total_value * trading_ratio / selection_limit as f64 + * stock_scale + }; if !target_value.is_finite() || target_value <= 0.0 { continue; } @@ -13179,7 +13205,6 @@ impl Strategy for PlatformExprStrategy { &mut projected_execution_state, ); intraday_attempted_buys.insert(symbol.clone()); - self.remember_position_entry_date(symbol, signal_date); } let after_qty = projected .position(&symbol) @@ -13194,9 +13219,40 @@ impl Strategy for PlatformExprStrategy { deferred_daily_target_values.insert(symbol.clone(), target_value); } if after_qty > before_qty { - same_bar_buy_symbols.insert(symbol.clone()); + same_bar_buy_symbols.insert(symbol); } } + } else if daily_top_up_active && self.config.target_portfolio_daily_enabled { + self.try_daily_top_up_at_position( + ctx, + &day, + &stock_list, + decision_date, + execution_date, + projection_date, + selection_factor_date, + signal_date, + daily_top_up_target_budget, + selection_limit, + defer_execution_risk, + None, + &mut projected, + &mut projected_execution_state, + &mut order_intents, + &mut available_cash, + &mut slot_working_symbols, + &mut same_bar_buy_symbols, + &pending_full_close_symbols, + &slot_blocking_symbols, + &same_day_sold_symbols, + &exit_symbols, + &delayed_sold_symbols, + &mut intraday_attempted_buys, + &mut daily_top_up_pending_buy_value, + &deferred_daily_target_values, + debug_daily_top_up, + &mut daily_top_up_debug_notes, + )?; } if periodic_rebalance { @@ -13397,13 +13453,8 @@ impl Strategy for PlatformExprStrategy { } } if self.config.rotation_enabled && periodic_rebalance { - let target_order = stock_list - .iter() - .take(selection_limit) - .cloned() - .collect::>(); - self.last_target_selection = Some(target_order.iter().cloned().collect()); - self.last_target_order = Some(target_order); + self.last_target_selection = + Some(stock_list.iter().take(selection_limit).cloned().collect()); } if self.config.rotation_enabled && trading_ratio.is_finite() { self.last_trading_ratio = Some(trading_ratio); @@ -27722,14 +27773,6 @@ mod tests { let mut strategy = PlatformExprStrategy::new(cfg); strategy.rebalance_day_counter = 2; strategy.last_rebalance_date = Some(prev_date); - let target_order = vec![ - buy_first.to_string(), - buy_second.to_string(), - keep_first.to_string(), - keep_second.to_string(), - ]; - strategy.last_target_selection = Some(target_order.iter().cloned().collect()); - strategy.last_target_order = Some(target_order); strategy .position_entry_dates .insert(take_profit.to_string(), prev_date);