允许弱市涨停持仓部分减仓

This commit is contained in:
boris
2026-06-21 02:19:59 +08:00
parent 9d41971d3f
commit 8495bf6ad8
+34 -11
View File
@@ -2319,6 +2319,27 @@ impl PlatformExprStrategy {
} }
} }
fn mark_highlimit_for_delayed_exit_at_time(
&mut self,
ctx: &StrategyContext<'_>,
date: NaiveDate,
symbol: &str,
execution_time: NaiveTime,
) -> Result<(), BacktestError> {
if !self.config.delayed_limit_open_exit_enabled
|| self.pending_highlimit_holdings.contains(symbol)
{
return Ok(());
}
if matches!(
self.stock_is_at_upper_limit_at_time(ctx, date, symbol, execution_time)?,
Some(true)
) {
self.pending_highlimit_holdings.insert(symbol.to_string());
}
Ok(())
}
fn stock_state_with_factor_date_and_time( fn stock_state_with_factor_date_and_time(
&self, &self,
ctx: &StrategyContext<'_>, ctx: &StrategyContext<'_>,
@@ -7463,14 +7484,12 @@ impl Strategy for PlatformExprStrategy {
if position.quantity == 0 || delayed_sold_symbols.contains(&position.symbol) { if position.quantity == 0 || delayed_sold_symbols.contains(&position.symbol) {
continue; continue;
} }
if self.regular_sell_should_wait_due_to_highlimit( self.mark_highlimit_for_delayed_exit_at_time(
ctx, ctx,
execution_date, execution_date,
&position.symbol, &position.symbol,
self.intraday_execution_start_time(), self.intraday_execution_start_time(),
)? { )?;
continue;
}
if pending_full_close_symbols.contains(&position.symbol) { if pending_full_close_symbols.contains(&position.symbol) {
continue; continue;
} }
@@ -11706,7 +11725,7 @@ mod tests {
} }
#[test] #[test]
fn platform_aiquant_weak_market_skips_pending_highlimit_target_adjust_until_open() { fn platform_aiquant_weak_market_allows_pending_highlimit_partial_target_adjust() {
let prev_date = d(2023, 5, 4); let prev_date = d(2023, 5, 4);
let date = d(2023, 5, 5); let date = d(2023, 5, 5);
let symbol = "600148.SH"; let symbol = "600148.SH";
@@ -11845,13 +11864,15 @@ mod tests {
let decision = strategy.on_day(&ctx).expect("platform decision"); let decision = strategy.on_day(&ctx).expect("platform decision");
assert!( assert!(
!decision.order_intents.iter().any(|intent| matches!( decision.order_intents.iter().any(|intent| matches!(
intent, intent,
OrderIntent::Shares { OrderIntent::Shares {
symbol: intent_symbol, symbol: intent_symbol,
quantity,
reason, reason,
.. } if intent_symbol == symbol
} if intent_symbol == symbol && reason == "daily_position_target_adjust" && reason == "daily_position_target_adjust"
&& *quantity < 0
)), )),
"{:?}", "{:?}",
decision.order_intents decision.order_intents
@@ -11999,13 +12020,15 @@ mod tests {
let decision = strategy.on_day(&ctx).expect("platform decision"); let decision = strategy.on_day(&ctx).expect("platform decision");
assert!( assert!(
!decision.order_intents.iter().any(|intent| matches!( decision.order_intents.iter().any(|intent| matches!(
intent, intent,
OrderIntent::Shares { OrderIntent::Shares {
symbol: intent_symbol, symbol: intent_symbol,
quantity,
reason, reason,
.. } if intent_symbol == symbol
} if intent_symbol == symbol && reason == "daily_position_target_adjust" && reason == "daily_position_target_adjust"
&& *quantity < 0
)), )),
"{:?}", "{:?}",
decision.order_intents decision.order_intents