增加日内补仓预算诊断

This commit is contained in:
boris
2026-06-19 06:03:17 +08:00
parent 1db80e1e13
commit 4b6301cb37
+64 -6
View File
@@ -1767,7 +1767,28 @@ impl PlatformExprStrategy {
return 0.0; return 0.0;
} }
let slots_remaining = selection_limit.saturating_sub(working_symbols.len()).max(1); let slots_remaining = selection_limit.saturating_sub(working_symbols.len()).max(1);
let active_value = working_symbols let active_value = self.remaining_buy_cash_active_value(
ctx,
projected,
date,
working_symbols,
value_symbols,
);
let working_value = active_value + pending_buy_value.max(0.0);
let per_slot_budget = (target_budget - working_value).max(0.0) / slots_remaining as f64;
let single_slot_cap = target_budget / selection_limit as f64;
per_slot_budget.min(single_slot_cap)
}
fn remaining_buy_cash_active_value(
&self,
ctx: &StrategyContext<'_>,
projected: &PortfolioState,
date: NaiveDate,
working_symbols: &BTreeSet<String>,
value_symbols: &BTreeSet<String>,
) -> f64 {
working_symbols
.iter() .iter()
.filter(|symbol| value_symbols.contains(*symbol)) .filter(|symbol| value_symbols.contains(*symbol))
.map(|symbol| { .map(|symbol| {
@@ -1778,11 +1799,7 @@ impl PlatformExprStrategy {
} }
}) })
.filter(|value| value.is_finite() && *value > 0.0) .filter(|value| value.is_finite() && *value > 0.0)
.sum::<f64>(); .sum::<f64>()
let working_value = active_value + pending_buy_value.max(0.0);
let per_slot_budget = (target_budget - working_value).max(0.0) / slots_remaining as f64;
let single_slot_cap = target_budget / selection_limit as f64;
per_slot_budget.min(single_slot_cap)
} }
fn project_order_value( fn project_order_value(
@@ -6493,6 +6510,10 @@ impl Strategy for PlatformExprStrategy {
let mut projected = ctx.portfolio.clone(); let mut projected = ctx.portfolio.clone();
let mut projected_execution_state = ProjectedExecutionState::default(); let mut projected_execution_state = ProjectedExecutionState::default();
let mut order_intents = Vec::new(); let mut order_intents = Vec::new();
let debug_daily_top_up = std::env::var("FIDC_BT_DEBUG_DAILY_TOP_UP")
.map(|value| value == "1" || value.eq_ignore_ascii_case("true"))
.unwrap_or(false);
let mut daily_top_up_debug_notes = Vec::<String>::new();
let mut exit_symbols = BTreeSet::new(); let mut exit_symbols = BTreeSet::new();
let mut same_day_sold_symbols = BTreeSet::<String>::new(); let mut same_day_sold_symbols = BTreeSet::<String>::new();
let mut intraday_attempted_buys = BTreeSet::<String>::new(); let mut intraday_attempted_buys = BTreeSet::<String>::new();
@@ -6899,6 +6920,17 @@ impl Strategy for PlatformExprStrategy {
if working_symbols.len() >= selection_limit { if working_symbols.len() >= selection_limit {
break; break;
} }
let active_value = if debug_daily_top_up {
self.remaining_buy_cash_active_value(
ctx,
&projected,
execution_date,
&working_symbols,
&value_symbols,
)
} else {
0.0
};
let slot_buy_cash = self.remaining_buy_cash_per_slot( let slot_buy_cash = self.remaining_buy_cash_per_slot(
ctx, ctx,
&projected, &projected,
@@ -6910,6 +6942,20 @@ impl Strategy for PlatformExprStrategy {
pending_buy_value, pending_buy_value,
); );
let available_buy_cash = slot_buy_cash.min(aiquant_available_cash); let available_buy_cash = slot_buy_cash.min(aiquant_available_cash);
if debug_daily_top_up {
daily_top_up_debug_notes.push(format!(
"daily_top_up_budget date={} working={} value_symbols={} active_value={:.4} pending_buy_value={:.4} target_budget={:.4} slot_buy_cash={:.4} available_cash={:.4} portfolio_cash={:.4}",
execution_date,
working_symbols.len(),
value_symbols.len(),
active_value,
pending_buy_value,
target_budget,
slot_buy_cash,
available_buy_cash,
aiquant_available_cash
));
}
if slot_buy_cash <= 0.0 || available_buy_cash < slot_buy_cash * 0.5 { if slot_buy_cash <= 0.0 || available_buy_cash < slot_buy_cash * 0.5 {
break; break;
} }
@@ -6967,6 +7013,17 @@ impl Strategy for PlatformExprStrategy {
working_symbols.insert(symbol.clone()); working_symbols.insert(symbol.clone());
slot_working_symbols.insert(symbol.clone()); slot_working_symbols.insert(symbol.clone());
pending_buy_value += available_buy_cash; pending_buy_value += available_buy_cash;
if debug_daily_top_up {
daily_top_up_debug_notes.push(format!(
"daily_top_up_fill date={} symbol={} requested_cash={:.4} filled_qty={} spent={:.4} remaining_cash={:.4}",
execution_date,
symbol,
buy_cash,
filled_qty,
spent,
aiquant_available_cash
));
}
filled_any = true; filled_any = true;
break; break;
} }
@@ -7208,6 +7265,7 @@ impl Strategy for PlatformExprStrategy {
]; ];
diagnostics.extend(selection_notes); diagnostics.extend(selection_notes);
diagnostics.extend(explicit_action_diagnostics); diagnostics.extend(explicit_action_diagnostics);
diagnostics.extend(daily_top_up_debug_notes);
let notes = vec![ let notes = vec![
format!("stock_list={}", stock_list.len()), format!("stock_list={}", stock_list.len()),