From 1c3add27ef06b8ba70dd79bab8fa435909e376c7 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Tue, 24 Mar 2026 06:14:27 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=94=B6=E7=9B=8A?= =?UTF-8?q?=E6=9B=B2=E7=BA=BF=E7=BB=9F=E8=AE=A1=E6=95=B0=E6=8D=AE=E4=B8=8E?= =?UTF-8?q?=E7=BB=84=E5=90=88=E8=AF=A6=E6=83=85=E4=B8=8D=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: - 收益曲线接口 totalReturn 直接取净值历史最后一条的 cumulativeReturn - 如果净值历史数据过时,统计信息会与当前持仓数据不一致 修复: - 在 GetNavHistoryAsync 中检查净值历史最后一条是否为今天 - 如果不是,获取当前持仓数据实时计算累计收益率 - 更新 statistics.TotalReturn 为实时值 影响: - 组合详情 historicalChange 和收益曲线 totalReturn 将保持一致 --- AssetManager.Services/PortfolioNavService.cs | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/AssetManager.Services/PortfolioNavService.cs b/AssetManager.Services/PortfolioNavService.cs index 6da1ebc..9baf287 100644 --- a/AssetManager.Services/PortfolioNavService.cs +++ b/AssetManager.Services/PortfolioNavService.cs @@ -77,6 +77,45 @@ public class PortfolioNavService : IPortfolioNavService // 计算统计指标 var returns = navHistory.Select(n => (double)n.DailyReturn).Where(r => r != 0).ToList(); var statistics = CalculateStatistics(returns, navHistory); + + // 如果净值历史的最后一条不是今天,实时计算当前累计收益率 + var lastNavDate = navHistory.Last().NavDate; + if (lastNavDate < DateTime.Today) + { + // 获取当前持仓数据 + var positions = await _db.Queryable() + .Where(p => p.PortfolioId == portfolioId) + .ToListAsync(); + + if (positions.Any()) + { + // 计算当前总市值和总成本 + decimal totalValue = 0; + decimal totalCost = 0; + + foreach (var pos in positions) + { + var currentValue = pos.Shares * pos.CurrentPrice; + var cost = pos.Shares * pos.AverageCost; + + // 汇率转换 + var currentInTarget = await _exchangeRateService.ConvertAmountAsync(currentValue, pos.Currency, portfolio.Currency); + var costInTarget = await _exchangeRateService.ConvertAmountAsync(cost, pos.Currency, portfolio.Currency); + + totalValue += currentInTarget; + totalCost += costInTarget; + } + + // 计算实时累计收益率 + if (totalCost > 0) + { + var realTimeReturn = (double)((totalValue - totalCost) / totalCost * 100); + statistics.TotalReturn = Math.Round(realTimeReturn, 2); + _logger.LogDebug("实时计算累计收益率: {RealTimeReturn}%, 总市值: {TotalValue}, 总成本: {TotalCost}", + realTimeReturn, totalValue, totalCost); + } + } + } return new NavHistoryResponse {