Revert "统一每日目标组合执行路径"

This reverts commit 0542a44afe.
This commit is contained in:
boris
2026-09-07 03:29:34 +08:00
parent 46c647d676
commit 7bc832f3c6
+87 -44
View File
@@ -1225,7 +1225,6 @@ pub struct PlatformExprStrategy {
rebalance_day_counter: usize, rebalance_day_counter: usize,
last_rebalance_date: Option<NaiveDate>, last_rebalance_date: Option<NaiveDate>,
last_target_selection: Option<BTreeSet<String>>, last_target_selection: Option<BTreeSet<String>>,
last_target_order: Option<Vec<String>>,
last_trading_ratio: Option<f64>, last_trading_ratio: Option<f64>,
portfolio_drawdown_controller: Option<PlatformPortfolioDrawdownController>, portfolio_drawdown_controller: Option<PlatformPortfolioDrawdownController>,
pending_highlimit_holdings: BTreeSet<String>, pending_highlimit_holdings: BTreeSet<String>,
@@ -1560,7 +1559,6 @@ impl PlatformExprStrategy {
rebalance_day_counter: 0, rebalance_day_counter: 0,
last_rebalance_date: None, last_rebalance_date: None,
last_target_selection: None, last_target_selection: None,
last_target_order: None,
last_trading_ratio: None, last_trading_ratio: None,
portfolio_drawdown_controller, portfolio_drawdown_controller,
pending_highlimit_holdings: BTreeSet::new(), 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 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 { if self.config.target_portfolio_daily_enabled && selection_limit > 0 {
let mut scales = Vec::new(); let mut scales = Vec::new();
let original_target_symbols = self for symbol in stock_list.iter().take(selection_limit) {
.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) {
let decision_stock = self.stock_state_with_factor_date( let decision_stock = self.stock_state_with_factor_date(
ctx, ctx,
decision_date, decision_date,
@@ -12566,20 +12552,20 @@ impl Strategy for PlatformExprStrategy {
&excluded_target_symbols, &excluded_target_symbols,
selection_limit, selection_limit,
) )
.into_iter()
.collect::<BTreeMap<_, _>>()
} else { } else {
Vec::new() BTreeMap::new()
}; };
let target_portfolio_weight_bps = target_portfolio_weights
.iter()
.cloned()
.collect::<BTreeMap<_, _>>();
if self.config.rotation_enabled if self.config.rotation_enabled
&& self.config.daily_position_target_adjust_enabled && self.config.daily_position_target_adjust_enabled
&& trading_ratio > 0.0 && trading_ratio > 0.0
&& (self.config.target_portfolio_daily_enabled || trading_ratio < 1.0) && (self.config.target_portfolio_daily_enabled || trading_ratio < 1.0)
&& selection_limit > 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() && (!ctx.portfolio.positions().is_empty()
|| (persistent_model_lifecycle && !self.position_entry_dates.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 { if daily_top_up_active
for (symbol, weight_bps) in &target_portfolio_weights { && self.config.target_portfolio_daily_enabled
let target_value = && persistent_model_lifecycle
strategy_visible_total_value * trading_ratio * f64::from(*weight_bps) {
/ 10_000.0; 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::<BTreeSet<_>>();
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 { if !target_value.is_finite() || target_value <= 0.0 {
continue; continue;
} }
@@ -13179,7 +13205,6 @@ impl Strategy for PlatformExprStrategy {
&mut projected_execution_state, &mut projected_execution_state,
); );
intraday_attempted_buys.insert(symbol.clone()); intraday_attempted_buys.insert(symbol.clone());
self.remember_position_entry_date(symbol, signal_date);
} }
let after_qty = projected let after_qty = projected
.position(&symbol) .position(&symbol)
@@ -13194,9 +13219,40 @@ impl Strategy for PlatformExprStrategy {
deferred_daily_target_values.insert(symbol.clone(), target_value); deferred_daily_target_values.insert(symbol.clone(), target_value);
} }
if after_qty > before_qty { 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 { if periodic_rebalance {
@@ -13397,13 +13453,8 @@ impl Strategy for PlatformExprStrategy {
} }
} }
if self.config.rotation_enabled && periodic_rebalance { if self.config.rotation_enabled && periodic_rebalance {
let target_order = stock_list self.last_target_selection =
.iter() Some(stock_list.iter().take(selection_limit).cloned().collect());
.take(selection_limit)
.cloned()
.collect::<Vec<_>>();
self.last_target_selection = Some(target_order.iter().cloned().collect());
self.last_target_order = Some(target_order);
} }
if self.config.rotation_enabled && trading_ratio.is_finite() { if self.config.rotation_enabled && trading_ratio.is_finite() {
self.last_trading_ratio = Some(trading_ratio); self.last_trading_ratio = Some(trading_ratio);
@@ -27722,14 +27773,6 @@ mod tests {
let mut strategy = PlatformExprStrategy::new(cfg); let mut strategy = PlatformExprStrategy::new(cfg);
strategy.rebalance_day_counter = 2; strategy.rebalance_day_counter = 2;
strategy.last_rebalance_date = Some(prev_date); 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 strategy
.position_entry_dates .position_entry_dates
.insert(take_profit.to_string(), prev_date); .insert(take_profit.to_string(), prev_date);