All ideas

portfolio_overview API: partial sells return sold-parcel cost base (web UI is correct)

After using the api via mcp (kimi k3) we got some numbers that were definitely not correct and didn't match with on-screen and cgt reports which we cross-checked against the api response. What went wrong? Any holding with a sell event gets scrambled cost-basis fields in the API; holdings with buys only are correct. performance.cost\base and performance.unrealised\gain, unrealised\gain\pct by extension. While you're there also review the totalReturn block - these might be messed up as well. kimi's theory: For a holding with multiple buy parcels followed by a partial sell, the portfolio\_overview API response reports the sold parcels' cost base as the holding's cost base and computes unrealised P&L from it. The web UI holdings page shows correct figures for the same holding, so this appears to be an API-layer bug only. \[I asked kimi to do a hypothetical to save me embarrassment\] Simple hypothetical that should reproduce it: Buy 100 sh @ $30 = $3,000 (parcel 1) Buy 100 sh @ $20 = $2,000 (parcel 2) Sell 100 sh @ $10 — FIFO consumes parcel 1 Current price: $10 Correct figures (what the web UI shows): Realised on sale: 100 × ($10-$30) = -$2,000 Remaining cost base: $2,000 (parcel 2) Unrealised: 100 × $10 - $2,000 = -$1,000 Lifetime capital result: -$3,000 What the API returns instead: cost\_base: $3,000 (the sold parcel's cost) unrealised\_gain: market value $1,000 - $3,000 = -$2,000 The realised -$2,000 appears nowhere; remaining-position cost base ($2,000) appears nowhere. All three figures are scrambled. Where is it happening? Platform: Web / API Browser or device: Chrome on macOS; also reproducible via the public API (portfolio\_overview endpoint / MCP) Steps to reproduce: Create a holding with 2+ buy parcels at different prices Add a partial sell (fewer shares than held), FIFO tax strategy Compare the API portfolio\_overview response for that holding against the web UI holdings page and CGT report for the same holding Expected result: API cost\_base matches the web UI: remaining open parcels' cost (total cost minus FIFO-allocated sold cost). Realised result on closed parcels reported separately. Actual result: API cost\_base equals the sold parcels' FIFO cost (matches the CGT report's sold-parcel figure to the cent). Unrealised P&L is computed as remaining market value minus the sold parcels' cost, understating the true unrealised loss. The realised loss on the sale is absent from the API performance data. Web UI and CGT report for the same holding are both correct. A fully-sold holding in the same portfolio reports correctly via the API, so this may be specific to partial sells with an open remainder. Screenshot, screen recording, or error message: