SPEC 015 Composition Report - rafaelfqueiroz/allmywallet GitHub Wiki

SPEC-015 — Composition Report

Status Draft
PRD source F5.4 (FR-5.21–5.24)
Depends on SPEC-009, SPEC-011
Milestone M5

Description

The report that answers what am I actually holding, and is it balanced?

It is the simplest of the four and the most used: a share-of-total view plus a sortable table of every holding with its value, quantity, average price, current price and unrealized gain. Because SPEC-011 supplies the grouping dimension, this single report covers what other trackers split into several — by asset class, by wallet, by ticker, by sector, by institution.

It also carries the one place the product comes closest to opinion: a concentration flag when a single asset exceeds a configurable share. That flag is informational and must stay that way — AllMyWallet gives no investment advice.

Business rules

ID Rule
BR-015-01 Composition is presented by the selected grouping (SPEC-011): asset class, wallet, individual asset, sector, or institution.
BR-015-02 Two presentations: a share-of-total visualization, and a sortable table with value, quantity, average price, current price and unrealized gain per row.
BR-015-03 Sector data applies to stocks and FIIs where available; holdings with no sector appear in "Not classified" (SPEC-011, BR-011-10), never dropped.
BR-015-04 Composition drift over time — how allocation across the selected grouping shifted during the period.
BR-015-05 Concentration flags when a single asset exceeds a user-configurable share of the scope (default 20%).
BR-015-06 Concentration flags are informational only and explicitly not advice. No wording may suggest an action to take.
BR-015-07 Shares are computed on current market value, not on cost basis.
BR-015-08 Unrealized gain per row = current value − (quantity × average cost) (SPEC-009, BR-009-04).
BR-015-09 Estimated values (accrued fixed income) are marked distinctly (SPEC-009, BR-009-11).
BR-015-10 Shares sum to 100% for the scope, and the value total equals the endpoint of the Portfolio Value report for the same scope and date (SPEC-013, BR-013-12).
BR-015-11 At wallet scope, quantities and values reflect allocated quantities, not full positions (SPEC-010).
BR-015-12 Grouping by wallet at portfolio scope includes Unassigned (SPEC-011, BR-011-09).
BR-015-13 Current value uses the latest delayed quote with its timestamp displayed (SPEC-008, BR-008-04).

Acceptance Criteria

  • Composition renders for all five grouping dimensions.
  • Shares sum to 100% for every grouping.
  • The value total equals the Portfolio Value report endpoint for the same scope and date.
  • The table sorts by every column, ascending and descending.
  • Value, quantity, average price, current price and unrealized gain are correct per row.
  • Unrealized gain reconciles to value minus quantity × average cost.
  • Holdings without sector data appear in "Not classified" and totals still reconcile.
  • Drift over time shows allocation shifts across the period for the selected grouping.
  • A holding exceeding the configured threshold is flagged; changing the threshold in user settings changes which holdings flag.
  • Flag wording is informational and suggests no action — verified by review, not just by test.
  • Accrued fixed income is visually distinguished from observed prices.
  • At wallet scope, a partially-allocated asset shows the allocated quantity, not the full position.
  • Grouping by wallet at portfolio scope includes Unassigned and sums to the portfolio.
  • The quote timestamp and delay tier are displayed.
  • An empty scope renders an empty state.

Out of Scope

  • Target allocation and drift against a target — moved to SPEC-017 at M7, which answers PRD Q6. Rebalancing suggestions remain out of scope everywhere: SPEC-017 supplies arithmetic against targets the user set and never a recommendation. BR-015-06 stands unchanged.
  • Risk metrics: correlation, diversification scores, beta.
  • Fundamental data beyond sector: P/E, dividend yield history, market cap.
  • Geographic or currency exposure breakdown, including look-through for BDRs.
  • Look-through into FII or ETF underlying holdings.
  • Any buy, sell or rebalance recommendation.
  • Sourcing sector classification data (PRD Q5 — open question whether free coverage suffices).
  • Historical composition reconstruction before the earliest imported transaction.

Decision Logs

# Decision Alternatives considered Rationale
DL-015-01 One report driven by SPEC-011's grouping, not several composition reports. Separate reports for asset class, sector, wallet The underlying computation is identical and only the grouping key changes. Separate reports would drift apart and multiply the surface where totals can stop reconciling.
DL-015-02 Shares computed on market value, not cost. Share of invested capital Composition answers "what is my money exposed to now". A position that tripled represents three times the exposure it did at purchase, and a cost-based share would understate exactly the concentration the user needs to see.
DL-015-03 Concentration flag is informational, with a user-configurable threshold. No flag; a fixed threshold; actionable rebalancing advice A flag is genuinely useful — concentration builds silently as winners run. Advice would make the product an unlicensed advisor (PRD risk R7). A user-set threshold makes it a tool the user configures rather than a judgement the product imposes. Superseded in part by SPEC-017 (M7), which permits user-set targets: the advice risk is mitigated by requiring every threshold to originate with the user, rather than by omitting the feature. The concentration flag itself remains informational and unchanged.
DL-015-04 "Not classified" for missing sector rather than exclusion. Drop holdings with no sector from the sector view Fixed income has no sector, and it can be a large share of a Brazilian portfolio. Dropping it would make the sector view disagree with every other view of the same scope, with no visible explanation.
DL-015-05 Wallet scope shows allocated quantities, not full positions. Show the full position when any part is allocated Showing the full position would make wallet composition wrong for every split holding and would double-count across wallets — a 60/40 split would appear as 100% in both.
DL-015-06 Cross-report equality with Portfolio Value asserted. Independent computation per report Consistent with SPEC-013 DL-013-06 and SPEC-014 DL-014-07. Two reports disagreeing about the portfolio total is the most trust-destroying defect available, and an automated assertion catches it in CI.