禁止退出信号股票当日补仓
This commit is contained in:
@@ -8762,23 +8762,9 @@ impl Strategy for PlatformExprStrategy {
|
||||
if !stop_hit && !profit_hit {
|
||||
continue;
|
||||
}
|
||||
let lower_limit_blocked = match self.stock_state_at_time(
|
||||
ctx,
|
||||
projection_date,
|
||||
&position.symbol,
|
||||
Some(self.intraday_execution_start_time()),
|
||||
) {
|
||||
Ok(stock) => stock.lower_limit > 0.0 && stock.last <= stock.lower_limit,
|
||||
Err(BacktestError::Data(crate::data::DataSetError::MissingSnapshot {
|
||||
..
|
||||
})) => false,
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
if !lower_limit_blocked {
|
||||
stop_take_exit_signal_symbols.insert(position.symbol.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.config.aiquant_transaction_cost
|
||||
&& self.config.rotation_enabled
|
||||
@@ -9255,6 +9241,9 @@ impl Strategy for PlatformExprStrategy {
|
||||
let rebalance_value_symbols = rebalance_working_symbols.clone();
|
||||
let mut rebalance_pending_buy_value = 0.0_f64;
|
||||
for symbol in stock_list.iter().take(selection_limit) {
|
||||
if exit_symbols.contains(symbol) {
|
||||
continue;
|
||||
}
|
||||
let decision_stock = self.stock_state_with_factor_date(
|
||||
ctx,
|
||||
decision_date,
|
||||
@@ -17290,7 +17279,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn platform_aiquant_allows_target_adjust_when_stop_loss_sell_is_lower_limit_blocked() {
|
||||
fn platform_aiquant_blocks_target_increase_when_stop_loss_sell_is_lower_limit_blocked() {
|
||||
let prev_date = d(2025, 1, 10);
|
||||
let date = d(2025, 1, 13);
|
||||
let symbol = "603269.SH";
|
||||
@@ -17420,7 +17409,7 @@ mod tests {
|
||||
reason,
|
||||
} if intent_symbol == symbol && *target_value == 0.0 && reason == "stop_loss_exit"
|
||||
)));
|
||||
assert!(decision.order_intents.iter().any(|intent| matches!(
|
||||
assert!(!decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::Shares {
|
||||
symbol: intent_symbol,
|
||||
@@ -21189,7 +21178,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn platform_weak_market_adjusts_before_lower_limit_blocked_stop_loss() {
|
||||
fn platform_weak_market_skips_target_increase_before_lower_limit_blocked_stop_loss() {
|
||||
let prev_date = d(2025, 2, 2);
|
||||
let date = d(2025, 2, 3);
|
||||
let symbols = ["000001.SZ", "000002.SZ"];
|
||||
@@ -21315,24 +21304,8 @@ mod tests {
|
||||
|
||||
let decision = strategy.on_day(&ctx).expect("platform decision");
|
||||
|
||||
let stop_loss_index = decision
|
||||
.order_intents
|
||||
.iter()
|
||||
.position(|intent| {
|
||||
matches!(
|
||||
intent,
|
||||
OrderIntent::TargetValue {
|
||||
symbol,
|
||||
target_value,
|
||||
reason,
|
||||
} if symbol == "000001.SZ" && *target_value == 0.0 && reason == "stop_loss_exit"
|
||||
)
|
||||
})
|
||||
.expect("stop-loss exit");
|
||||
assert!(
|
||||
decision.order_intents[..stop_loss_index]
|
||||
.iter()
|
||||
.any(|intent| matches!(
|
||||
!decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::Shares {
|
||||
symbol,
|
||||
@@ -21345,6 +21318,14 @@ mod tests {
|
||||
"{:?}",
|
||||
decision.order_intents
|
||||
);
|
||||
assert!(decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::TargetValue {
|
||||
symbol,
|
||||
target_value,
|
||||
reason,
|
||||
} if symbol == "000001.SZ" && *target_value == 0.0 && reason == "stop_loss_exit"
|
||||
)));
|
||||
assert!(decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::Value { symbol, reason, .. }
|
||||
@@ -21353,7 +21334,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn platform_weak_market_adjusts_before_intraday_stop_loss_sell_blocked() {
|
||||
fn platform_weak_market_skips_target_increase_before_intraday_stop_loss_sell_blocked() {
|
||||
let prev_date = d(2025, 2, 2);
|
||||
let date = d(2025, 2, 3);
|
||||
let symbols = ["000001.SZ", "000002.SZ"];
|
||||
@@ -21497,24 +21478,8 @@ mod tests {
|
||||
|
||||
let decision = strategy.on_day(&ctx).expect("platform decision");
|
||||
|
||||
let stop_loss_index = decision
|
||||
.order_intents
|
||||
.iter()
|
||||
.position(|intent| {
|
||||
matches!(
|
||||
intent,
|
||||
OrderIntent::TargetValue {
|
||||
symbol,
|
||||
target_value,
|
||||
reason,
|
||||
} if symbol == "000001.SZ" && *target_value == 0.0 && reason == "stop_loss_exit"
|
||||
)
|
||||
})
|
||||
.expect("stop-loss exit");
|
||||
assert!(
|
||||
decision.order_intents[..stop_loss_index]
|
||||
.iter()
|
||||
.any(|intent| matches!(
|
||||
!decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::Shares {
|
||||
symbol,
|
||||
@@ -21527,6 +21492,14 @@ mod tests {
|
||||
"{:?}",
|
||||
decision.order_intents
|
||||
);
|
||||
assert!(decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::TargetValue {
|
||||
symbol,
|
||||
target_value,
|
||||
reason,
|
||||
} if symbol == "000001.SZ" && *target_value == 0.0 && reason == "stop_loss_exit"
|
||||
)));
|
||||
assert!(decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::Value { symbol, reason, .. }
|
||||
@@ -24915,7 +24888,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn platform_periodic_rebalance_can_rebuy_released_unsellable_stop_loss_symbol() {
|
||||
fn platform_periodic_rebalance_skips_unsellable_stop_loss_symbol() {
|
||||
let prev_date = d(2025, 5, 13);
|
||||
let date = d(2025, 5, 14);
|
||||
let symbols = ["000001.SZ", "000002.SZ", "000003.SZ"];
|
||||
@@ -25078,7 +25051,7 @@ mod tests {
|
||||
decision.order_intents
|
||||
);
|
||||
assert!(
|
||||
decision.order_intents.iter().any(|intent| matches!(
|
||||
!decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::Value { symbol, reason, .. }
|
||||
if symbol == "000001.SZ" && reason == "periodic_rebalance_buy"
|
||||
@@ -25086,6 +25059,15 @@ mod tests {
|
||||
"{:?}",
|
||||
decision.order_intents
|
||||
);
|
||||
assert!(
|
||||
decision.order_intents.iter().any(|intent| matches!(
|
||||
intent,
|
||||
OrderIntent::Value { symbol, reason, .. }
|
||||
if symbol == "000003.SZ" && reason == "periodic_rebalance_buy"
|
||||
)),
|
||||
"{:?}",
|
||||
decision.order_intents
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user