NAV / mark-to-market
Firm + per-customer portfolio valuation. Cost vs live market.
Why the ledger DOESN'T post MTM
The ledger stays cost-only. Marking custody to market on the general ledger would:
- Breach the trial-balance invariant unless offset with an unrealized-P&L account (which introduces its own complexity), and
- Post revenue that hasn't crystallized — unrealized gains aren't cash yet.
So MTM is a reporting view, not journal entries. The endpoint fetches live quotes on demand and computes the delta against the ledger's cost basis.
What the report shows
Firm-wide:
- Cash + market value + cost basis + unrealized PnL (% and USD)
- Firm NAV = cash + market value
- Position count across the book
- Top positions (largest by market value)
Per customer:
- Status:
valued/no_link(no ViewTrade linkage) /error(fetch failed) - Cash + market + cost + unrealized PnL
- Cost drift — ledger's cost basis vs ViewTrade's reported cost basis
Cost drift signal
A material cost_drift means one of:
- The ledger has trades ViewTrade doesn't have (very rare).
- ViewTrade has trades the ledger hasn't ingested (common on the forward-only ingest).
- A corporate action (split, merger) adjusted ViewTrade's basis without a matching event on our side.
Surface but don't automate a fix — case-by-case triage.
Per-customer failure isolation
If a live ViewTrade fetch fails for one customer (auth issue on their
account, transient network), that customer shows status=error with the
error message. The firm rollup keeps going — a single bad customer doesn't
break the report.
Where to see it
- Frontend:
/nav(India book). KPI tiles, per-customer table, top positions. - API:
GET /v1/india/nav. - Related: used by Schedule FA for the closing value column.
Follow-ups
- Daily snapshot writer → time-series NAV, true Schedule FA peaks, faster historical queries.
- Sector / concentration breakdowns (top-N by sector).