#7880·ghostfolio

[BUG] 按成本基础计算持仓价值,而不是按市值计算: marketPrice: 1, investment: 0, hasErrors: 所有符号均为 true,尽管 MarketData 正确

作者: jkaware55创建于 2026年9月15日更新于 2026年9月15日

Bug description Every holding is valued at its transaction unitPrice (cost basis) rather than its current market price. The portfolio total is therefore wrong for any position whose price has moved. The market data itself is fine — MarketData contains correct, current prices for every symbol, gathered without errors. The portfolio calculator does not use them. It flags every symbol as errored and falls back to cost basis. Minimal reproduction below: a fresh official Docker image, one user, three BUY activities. Steps to reproduce Start a fresh instance from ghostfolio/ghostfolio:latest with an empty PostgreSQL database and a new Redis (no other configuration; default DATA_SOURCES, base currency USD). POST /api/v1/user to create a user, then authenticate via POST /api/v1/auth/anonymous. Import three activities via POST /api/v1/import: json { "activities": [ {"symbol":"AAPL","type":"BUY","quantity":100,"unitPrice":100.00,"fee":0,"currency":"USD","dataSource":"YAHOO","date":"2026-09-04T00:00:00.000Z"}, {"symbol":"VOO","type":"BUY","quantity":100,"unitPrice":100.00,"fee":0,"currency":"USD","dataSource":"YAHOO","date":"2026-09-04T00:00:00.000Z"}, {"symbol":"FXAIX","type":"BUY","quantity":100,"unitPrice":100.00,"fee":0,"currency":"USD","dataSource":"YAHOO","date":"2026-09-04T00:00:00.000Z"} ] } Wait for data gathering to complete (or POST /api/v1/admin/gather). GET /api/v1/portfolio/details?range=max. Expected behaviour Each holding valued at quantity × market price: Symbol Qty Market price Expected value AAPL 100 333.08 33,308.00 VOO 100 708.01 70,801.00 FXAIX 100 268.67 26,867.00 Total 130,976.00 Actual behaviour AAPL value=10,000.00 marketPrice=1 quantity=100 investment=0 VOO value=10,000.00 marketPrice=1 quantity=100 investment=0 FXAIX value=10,000.00 marketPrice=1 quantity=100 investment=0 TOTAL: $30,000.00 summary.currentValueInBaseCurrency: 0 summary.totalInvestment: 0 $30,000 is exactly 300 shares × $100.00 — the cost basis. The cached portfolio snapshot contains: json { "hasErrors": true, "errors": [ {"dataSource":"YAHOO","symbol":"AAPL"}, {"dataSource":"YAHOO","symbol":"VOO"}, {"dataSource":"YAHOO","symbol":"FXAIX"} ], "totalInvestment": 0 } Why this is not a data-provider problem The prices are in the database and are correct. Immediately after the run above: sql SELECT symbol, count(*), max(date)::date, round(max("marketPrice")::numeric,2) FROM "MarketData" GROUP BY symbol ORDER BY symbol; symbol | count | max | px ---------+-------+------------+-------- AAPL | 11 | 2026-09-14 | 333.08 FXAIX | 11 | 2026-09-14 | 268.67 VOO | 11 | 2026-09-14 | 708.01 Data gathering completes and logs no errors. MarketData.symbol/dataSource joins cleanly to SymbolProfile.symbol/dataSource for all three. yahoo-finance2 works from inside the same container, including the batch call the snapshot path uses: js const yf = new

内容来源: ghostfolio/ghostfolio