Files
InvestmentsVisualizer/README.md
Dasemu 1dae56415c Initial commit: investment dashboard with contributions panel and forecast chart
React + Vite frontend with a local-JSON-backed API (Vite middleware) for
tracking portfolio holdings, contributions/withdrawals, recurring
contribution plans, and a forecast chart comparing the portfolio's real
value against a same-contributions S&P 500 benchmark.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 19:18:46 +02:00

2.4 KiB

Investment Visualizer

A personal investment dashboard: track contributions, see asset allocation, and compare your portfolio's performance against the S&P 500.

Stack

  • Frontend: React + TypeScript + Vite, charts with Recharts.
  • Backend: a small REST API implemented as a Vite dev-server middleware (server/apiPlugin.ts) backed by local JSON files in data/. No database, no separate process — npm run dev starts both.
  • Data: everything lives under data/*.json. The API layer (src/api/client.ts) is the only place that knows the data lives in local files — swapping it for a real backend later means only changing that file.

Data model (data/)

  • portfolio.json — current holdings snapshot (values, asset class, region, RV/RF allocation).

  • history.json — periodic total-account-value snapshots, used to compute time-weighted return (TWR). Add more snapshots over time for a more accurate performance line.

  • contributions.json — the movements ledger (external contributions/ withdrawals plus internal fund subscriptions/redemptions) and recurring contribution plans (weekly/monthly/etc.) used to project future cash flows.

  • settings.json — portfolio inception date, forecast horizon (years), and the assumed annual return used for the projected part of the chart (historical TWR-derived or a manual assumption).

  • sp500.json — cached daily S&P 500 closes, refreshed with:

    node scripts/fetch-sp500.mjs
    

Performance methodology

  • Portfolio return: simplified chain-linked time-weighted return (TWR) computed from history.json snapshots and external cash flows in contributions.json. Internal fund subscriptions/redemptions net to zero on total account value and don't affect it.
  • S&P 500 line: percentage change of the index since the portfolio's inception date, for an apples-to-apples "who's outperforming whom" comparison against the portfolio's TWR line.
  • Forecast segment: continues the portfolio line past today using either the historical annualized TWR or a manual rate, applied to the current value plus projected future contributions from active recurring plans.
  • 0% baseline: cumulative net contributions (actual + projected) with no investment return at all — the reference line for "what if it just sat in cash."

Development

npm install
npm run dev

This starts Vite (frontend + local JSON API) on http://localhost:5173.