fix(api): 修复时光机引擎本金未折算汇率 bug,重建历史财务快照
This commit is contained in:
@@ -32,13 +32,8 @@ export async function recordDailySnapshot() {
|
||||
new Big(0)
|
||||
).toString();
|
||||
|
||||
// 推导真实投入本金 CNY = 市值 - 累计盈亏
|
||||
const totalCostCny = positions.reduce(
|
||||
(sum, pos) => {
|
||||
const mv = new Big(pos.marketValueCny || '0');
|
||||
const ap = new Big(pos.accumulatedPnlCny || '0');
|
||||
return sum.plus(mv.minus(ap));
|
||||
},
|
||||
(sum, pos) => sum.plus(new Big(pos.totalCostCny || '0')),
|
||||
new Big(0)
|
||||
).toString();
|
||||
|
||||
@@ -357,6 +352,7 @@ export async function reconstructPortfolioHistory() {
|
||||
quantity: transactions.quantity,
|
||||
price: transactions.price,
|
||||
fee: transactions.fee,
|
||||
exchangeRate: transactions.exchangeRate,
|
||||
})
|
||||
.from(transactions)
|
||||
.where(lte(transactions.executedAt, currentDate))
|
||||
@@ -399,7 +395,30 @@ export async function reconstructPortfolioHistory() {
|
||||
const metrics = calculateAssetMetrics(assetTxs, priceStrForMetrics);
|
||||
|
||||
const posValueCny = new Big(metrics.marketValue).times(snapshotFxRate);
|
||||
const posCostCny = new Big(metrics.accumulatedCost || '0');
|
||||
|
||||
// 使用交易时的真实汇率计算法币本金,而非直接用 metrics.accumulatedCost
|
||||
let calculatedFiatCost = new Big(0);
|
||||
const rawTxs = historicalTx.filter(t => t.assetId === assetId && (t.txType === 'BUY' || t.txType === 'SELL' || t.txType === 'DIVIDEND'));
|
||||
let currentQty = new Big(0);
|
||||
for (const tx of rawTxs) {
|
||||
const qty = new Big(tx.quantity);
|
||||
const fx = new Big(tx.exchangeRate || '1');
|
||||
const price = new Big(tx.price);
|
||||
|
||||
if (tx.txType === 'BUY') {
|
||||
currentQty = currentQty.plus(qty);
|
||||
calculatedFiatCost = calculatedFiatCost.plus(qty.times(price).times(fx));
|
||||
} else if (tx.txType === 'SELL') {
|
||||
let avgFiatCostPerUnit = new Big(0);
|
||||
if (currentQty.gt(0)) {
|
||||
avgFiatCostPerUnit = calculatedFiatCost.div(currentQty);
|
||||
}
|
||||
calculatedFiatCost = calculatedFiatCost.minus(avgFiatCostPerUnit.times(qty));
|
||||
currentQty = currentQty.minus(qty);
|
||||
}
|
||||
}
|
||||
|
||||
const posCostCny = calculatedFiatCost.gt(0) ? calculatedFiatCost : new Big(0);
|
||||
|
||||
totalValueCny = totalValueCny.plus(posValueCny);
|
||||
totalCostCny = totalCostCny.plus(posCostCny);
|
||||
|
||||
Reference in New Issue
Block a user