Skip to main content

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).