fix: 修复 BackfillNavHistoryInternalAsync 中卖出成本计算的严重bug

问题:卖出时用全局累计成本计算减少量,而非该标的的成本
修复:使用该标的的成本(转换为目标币种后)计算减少量
同时添加除零安全检查
This commit is contained in:
OpenClaw Agent 2026-03-25 04:12:01 +00:00
parent 82264ecc25
commit d07bede125

View File

@ -394,6 +394,14 @@ public class PortfolioNavService : IPortfolioNavService
if (holdings.ContainsKey(tx.StockCode)) if (holdings.ContainsKey(tx.StockCode))
{ {
var existing = holdings[tx.StockCode]; var existing = holdings[tx.StockCode];
// 安全检查:防止除零
if (existing.shares <= 0)
{
holdings.Remove(tx.StockCode);
continue;
}
decimal soldRatio = tx.Amount / existing.shares; decimal soldRatio = tx.Amount / existing.shares;
decimal remainingShares = existing.shares - tx.Amount; decimal remainingShares = existing.shares - tx.Amount;
decimal remainingCost = existing.cost * (1 - (decimal)soldRatio); decimal remainingCost = existing.cost * (1 - (decimal)soldRatio);
@ -407,8 +415,11 @@ public class PortfolioNavService : IPortfolioNavService
holdings[tx.StockCode] = (remainingShares, remainingCost, existing.currency, existing.assetType); holdings[tx.StockCode] = (remainingShares, remainingCost, existing.currency, existing.assetType);
} }
// 按比例减少累计投入成本(关键修复:不再用卖出金额) // 按比例减少累计投入成本(修复:使用该标的的成本,而非全局累计成本)
decimal costToReduce = cumulativeCost * (decimal)soldRatio; // 先将该标的的成本转换为目标币种
decimal existingCostInTarget = await _exchangeRateService.ConvertAmountAsync(
existing.cost, existing.currency ?? targetCurrency, targetCurrency);
decimal costToReduce = existingCostInTarget * (decimal)soldRatio;
cumulativeCost -= costToReduce; cumulativeCost -= costToReduce;
} }
} }