按持仓顺序处理未完成清仓补仓
This commit is contained in:
@@ -8323,7 +8323,15 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
.filter(|symbol| !delayed_sold_symbols.contains(*symbol))
|
.filter(|symbol| !delayed_sold_symbols.contains(*symbol))
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<BTreeSet<_>>();
|
.collect::<BTreeSet<_>>();
|
||||||
|
let daily_top_up_active = self.config.daily_top_up_enabled
|
||||||
|
&& self.config.rotation_enabled
|
||||||
|
&& !periodic_rebalance
|
||||||
|
&& trading_ratio > 0.0
|
||||||
|
&& selection_limit > 0;
|
||||||
|
let daily_top_up_target_budget = aiquant_total_value * trading_ratio;
|
||||||
|
let mut daily_top_up_pending_buy_value = 0.0_f64;
|
||||||
let mut pending_full_close_symbols = BTreeSet::<String>::new();
|
let mut pending_full_close_symbols = BTreeSet::<String>::new();
|
||||||
|
let mut interleaved_pending_full_close_symbols = BTreeSet::<String>::new();
|
||||||
let risk_level_forced_exit_time = self.risk_level_forced_exit_time();
|
let risk_level_forced_exit_time = self.risk_level_forced_exit_time();
|
||||||
self.pending_full_close_symbols.retain(|symbol| {
|
self.pending_full_close_symbols.retain(|symbol| {
|
||||||
ctx.portfolio
|
ctx.portfolio
|
||||||
@@ -8350,6 +8358,10 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pending_full_close_symbols.insert(symbol.clone());
|
pending_full_close_symbols.insert(symbol.clone());
|
||||||
|
if daily_top_up_active {
|
||||||
|
interleaved_pending_full_close_symbols.insert(symbol);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
exit_symbols.insert(symbol.clone());
|
exit_symbols.insert(symbol.clone());
|
||||||
order_intents.push(OrderIntent::TargetValue {
|
order_intents.push(OrderIntent::TargetValue {
|
||||||
symbol: symbol.clone(),
|
symbol: symbol.clone(),
|
||||||
@@ -8640,18 +8652,76 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let daily_top_up_active = self.config.daily_top_up_enabled
|
|
||||||
&& self.config.rotation_enabled
|
|
||||||
&& !periodic_rebalance
|
|
||||||
&& trading_ratio > 0.0
|
|
||||||
&& selection_limit > 0;
|
|
||||||
let daily_top_up_target_budget = aiquant_total_value * trading_ratio;
|
|
||||||
let mut daily_top_up_pending_buy_value = 0.0_f64;
|
|
||||||
|
|
||||||
for position in ctx.portfolio.positions().values() {
|
for position in ctx.portfolio.positions().values() {
|
||||||
if delayed_sold_symbols.contains(&position.symbol)
|
if delayed_sold_symbols.contains(&position.symbol) {
|
||||||
|| pending_full_close_symbols.contains(&position.symbol)
|
continue;
|
||||||
{
|
}
|
||||||
|
if interleaved_pending_full_close_symbols.contains(&position.symbol) {
|
||||||
|
exit_symbols.insert(position.symbol.clone());
|
||||||
|
order_intents.push(OrderIntent::TargetValue {
|
||||||
|
symbol: position.symbol.clone(),
|
||||||
|
target_value: 0.0,
|
||||||
|
reason: "pending_full_close_exit".to_string(),
|
||||||
|
});
|
||||||
|
self.forget_position_entry_date(&position.symbol);
|
||||||
|
slot_working_symbols.remove(&position.symbol);
|
||||||
|
let can_sell = defer_execution_risk
|
||||||
|
|| self.can_sell_position(ctx, execution_date, &position.symbol);
|
||||||
|
if can_sell {
|
||||||
|
let close_submitted = self
|
||||||
|
.project_target_zero(
|
||||||
|
ctx,
|
||||||
|
&mut projected,
|
||||||
|
projection_date,
|
||||||
|
&position.symbol,
|
||||||
|
&mut projected_execution_state,
|
||||||
|
)
|
||||||
|
.is_some();
|
||||||
|
if close_submitted {
|
||||||
|
if Self::projected_position_is_flat(&projected, &position.symbol) {
|
||||||
|
same_day_sold_symbols.insert(position.symbol.clone());
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if daily_top_up_active {
|
||||||
|
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,
|
||||||
|
Some(position.symbol.as_str()),
|
||||||
|
&mut projected,
|
||||||
|
&mut projected_execution_state,
|
||||||
|
&mut order_intents,
|
||||||
|
&mut aiquant_available_cash,
|
||||||
|
&mut slot_working_symbols,
|
||||||
|
&mut same_bar_buy_symbols,
|
||||||
|
&pending_full_close_symbols,
|
||||||
|
&same_day_sold_symbols,
|
||||||
|
&exit_symbols,
|
||||||
|
&delayed_sold_symbols,
|
||||||
|
&mut intraday_attempted_buys,
|
||||||
|
&mut daily_top_up_pending_buy_value,
|
||||||
|
debug_daily_top_up,
|
||||||
|
&mut daily_top_up_debug_notes,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if pending_full_close_symbols.contains(&position.symbol) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let projected_position = projected.position(&position.symbol).unwrap_or(position);
|
let projected_position = projected.position(&position.symbol).unwrap_or(position);
|
||||||
|
|||||||
Reference in New Issue
Block a user