Stock Analysis Overview
Eight per-symbol fundamental endpoints + one global feed, computed on read from financial reports, dividend events, and live prices
The stock-analysis module exposes eight per-symbol fundamentals endpoints under /api/nepse/companies/{symbol}/fundamentals/* plus one global cross-symbol feed at /api/nepse/upcoming-book-closes. Every payload is computed on read from the latest reported quarter, the dividend/rights/AGM/merger calendars, and the live price row; Redis absorbs the load via per-feature TTLs ranging from 5 minutes to 1 hour.
All endpoints are public (rate-limited under the rl30 group at 30 req/min/IP), HTTP GET only, and case-insensitive on symbol. No JWT.
What this module owns
- Snapshot — top-of-page header card: sector, listing date, paid-up capital, LTP, market cap, book value per share, EPS-TTM, P/E, dividend yield.
- Statements — quarterly / annual income statement and balance sheet rows by canonical line item. Cash flow short-circuits to
available:falseuntil upstream exposes it. - Ratios — four tabs (
valuation,profitability,solvency,growth) computed off the latest reported quarter. Sector benchmarks and historical sparklines return null/empty until multi-quarter coverage exists. - Dividends — historical dividend table, total-return-index chart series, and inline upcoming book closures.
- Ownership — two-tier promoter/public donut (auto-upgrades to four-tier when Phase A CSV ingest is configured), board of directors + management team, plus auditor and top shareholders when available.
- Peers — side-by-side ratio comparison + cohort-normalized radar polygon. Cross-sector peers are silently filtered.
- Announcements — unified timeline of dividends, rights, AGMs, mergers, and quarterly results, filtered by chip and date window.
- Fair value — two-method estimate (Graham + Earnings-based) with average and delta-vs-LTP. No verdict label — FE renders the under/fair/over indicator from
deltaPercent. - Upcoming book closes (global) — cross-symbol calendar feed, owned by the
dividendspackage.
The MetricFloat64 envelope
Every computed surface returns a uniform shape so the frontend can render a value, a dash, or a tooltip without per-field branching:
type MetricFloat64 = {
value?: number; // omitted when status !== "valid"
source: 'mdp' | 'computed' | 'manual_swp';
status: 'valid' | 'upstream_missing' | 'insufficient_history' | 'negative_input' | 'insufficient_cohort';
};valid— number is usable; render it.upstream_missing— required input not available (e.g. MDP hasn't filled the column yet).insufficient_history— feature needs multi-quarter history that doesn't yet exist (growth tab under v4.5).negative_input— input was non-positive in a context where positive is required (e.g. P/E on negative EPS).insufficient_cohort— peer cohort below the floor (fair value sector P/E needs ≥3 peers, focal excluded).
source distinguishes raw MDP-ingested values (mdp), values derived by service-layer math (computed), and operator-uploaded overrides (manual_swp).
Read this next
- Architecture — package layout, bundle wiring, and the compute-on-read pipeline.
- Snapshot — the top-of-page header card.
- Statements — financial statements with canonical row rendering.
- Ratios — per-tab ratio engine (also reused by Peers).
- Reference — every endpoint, DTO, and cache key on one page.