From d07bede125a34129d8998fda8399e51e67c87e62 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Wed, 25 Mar 2026 04:12:01 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20BackfillNavHistoryI?= =?UTF-8?q?nternalAsync=20=E4=B8=AD=E5=8D=96=E5=87=BA=E6=88=90=E6=9C=AC?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E7=9A=84=E4=B8=A5=E9=87=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:卖出时用全局累计成本计算减少量,而非该标的的成本 修复:使用该标的的成本(转换为目标币种后)计算减少量 同时添加除零安全检查 --- AssetManager.Services/PortfolioNavService.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/AssetManager.Services/PortfolioNavService.cs b/AssetManager.Services/PortfolioNavService.cs index 94b0682..ad010b6 100644 --- a/AssetManager.Services/PortfolioNavService.cs +++ b/AssetManager.Services/PortfolioNavService.cs @@ -394,6 +394,14 @@ public class PortfolioNavService : IPortfolioNavService if (holdings.ContainsKey(tx.StockCode)) { var existing = holdings[tx.StockCode]; + + // 安全检查:防止除零 + if (existing.shares <= 0) + { + holdings.Remove(tx.StockCode); + continue; + } + decimal soldRatio = tx.Amount / existing.shares; decimal remainingShares = existing.shares - tx.Amount; decimal remainingCost = existing.cost * (1 - (decimal)soldRatio); @@ -407,8 +415,11 @@ public class PortfolioNavService : IPortfolioNavService 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; } }