修正FIDC未完成清仓占位预算

This commit is contained in:
boris
2026-07-08 01:12:30 +08:00
parent 12da5a4704
commit e0a7eb8972
+46 -16
View File
@@ -2214,14 +2214,19 @@ impl PlatformExprStrategy {
working_symbols: &BTreeSet<String>, working_symbols: &BTreeSet<String>,
value_symbols: &BTreeSet<String>, value_symbols: &BTreeSet<String>,
pending_buy_value: f64, pending_buy_value: f64,
slot_blocking_symbols: &BTreeSet<String>,
) -> f64 { ) -> f64 {
if selection_limit == 0 || !target_budget.is_finite() || target_budget <= 0.0 { if selection_limit == 0 || !target_budget.is_finite() || target_budget <= 0.0 {
return 0.0; return 0.0;
} }
if working_symbols.len() >= selection_limit { let effective_working_count =
Self::effective_slot_count(working_symbols, slot_blocking_symbols);
if effective_working_count >= selection_limit {
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(effective_working_count)
.max(1);
let active_value = self.remaining_buy_cash_active_value( let active_value = self.remaining_buy_cash_active_value(
ctx, ctx,
projected, projected,
@@ -2235,6 +2240,13 @@ impl PlatformExprStrategy {
per_slot_budget.min(single_slot_cap) per_slot_budget.min(single_slot_cap)
} }
fn effective_slot_count(
working_symbols: &BTreeSet<String>,
slot_blocking_symbols: &BTreeSet<String>,
) -> usize {
working_symbols.union(slot_blocking_symbols).count()
}
fn remaining_buy_cash_active_value( fn remaining_buy_cash_active_value(
&self, &self,
ctx: &StrategyContext<'_>, ctx: &StrategyContext<'_>,
@@ -8483,7 +8495,7 @@ impl Strategy for PlatformExprStrategy {
self.forget_position_entry_date(&position.symbol); self.forget_position_entry_date(&position.symbol);
slot_working_symbols.remove(&position.symbol); slot_working_symbols.remove(&position.symbol);
if can_sell { if can_sell {
if self let close_submitted = self
.project_target_zero( .project_target_zero(
ctx, ctx,
&mut projected, &mut projected,
@@ -8491,11 +8503,17 @@ impl Strategy for PlatformExprStrategy {
&position.symbol, &position.symbol,
&mut projected_execution_state, &mut projected_execution_state,
) )
.is_some() .is_some();
&& Self::projected_position_is_flat(&projected, &position.symbol) if close_submitted {
{ if Self::projected_position_is_flat(&projected, &position.symbol) {
same_day_sold_symbols.insert(position.symbol.clone()); same_day_sold_symbols.insert(position.symbol.clone());
self.pending_full_close_symbols.remove(&position.symbol); pending_full_close_symbols.remove(&position.symbol);
self.pending_full_close_symbols.remove(&position.symbol);
} else {
pending_full_close_symbols.insert(position.symbol.clone());
self.pending_full_close_symbols
.insert(position.symbol.clone());
}
} }
} else { } else {
unresolved_stop_loss_symbols.insert(position.symbol.clone()); unresolved_stop_loss_symbols.insert(position.symbol.clone());
@@ -8512,8 +8530,8 @@ impl Strategy for PlatformExprStrategy {
}); });
self.forget_position_entry_date(&position.symbol); self.forget_position_entry_date(&position.symbol);
slot_working_symbols.remove(&position.symbol); slot_working_symbols.remove(&position.symbol);
if can_sell if can_sell {
&& self let close_submitted = self
.project_target_zero( .project_target_zero(
ctx, ctx,
&mut projected, &mut projected,
@@ -8521,11 +8539,18 @@ impl Strategy for PlatformExprStrategy {
&position.symbol, &position.symbol,
&mut projected_execution_state, &mut projected_execution_state,
) )
.is_some() .is_some();
&& Self::projected_position_is_flat(&projected, &position.symbol) if close_submitted {
{ if Self::projected_position_is_flat(&projected, &position.symbol) {
same_day_sold_symbols.insert(position.symbol.clone()); same_day_sold_symbols.insert(position.symbol.clone());
self.pending_full_close_symbols.remove(&position.symbol); pending_full_close_symbols.remove(&position.symbol);
self.pending_full_close_symbols.remove(&position.symbol);
} else {
pending_full_close_symbols.insert(position.symbol.clone());
self.pending_full_close_symbols
.insert(position.symbol.clone());
}
}
} }
} }
} }
@@ -8546,7 +8571,9 @@ impl Strategy for PlatformExprStrategy {
let value_symbols = working_symbols.clone(); let value_symbols = working_symbols.clone();
let mut pending_buy_value = 0.0_f64; let mut pending_buy_value = 0.0_f64;
loop { loop {
if working_symbols.len() >= selection_limit { if Self::effective_slot_count(&working_symbols, &pending_full_close_symbols)
>= selection_limit
{
break; break;
} }
let active_value = if debug_daily_top_up { let active_value = if debug_daily_top_up {
@@ -8569,6 +8596,7 @@ impl Strategy for PlatformExprStrategy {
&working_symbols, &working_symbols,
&value_symbols, &value_symbols,
pending_buy_value, pending_buy_value,
&pending_full_close_symbols,
); );
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 { if debug_daily_top_up {
@@ -8834,6 +8862,7 @@ impl Strategy for PlatformExprStrategy {
&rebalance_working_symbols, &rebalance_working_symbols,
&rebalance_value_symbols, &rebalance_value_symbols,
rebalance_pending_buy_value, rebalance_pending_buy_value,
&pending_full_close_symbols,
); );
slot_buy_cash * stock_scale slot_buy_cash * stock_scale
}; };
@@ -19760,6 +19789,7 @@ mod tests {
&working_symbols, &working_symbols,
&value_symbols, &value_symbols,
0.0, 0.0,
&BTreeSet::new(),
); );
assert!( assert!(