fix: 修复收益曲线统计数据与组合详情不一致的问题

问题:
- 收益曲线接口 totalReturn 直接取净值历史最后一条的 cumulativeReturn
- 如果净值历史数据过时,统计信息会与当前持仓数据不一致

修复:
- 在 GetNavHistoryAsync 中检查净值历史最后一条是否为今天
- 如果不是,获取当前持仓数据实时计算累计收益率
- 更新 statistics.TotalReturn 为实时值

影响:
- 组合详情 historicalChange 和收益曲线 totalReturn 将保持一致
This commit is contained in:
OpenClaw Agent 2026-03-24 06:14:27 +00:00
parent 6b50d7fc50
commit 1c3add27ef

View File

@ -77,6 +77,45 @@ public class PortfolioNavService : IPortfolioNavService
// 计算统计指标 // 计算统计指标
var returns = navHistory.Select(n => (double)n.DailyReturn).Where(r => r != 0).ToList(); var returns = navHistory.Select(n => (double)n.DailyReturn).Where(r => r != 0).ToList();
var statistics = CalculateStatistics(returns, navHistory); var statistics = CalculateStatistics(returns, navHistory);
// 如果净值历史的最后一条不是今天,实时计算当前累计收益率
var lastNavDate = navHistory.Last().NavDate;
if (lastNavDate < DateTime.Today)
{
// 获取当前持仓数据
var positions = await _db.Queryable<PortfolioPosition>()
.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 return new NavHistoryResponse
{ {