feat(portfolio): 支持显示已清仓历史持仓,增加防乱码 CSV 导出功能

This commit is contained in:
2026-05-02 15:04:56 +08:00
parent 2570144112
commit 3e81c1dc5b
4 changed files with 84 additions and 9 deletions
+11 -5
View File
@@ -173,7 +173,7 @@ function getTodayInShanghai(): Date {
return new Date(utcDate.getTime() + shanghaiOffset);
}
export async function getPortfolioPositions(): Promise<Position[]> {
export async function getPortfolioPositions(includeCleared: boolean = false): Promise<Position[]> {
const allTransactions = await db
.select({
id: transactions.id,
@@ -334,11 +334,17 @@ export async function getPortfolioPositions(): Promise<Position[]> {
const today = getTodayInShanghai();
const result: Position[] = [];
const CLEARED_QUANTITY_TOLERANCE = new Big('1e-8');
for (const [_, holding] of holdings) {
if (holding.quantity.lte(0)) continue;
const hasPosition = holding.quantity.gt(CLEARED_QUANTITY_TOLERANCE);
if (!hasPosition && !includeCleared) {
continue;
}
const cnyValue = calculateCnyValueFromPrice(
holding.quantity,
hasPosition ? holding.quantity : new Big('0'),
holding.latestPrice,
holding.baseCurrency,
rateMap
@@ -442,8 +448,8 @@ export async function getPortfolioPositions(): Promise<Position[]> {
return result;
}
export async function getPortfolioSummary() {
const positions = await getPortfolioPositions();
export async function getPortfolioSummary(includeCleared: boolean = false) {
const positions = await getPortfolioPositions(includeCleared);
// 单一事实来源:复用 getPortfolioPositions 已汇率折算的结果
let totalCnyValue = new Big('0');
+1 -1
View File
@@ -24,7 +24,7 @@ function getTodayInShanghai(): string {
}
export async function recordDailySnapshot() {
const positions = await getPortfolioPositions();
const positions = await getPortfolioPositions(false);
// 统一使用 engine 输出的 marketValueCny / accumulatedPnlCny
const totalValueCny = positions.reduce(