修正AiQuant固定现金调仓预算
This commit is contained in:
@@ -7970,7 +7970,11 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
if !self.config.aiquant_transaction_cost {
|
if !self.config.aiquant_transaction_cost {
|
||||||
aiquant_available_cash = projected.cash();
|
aiquant_available_cash = projected.cash();
|
||||||
}
|
}
|
||||||
let fixed_buy_cash = aiquant_total_value * trading_ratio / selection_limit as f64;
|
let fixed_buy_cash = if self.config.aiquant_transaction_cost {
|
||||||
|
aiquant_available_cash * trading_ratio / selection_limit as f64
|
||||||
|
} else {
|
||||||
|
aiquant_total_value * trading_ratio / selection_limit as f64
|
||||||
|
};
|
||||||
let target_budget = aiquant_total_value * trading_ratio;
|
let target_budget = aiquant_total_value * trading_ratio;
|
||||||
let mut rebalance_working_symbols = slot_working_symbols.clone();
|
let mut rebalance_working_symbols = slot_working_symbols.clone();
|
||||||
if self.config.release_slot_on_exit_signal {
|
if self.config.release_slot_on_exit_signal {
|
||||||
@@ -8052,6 +8056,9 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
let target_cash = if self.config.aiquant_transaction_cost {
|
||||||
|
fixed_buy_cash * stock_scale
|
||||||
|
} else {
|
||||||
let slot_buy_cash = self.remaining_buy_cash_per_slot(
|
let slot_buy_cash = self.remaining_buy_cash_per_slot(
|
||||||
ctx,
|
ctx,
|
||||||
&projected,
|
&projected,
|
||||||
@@ -8062,7 +8069,8 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
&rebalance_value_symbols,
|
&rebalance_value_symbols,
|
||||||
rebalance_pending_buy_value,
|
rebalance_pending_buy_value,
|
||||||
);
|
);
|
||||||
let target_cash = slot_buy_cash * stock_scale;
|
slot_buy_cash * stock_scale
|
||||||
|
};
|
||||||
let buy_cash = target_cash.min(aiquant_available_cash);
|
let buy_cash = target_cash.min(aiquant_available_cash);
|
||||||
if buy_cash <= 0.0 {
|
if buy_cash <= 0.0 {
|
||||||
break;
|
break;
|
||||||
@@ -18383,14 +18391,14 @@ mod tests {
|
|||||||
.count();
|
.count();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
aiquant_periodic_buys, 1,
|
aiquant_periodic_buys, 2,
|
||||||
"{:?}",
|
"{:?}",
|
||||||
aiquant_decision.order_intents
|
aiquant_decision.order_intents
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn platform_aiquant_periodic_rebalance_does_not_reuse_same_callback_sell_cash() {
|
fn platform_aiquant_periodic_rebalance_uses_cash_divided_by_top_n_buy_budget() {
|
||||||
let prev_date = d(2025, 5, 13);
|
let prev_date = d(2025, 5, 13);
|
||||||
let date = d(2025, 5, 14);
|
let date = d(2025, 5, 14);
|
||||||
let retained_symbols = (1..=17)
|
let retained_symbols = (1..=17)
|
||||||
@@ -18580,13 +18588,18 @@ mod tests {
|
|||||||
"{:?}",
|
"{:?}",
|
||||||
decision.order_intents
|
decision.order_intents
|
||||||
);
|
);
|
||||||
assert_eq!(periodic_buys, 2, "{:?}", decision.order_intents);
|
assert_eq!(
|
||||||
|
periodic_buys,
|
||||||
|
new_symbols.len(),
|
||||||
|
"{:?}",
|
||||||
|
decision.order_intents
|
||||||
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!decision.order_intents.iter().any(|intent| matches!(
|
decision.order_intents.iter().all(|intent| match intent {
|
||||||
intent,
|
OrderIntent::Value { value, reason, .. } if reason == "periodic_rebalance_buy" =>
|
||||||
OrderIntent::Value { symbol, reason, .. }
|
(*value - 6_500.0).abs() < 1e-6,
|
||||||
if symbol == &new_symbols[2] && reason == "periodic_rebalance_buy"
|
_ => true,
|
||||||
)),
|
}),
|
||||||
"{:?}",
|
"{:?}",
|
||||||
decision.order_intents
|
decision.order_intents
|
||||||
);
|
);
|
||||||
@@ -18742,7 +18755,7 @@ mod tests {
|
|||||||
reason,
|
reason,
|
||||||
} if symbol == "000002.SZ"
|
} if symbol == "000002.SZ"
|
||||||
&& reason == "periodic_rebalance_buy"
|
&& reason == "periodic_rebalance_buy"
|
||||||
&& (*value - 10_000.0).abs() < 1e-6
|
&& (*value - 5_000.0).abs() < 1e-6
|
||||||
)),
|
)),
|
||||||
"{:?}",
|
"{:?}",
|
||||||
decision.order_intents
|
decision.order_intents
|
||||||
|
|||||||
Reference in New Issue
Block a user