修正延迟卖出后止盈止损补仓槽位
This commit is contained in:
@@ -8197,7 +8197,6 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
let mut intraday_attempted_buys = BTreeSet::<String>::new();
|
let mut intraday_attempted_buys = BTreeSet::<String>::new();
|
||||||
let mut same_bar_buy_symbols = BTreeSet::<String>::new();
|
let mut same_bar_buy_symbols = BTreeSet::<String>::new();
|
||||||
let mut delayed_sold_symbols = BTreeSet::<String>::new();
|
let mut delayed_sold_symbols = BTreeSet::<String>::new();
|
||||||
let mut delayed_open_exit_submitted = false;
|
|
||||||
let mut unresolved_stop_loss_symbols = BTreeSet::<String>::new();
|
let mut unresolved_stop_loss_symbols = BTreeSet::<String>::new();
|
||||||
let mut pending_risk_level_forced_exit_symbols = BTreeSet::<String>::new();
|
let mut pending_risk_level_forced_exit_symbols = BTreeSet::<String>::new();
|
||||||
let delayed_limit_exit_time = self
|
let delayed_limit_exit_time = self
|
||||||
@@ -8301,7 +8300,6 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
end_time: Some(delayed_limit_exit_time),
|
end_time: Some(delayed_limit_exit_time),
|
||||||
reason: "delayed_limit_open_sell".to_string(),
|
reason: "delayed_limit_open_sell".to_string(),
|
||||||
});
|
});
|
||||||
delayed_open_exit_submitted = true;
|
|
||||||
delayed_sold_symbols.insert(symbol.clone());
|
delayed_sold_symbols.insert(symbol.clone());
|
||||||
self.forget_position_entry_date(&symbol);
|
self.forget_position_entry_date(&symbol);
|
||||||
let projected_sold = if ctx
|
let projected_sold = if ctx
|
||||||
@@ -8407,10 +8405,7 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
let mut daily_top_up_pending_buy_value = 0.0_f64;
|
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 slot_blocking_symbols = BTreeSet::<String>::new();
|
let mut slot_blocking_symbols = BTreeSet::<String>::new();
|
||||||
let should_block_released_slots_after_top_up =
|
let should_block_partial_exit_residual_slot = trading_ratio < 1.0;
|
||||||
delayed_open_exit_submitted && !self.config.release_slot_on_exit_signal;
|
|
||||||
let should_block_partial_exit_residual_slot =
|
|
||||||
should_block_released_slots_after_top_up || trading_ratio < 1.0;
|
|
||||||
let interleaved_pending_full_close_symbols = BTreeSet::<String>::new();
|
let 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| {
|
||||||
@@ -8870,8 +8865,7 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
target_value: 0.0,
|
target_value: 0.0,
|
||||||
reason: "stop_loss_exit".to_string(),
|
reason: "stop_loss_exit".to_string(),
|
||||||
});
|
});
|
||||||
if daily_top_up_pending_buy_value > 0.0 && should_block_released_slots_after_top_up
|
if daily_top_up_pending_buy_value > 0.0 && trading_ratio < 1.0 {
|
||||||
{
|
|
||||||
slot_blocking_symbols.insert(position.symbol.clone());
|
slot_blocking_symbols.insert(position.symbol.clone());
|
||||||
}
|
}
|
||||||
self.forget_position_entry_date(&position.symbol);
|
self.forget_position_entry_date(&position.symbol);
|
||||||
@@ -23324,7 +23318,7 @@ mod tests {
|
|||||||
cfg.stop_loss_expr = "false".to_string();
|
cfg.stop_loss_expr = "false".to_string();
|
||||||
cfg.take_profit_expr = "1.1".to_string();
|
cfg.take_profit_expr = "1.1".to_string();
|
||||||
cfg.daily_top_up_enabled = true;
|
cfg.daily_top_up_enabled = true;
|
||||||
cfg.release_slot_on_exit_signal = true;
|
cfg.release_slot_on_exit_signal = false;
|
||||||
cfg.aiquant_transaction_cost = true;
|
cfg.aiquant_transaction_cost = true;
|
||||||
cfg.intraday_execution_time = Some(NaiveTime::from_hms_opt(10, 18, 0).unwrap());
|
cfg.intraday_execution_time = Some(NaiveTime::from_hms_opt(10, 18, 0).unwrap());
|
||||||
cfg.delayed_limit_open_exit_enabled = true;
|
cfg.delayed_limit_open_exit_enabled = true;
|
||||||
|
|||||||
@@ -1793,12 +1793,6 @@ pub fn platform_expr_config_from_spec(
|
|||||||
{
|
{
|
||||||
cfg.retry_empty_rebalance = true;
|
cfg.retry_empty_rebalance = true;
|
||||||
}
|
}
|
||||||
if trading
|
|
||||||
.and_then(|item| item.release_slot_on_exit_signal)
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
cfg.release_slot_on_exit_signal = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let trade_times = spec_trade_times(spec);
|
let trade_times = spec_trade_times(spec);
|
||||||
if let Some(main_trade_time) = trade_times.last().copied() {
|
if let Some(main_trade_time) = trade_times.last().copied() {
|
||||||
@@ -3093,51 +3087,6 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn aiquant_compatibility_defaults_release_slot_on_exit_signal() {
|
|
||||||
let spec = serde_json::json!({
|
|
||||||
"engineConfig": {
|
|
||||||
"profileName": "cn_a_microcap_v1",
|
|
||||||
"compatibilityProfile": "aiquant_rqalpha"
|
|
||||||
},
|
|
||||||
"runtimeExpressions": {
|
|
||||||
"trading": {
|
|
||||||
"dailyTopUp": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let cfg = platform_expr_config_from_value("", "", &spec).expect("config");
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
cfg.release_slot_on_exit_signal,
|
|
||||||
"AiQuant compatibility must release the strategy working slot when an exit signal is emitted"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn aiquant_compatibility_respects_explicit_release_slot_false() {
|
|
||||||
let spec = serde_json::json!({
|
|
||||||
"engineConfig": {
|
|
||||||
"profileName": "cn_a_microcap_v1",
|
|
||||||
"compatibilityProfile": "aiquant_rqalpha"
|
|
||||||
},
|
|
||||||
"runtimeExpressions": {
|
|
||||||
"trading": {
|
|
||||||
"dailyTopUp": true,
|
|
||||||
"releaseSlotOnExitSignal": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let cfg = platform_expr_config_from_value("", "", &spec).expect("config");
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!cfg.release_slot_on_exit_signal,
|
|
||||||
"explicit FIDC semantics must override the AiQuant compatibility default"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parses_explicit_delayed_limit_open_exit() {
|
fn parses_explicit_delayed_limit_open_exit() {
|
||||||
let spec = serde_json::json!({
|
let spec = serde_json::json!({
|
||||||
|
|||||||
Reference in New Issue
Block a user