fix(ledger): 补全汇率折算乘数,修复跨币种直接相加导致的盈亏总额失真

This commit is contained in:
2026-05-01 05:20:30 +08:00
parent a3b5563db2
commit 52a94a9ffa
3 changed files with 35 additions and 2 deletions
+19
View File
@@ -24,8 +24,12 @@ interface Position {
realizedPnlCny: string;
avgCost: string;
dilutedCost: string;
dilutedCostCny: string;
floatingPnl: string;
floatingPnlCny: string;
accumulatedPnl: string;
accumulatedPnlCny: string;
marketValueCny: string;
holdingDays: number;
exchange: string;
accumulatedDividendsCny: string;
@@ -326,6 +330,17 @@ export async function getPortfolioPositions(): Promise<Position[]> {
holding.latestPrice
);
// 获取资产对人民币的汇率
const fxRate = new Big(
getRate(rateMap, holding.baseCurrency, 'CNY') || '1'
);
// 将引擎返回的原生币种金额折算为 CNY
const marketValueCny = new Big(metrics.marketValue).times(fxRate).toString();
const floatingPnlCny = new Big(metrics.floatingPnl).times(fxRate).toString();
const accumulatedPnlCny = new Big(metrics.accumulatedPnl).times(fxRate).toString();
const dilutedCostCny = new Big(metrics.dilutedCost).times(fxRate).toString();
const holdingNative = new Big(metrics.holdings);
const avgCostNative = new Big(metrics.averageCost);
const dilutedCostNative = new Big(metrics.dilutedCost);
@@ -370,8 +385,12 @@ export async function getPortfolioPositions(): Promise<Position[]> {
realizedPnlCny: holding.realizedPnlCny.toString(),
avgCost: metrics.averageCost,
dilutedCost: metrics.dilutedCost,
dilutedCostCny,
floatingPnl: metrics.floatingPnl,
floatingPnlCny,
accumulatedPnl: metrics.accumulatedPnl,
accumulatedPnlCny,
marketValueCny,
holdingDays,
exchange: holding.exchange,
accumulatedDividendsCny: holding.accumulatedDividendsCny.toString(),
+10 -2
View File
@@ -333,8 +333,16 @@ export async function reconstructPortfolioHistory() {
const metrics = calculateAssetMetrics(assetTxs, cnyPrice);
totalValueCny = totalValueCny.plus(metrics.marketValue);
totalCostCny = totalCostCny.plus(metrics.totalInvested);
// 获取资产对人民币的汇率
const assetFxRate = new Big(getRate(baseCurrency, 'CNY') || '1');
// marketValue 已使用 CNY 价格计算,直接取用
// totalInvested 基于原始币种价格,需乘以汇率折算为 CNY
const posValueCny = new Big(metrics.marketValue);
const posCostCny = new Big(metrics.totalInvested).times(assetFxRate);
totalValueCny = totalValueCny.plus(posValueCny);
totalCostCny = totalCostCny.plus(posCostCny);
}
const existing = await db