Shop It Docs
Portfolio Module

Portfolio Overview

Authenticated CRUD for user portfolios with a unified transactions ledger; all derived numbers are computed at read time

The portfolio module exposes JWT-authenticated REST endpoints under /api/v1/nepse/portfolios/*. A portfolio is a header row plus a flat list of transactions; every dashboard number — current units, WACC, P&L, day P&L, distribution pies, valuation series — is derived in Go from those transactions at read time. There is no FIFO lot table, no holdings projection, no recompute-on-write pipeline.

Every endpoint is JWT-authenticated. The customer ID is taken from the token; never from the request body. No customer ever sees another customer's portfolio.

What this module owns

  • Portfolio CRUD — create, list, get, update (name, description, isDefault), soft-delete.
  • Transactions ledger — one unified CRUD surface for all 8 event types: BUY, SELL, IPO, FPO, RIGHTS, AUCTION, DIVIDEND, BONUS.
  • Read-time derivations in views/:
    • BuildState — replays transactions chronologically into a per-company state (current units, WACC cost basis, sold units, realized P&L, dividend total).
    • DayPnL — splits today's gain across overnight units, today-buy lots, and today-sell legs.
    • BuildValuation — walks the same event stream against historical close prices to produce a [{d, v, cb}] time-series for charts.
    • BuildDistributionbyCompany and bySector pies, valued at LTP × current units.
  • Broker analysis — today's accumulation/distribution/mixed buckets per portfolio company (standalone endpoint, not bundled with detail).

What this module does NOT do on the write path

The product spec is explicit: the user enters every number; the backend stores and shows.

  • No broker tier table lookup, no SEBON % derivation, no DP fee defaults.
  • No CGT computation from holding-period rates.
  • No settlement-date lookup.
  • No FIFO replay on insert/update/delete.
  • No total_amount_computed / cgt_computed / cost_basis_at_sell audit columns.

The backend does validate that the user-supplied fields are internally consistent within ±0.01 NPR (gross = qty × rate, netAmount agrees with amount ± fees ± cgt, CGT within [0, gain × rate(term)]) and rejects oversells via a single SELECT SUM(...) aggregate.

Read this next

  • Architecture — package layout and request lifecycle.
  • Portfolio CRUD — create / list / get / update / delete.
  • Transactions — the one ledger that replaces the old trades + dividends + corporate-actions + holdings tables.
  • Reference — every endpoint, DTO, and cache key on one page.