修正AiQuant等权调仓预算
This commit is contained in:
@@ -2884,11 +2884,7 @@ where
|
|||||||
});
|
});
|
||||||
let note = format!(
|
let note = format!(
|
||||||
"cash_dividend_receivable {} share_cash={:.6} quantity={} payable_date={} cash={:.2}",
|
"cash_dividend_receivable {} share_cash={:.6} quantity={} payable_date={} cash={:.2}",
|
||||||
action.symbol,
|
action.symbol, action.share_cash, quantity_after, payable_date, cash_delta
|
||||||
action.share_cash,
|
|
||||||
quantity_after,
|
|
||||||
payable_date,
|
|
||||||
cash_delta
|
|
||||||
);
|
);
|
||||||
notes.push(note.clone());
|
notes.push(note.clone());
|
||||||
report.account_events.push(AccountEvent {
|
report.account_events.push(AccountEvent {
|
||||||
|
|||||||
@@ -7967,14 +7967,8 @@ impl Strategy for PlatformExprStrategy {
|
|||||||
slot_working_symbols.remove(symbol);
|
slot_working_symbols.remove(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
@@ -18398,7 +18392,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn platform_aiquant_periodic_rebalance_uses_cash_divided_by_top_n_buy_budget() {
|
fn platform_aiquant_periodic_rebalance_uses_total_value_equal_weight_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)
|
||||||
@@ -18597,7 +18591,7 @@ mod tests {
|
|||||||
assert!(
|
assert!(
|
||||||
decision.order_intents.iter().all(|intent| match intent {
|
decision.order_intents.iter().all(|intent| match intent {
|
||||||
OrderIntent::Value { value, reason, .. } if reason == "periodic_rebalance_buy" =>
|
OrderIntent::Value { value, reason, .. } if reason == "periodic_rebalance_buy" =>
|
||||||
(*value - 6_500.0).abs() < 1e-6,
|
(*value - 126_500.0).abs() < 1e-6,
|
||||||
_ => true,
|
_ => true,
|
||||||
}),
|
}),
|
||||||
"{:?}",
|
"{:?}",
|
||||||
@@ -18755,7 +18749,7 @@ mod tests {
|
|||||||
reason,
|
reason,
|
||||||
} if symbol == "000002.SZ"
|
} if symbol == "000002.SZ"
|
||||||
&& reason == "periodic_rebalance_buy"
|
&& reason == "periodic_rebalance_buy"
|
||||||
&& (*value - 5_000.0).abs() < 1e-6
|
&& (*value - 10_000.0).abs() < 1e-6
|
||||||
)),
|
)),
|
||||||
"{:?}",
|
"{:?}",
|
||||||
decision.order_intents
|
decision.order_intents
|
||||||
|
|||||||
@@ -410,8 +410,14 @@ fn engine_settles_same_day_dividend_after_split_for_aiquant_semantics() {
|
|||||||
delisted_at: None,
|
delisted_at: None,
|
||||||
status: "active".to_string(),
|
status: "active".to_string(),
|
||||||
}],
|
}],
|
||||||
vec![stock_market_snapshot(buy_date), stock_market_snapshot(ex_date)],
|
vec![
|
||||||
vec![stock_factor_snapshot(buy_date), stock_factor_snapshot(ex_date)],
|
stock_market_snapshot(buy_date),
|
||||||
|
stock_market_snapshot(ex_date),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
stock_factor_snapshot(buy_date),
|
||||||
|
stock_factor_snapshot(ex_date),
|
||||||
|
],
|
||||||
vec![stock_candidate(buy_date), stock_candidate(ex_date)],
|
vec![stock_candidate(buy_date), stock_candidate(ex_date)],
|
||||||
vec![benchmark_snapshot(buy_date), benchmark_snapshot(ex_date)],
|
vec![benchmark_snapshot(buy_date), benchmark_snapshot(ex_date)],
|
||||||
vec![CorporateAction {
|
vec![CorporateAction {
|
||||||
@@ -469,12 +475,16 @@ fn engine_settles_same_day_dividend_after_split_for_aiquant_semantics() {
|
|||||||
assert_eq!(reinvest_fill.quantity, 100);
|
assert_eq!(reinvest_fill.quantity, 100);
|
||||||
assert!((reinvest_fill.price - ((10.0 - 1.05) / 1.2)).abs() < 1e-9);
|
assert!((reinvest_fill.price - ((10.0 - 1.05) / 1.2)).abs() < 1e-9);
|
||||||
|
|
||||||
assert!(result
|
assert!(
|
||||||
.position_events
|
result
|
||||||
.iter()
|
.position_events
|
||||||
.any(|event| event.reason == "stock_split 1.200000" && event.quantity_after == 1_200));
|
.iter()
|
||||||
assert!(result
|
.any(|event| event.reason == "stock_split 1.200000" && event.quantity_after == 1_200)
|
||||||
.account_events
|
);
|
||||||
.iter()
|
assert!(
|
||||||
.any(|event| event.note.contains("cash_receivable_reinvested")));
|
result
|
||||||
|
.account_events
|
||||||
|
.iter()
|
||||||
|
.any(|event| event.note.contains("cash_receivable_reinvested"))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user