fix: 首页组合收益率实时计算
This commit is contained in:
parent
c7712e57bb
commit
71aa7211d6
@ -176,30 +176,60 @@ public class PortfolioService : IPortfolioService
|
|||||||
|
|
||||||
foreach (var p in portfolios)
|
foreach (var p in portfolios)
|
||||||
{
|
{
|
||||||
// 获取持仓数量
|
// 获取该组合的所有持仓
|
||||||
var positionCount = _db.Queryable<Position>()
|
var positions = _db.Queryable<Position>()
|
||||||
.Where(pos => pos.PortfolioId == p.Id)
|
.Where(pos => pos.PortfolioId == p.Id)
|
||||||
.Count();
|
.ToList();
|
||||||
|
|
||||||
// 获取今日盈亏(从净值历史)
|
int positionCount = positions.Count;
|
||||||
var todayNav = _db.Queryable<PortfolioNavHistory>()
|
|
||||||
.Where(n => n.PortfolioId == p.Id && n.NavDate == DateTime.Today)
|
|
||||||
.First();
|
|
||||||
|
|
||||||
double todayProfit = 0;
|
// 实时计算当前市值和总成本
|
||||||
if (todayNav != null && p.TotalValue > 0)
|
decimal totalValue = 0;
|
||||||
|
decimal totalCost = 0;
|
||||||
|
decimal todayProfit = 0;
|
||||||
|
string portfolioCurrency = p.Currency ?? "CNY";
|
||||||
|
|
||||||
|
foreach (var pos in positions)
|
||||||
{
|
{
|
||||||
// 今日盈亏 = 今日市值 - 昨日市值
|
if (pos.StockCode == null || pos.Currency == null)
|
||||||
var yesterdayNav = _db.Queryable<PortfolioNavHistory>()
|
|
||||||
.Where(n => n.PortfolioId == p.Id && n.NavDate < DateTime.Today)
|
|
||||||
.OrderByDescending(n => n.NavDate)
|
|
||||||
.First();
|
|
||||||
|
|
||||||
if (yesterdayNav != null)
|
|
||||||
{
|
{
|
||||||
todayProfit = (double)(todayNav.TotalValue - yesterdayNav.TotalValue);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取实时价格
|
||||||
|
decimal currentPrice = pos.AvgPrice;
|
||||||
|
decimal previousClose = pos.AvgPrice;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var priceResponse = _marketDataService.GetPriceAsync(pos.StockCode, pos.AssetType ?? "Stock").GetAwaiter().GetResult();
|
||||||
|
if (priceResponse.Price > 0)
|
||||||
|
{
|
||||||
|
currentPrice = priceResponse.Price;
|
||||||
|
previousClose = priceResponse.PreviousClose > 0 ? priceResponse.PreviousClose : currentPrice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "获取标的 {StockCode} 实时价格失败,使用成本价", pos.StockCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
decimal positionValue = pos.Shares * currentPrice;
|
||||||
|
decimal positionCost = pos.Shares * pos.AvgPrice;
|
||||||
|
decimal positionTodayProfit = previousClose > 0 ? pos.Shares * (currentPrice - previousClose) : 0;
|
||||||
|
|
||||||
|
// 汇率转换到组合本位币
|
||||||
|
var valueInTarget = _exchangeRateService.ConvertAmountAsync(positionValue, pos.Currency, portfolioCurrency).GetAwaiter().GetResult();
|
||||||
|
var costInTarget = _exchangeRateService.ConvertAmountAsync(positionCost, pos.Currency, portfolioCurrency).GetAwaiter().GetResult();
|
||||||
|
var todayProfitInTarget = _exchangeRateService.ConvertAmountAsync(positionTodayProfit, pos.Currency, portfolioCurrency).GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
totalValue += valueInTarget;
|
||||||
|
totalCost += costInTarget;
|
||||||
|
todayProfit += todayProfitInTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算收益率
|
||||||
|
double returnRate = totalCost > 0 ? (double)((totalValue - totalCost) / totalCost * 100) : 0;
|
||||||
|
returnRate = Math.Round(returnRate, 2);
|
||||||
|
|
||||||
result.Add(new PortfolioListItem
|
result.Add(new PortfolioListItem
|
||||||
{
|
{
|
||||||
@ -211,11 +241,11 @@ public class PortfolioService : IPortfolioService
|
|||||||
IconChar = p.Name?.Substring(0, 1).ToUpper() ?? "P",
|
IconChar = p.Name?.Substring(0, 1).ToUpper() ?? "P",
|
||||||
IconBgClass = "bg-blue-100",
|
IconBgClass = "bg-blue-100",
|
||||||
IconTextClass = "text-blue-700",
|
IconTextClass = "text-blue-700",
|
||||||
Value = (double)p.TotalValue,
|
Value = (double)totalValue,
|
||||||
Currency = p.Currency,
|
Currency = p.Currency,
|
||||||
ReturnRate = (double)p.ReturnRate,
|
ReturnRate = returnRate,
|
||||||
ReturnType = p.ReturnRate >= 0 ? "positive" : "negative",
|
ReturnType = returnRate >= 0 ? "positive" : "negative",
|
||||||
TodayProfit = todayProfit,
|
TodayProfit = (double)todayProfit,
|
||||||
TodayProfitCurrency = p.Currency
|
TodayProfitCurrency = p.Currency
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user