增加日内补仓预算诊断
This commit is contained in:
@@ -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()),
|
||||||
|
|||||||
Reference in New Issue
Block a user