Skip to content

Calculate consistent holding values, cost basis, and portfolio returns #131

Closed

Description

@31b4

Goal

Make every current portfolio and trade-preview number traceable to the same investment accounting rules.

Current behavior

The client derives quantity from trades and approximates gain using current value minus net traded amounts. MCP uses stored quantity and has legacy USD trade assumptions. Prototype average cost averages all buys, which is insufficient for a defined remaining-cost method after sales and rebuys.

Desired behavior

Implement the settled accounting contract as shared pure calculations where appropriate, with service adapters for API, client and independent MCP. Inputs include opening units/known basis, ordered signed trades, execution/cash currencies, explicit fees, manual cost and valuations, quotes and valid FX.

Calculate current native/converted value, remaining weighted-average cost and average price, net invested separately, realized/unrealized/total gain and clearly defined percentages. Portfolio filters and net-worth exclusions retain their distinct documented meanings. Preserve zero/negative values and signs. Unknown cost does not prevent a known market value, but does make affected gain metrics unavailable; do not substitute zero cost.

Provide preview calculations for position after a trade, buy average cost and estimated sale gain using the same rules as saved data. Define native daily price change and converted portfolio daily change separately, with manual/stale coverage explicit and cash flows excluded from market gain. Range calculations are consumed by the history issue using this contract. Corporate-action/dividend gaps are reported according to the rules issue, without unrequested automated feeds or tax claims.

Acceptance criteria

  • Synthetic golden examples for partial sale/rebuy, full liquidation, openings, fees, manual gains and cross-currency trades produce the agreed values across consumers.
  • API/client/MCP agree on current units and native values; their documented aggregate exclusion and incomplete-FX policies remain intentional and visible.
  • Net invested is not mislabeled cost basis; negative/zero denominators, unknown cost and missing prices/FX never produce misleading zero gain or infinite percentages.
  • Trade preview equals the recomputed post-save position for the same inputs, with no duplicate conversion or cash/quantity rounding.
  • Return labels/tooltips document the method and coverage, including what is omitted from the today figure.

References or visuals

Parent: #123. Milestone: Investment Page Rework.

Design: user-supplied Investments Redesign.dc.html, sections 1a (desktop), 1b (mobile), and the holdings-table screenshot in the Codex conversation. Its generated prices, fixed FX, dates and sample holdings are visual fixtures, not calculation rules or migration data.

Branch from the fetched epic/123-investment-rework tip, use this sub-issue number in the branch name, and target its PR to that epic. Final integration into main requires completion of the epic and explicit user approval.

Implementation dependencies: #128, #129, #130. Native blocked-by relationships record these prerequisites.

Accounting contract from #126

Review checkpoint: MR #136; version 1 contract. Apply the reviewed contract when this prerequisite is integrated; this note does not start this child or approve a merge.

Use the metric dictionary and worked examples. Maintain remaining moving weighted-average basis separately from net external cash. Reporting basis uses acquisition-date conversion of exact cash, never current-FX translation of the final native gain. Imported known remaining basis does not prove lifetime cash or realized history. Holding Return amount is total gain; its percentage is the covered daily-linked Estimated return, not gain/net-invested. Scope Investments to active holdings regardless of net-worth exclusion; Dashboard/MCP net-worth totals honor that exclusion. The trace found Dashboard currently adds the unfiltered investment value: include its exclusion fix and regression coverage. Keep MCP warned partial totals and per-metric null coverage explicit.

Implementation review checkpoint

Ready MR #142 targets epic/123-investment-rework; it adds derived accounting and nonmutating trade previews without a migration. Shared production-engine golden tests, API/client/MCP parity, scopes and covered Market Today calculations are implemented. Full holding/portfolio daily-linked percentages remain explicitly unavailable until #132 supplies daily history; full overview/detail layouts remain #133/#134.

Local verification: client 391, API 163, MCP 51, Worker/D1 184 (two existing skips), all types/build/lint and 26 deployment tests. Final affected integration suites: 32 passing. October 12 disposable-export metrics reads preserve every financial row/row ID/source revision and unknown legacy cost/cash; integrity checks pass, original unchanged and private copy deleted. Synthetic desktop/mobile, dark/light, privacy, sale-preview and failed-refresh checks passed. No production access or remote migrations.

All 11 CI checks passed on final commit 9ab803c, including Worker/D1 integration and Node 26 client tests. Stop at this MR for user review before #132; no merge or deployment is implied.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:analyticsFinancial calculations and analyticsarea:investmentsInvestments and portfolio UIarea:mcpFinance MCP tools and review workflowenhancementNew feature or request

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions