修复补减仓时对原持仓重复计入交易滑点

This commit is contained in:
boris
2026-09-19 21:29:52 +08:00
parent 175b319d47
commit 4d731f9c14
3 changed files with 29 additions and 4 deletions
+12 -2
View File
@@ -1588,7 +1588,17 @@ pub fn build_stock_pool_target_plan_with_fee_model(
if sizing_price <= Decimal::ZERO {
return Err(format!("{symbol} execution sizing price is invalid"));
}
let raw_target = (target_value / sizing_price).floor();
// Existing shares are marked at the observed market price. Only the
// new buy leg pays its executable/slippage price; repricing the whole
// position would charge fictitious slippage and miss a board lot.
let current_value = current_quantity * quote.last_price;
let raw_target = if target_value >= current_value {
current_quantity + ((target_value - current_value) / sizing_price).floor()
} else {
// Sale slippage changes proceeds, not the marked shares we must
// remove to reach a market-value target.
(target_value / quote.last_price).floor()
};
let (step, minimum_buy) = order_quantity_rules(quote)?;
let mut target_quantity = current_quantity;
let mut delta = Decimal::ZERO;
@@ -1911,7 +1921,7 @@ pub fn build_stock_pool_target_plan_with_fee_model(
let cost = |quantity: Decimal| {
Ok(quantity * price + fee_for(&row.symbol, OrderSide::Buy, quantity * price)?)
};
let own_budget = (row.target_value - row.current_quantity * price).max(Decimal::ZERO);
let own_budget = (row.target_value - row.current_quantity * quote.last_price).max(Decimal::ZERO);
let allocation_quantity = max_affordable_buy_quantity_with_cost(
own_budget,
row.delta_quantity,