baseline
A variant of Personal Finance & Investment Tracker.
View the interactive variant page →
Personal Finance & Investment Tracker
Part of the worlds-biggest-software-project initiative.
An open, AI-native platform that unifies net worth, investment performance, and tax optimisation in a single view.
Personal Finance & Investment Tracker is a candidate open-source project for individuals whose assets are spread across bank accounts, brokerages, retirement funds, property, cryptocurrency, and private investments. It targets the gap between budgeting-only and investment-only tools by providing a holistic dashboard with AI-driven insights across the full financial picture.
Why Personal Finance & Investment Tracker?
- Most consumer tools focus on either budgeting (YNAB, Quicken Simplifi) or investments (Empower, PortfolioPilot), forcing users to manually reconcile across multiple apps.
- Comprehensive trackers like Kubera ($249–$2,499/yr) and full AI recommendation tiers like PortfolioPilot Platinum ($99/mo) are expensive, while affordable options lack advanced portfolio analytics.
- No mainstream product offers a holistic tax planning timeline that visualises Roth conversions, tax-loss harvesting windows, estimated tax payments, and capital gains realisation across the calendar year.
- Cross-account tax-loss harvesting for DIY investors is unaddressed: Wealthfront only harvests assets it manages directly.
- Privacy-conscious users have no local-first or self-hosted option among incumbent SaaS products.
- Non-US asset support (PSD2, UK, Australian, Asian account types) is poorly served by predominantly US-centric incumbents.
Key Features
Net Worth & Aggregation
- Multi-account aggregation via Plaid or MX covering bank, brokerage, credit card, and loan accounts
- Net worth dashboard with daily balance updates and historical trend chart
- Multi-currency support with automatic FX conversion
- CSV import fallback for institutions without API coverage
Investment Analytics
- Holdings list, total portfolio value, asset allocation breakdown, and daily gain/loss
- Time-weighted return and benchmark comparison against indices such as S&P 500 and 60/40
- Fee drag analysis across all linked investment accounts
- Cost basis tracking (FIFO, LIFO, specific identification) with realised vs unrealised gains
Tax Optimisation
- Tax event tracking, including realised gains/losses, estimated tax liability, and wash sale flagging
- Tax-loss harvesting opportunity identification across externally held accounts
- Account contribution optimisation across 401k, IRA, HSA, and taxable accounts
- Roth conversion and capital gains planning tools
Budgeting & Cashflow
- Transaction auto-categorisation with manual correction and category learning
- Budget and spending plan creation with monthly tracking
- Recurring bill and subscription detection
- Cashflow forecasting
Planning & AI Insights
- Retirement projections using Monte Carlo probability scoring
- Goal feasibility analysis and scenario modelling (e.g. retire at 60, pay off mortgage early)
- AI financial Q&A using the user's actual portfolio data
- Proactive alerts for portfolio drift, tax events, fee drags, and unusual spending
Alternative Assets & Estate (backlog)
- Real estate (Zillow or manual), vehicles (VIN), private equity (Carta), precious metals, and crypto/DeFi balances
- Beneficiary and estate document tracking alongside asset records
- Document vault with OCR for statements and tax returns
AI-Native Advantage
AI is applied where incumbents underuse it: continuous tax opportunity identification across all accounts, natural-language Q&A grounded in the user's real portfolio, proactive anomaly detection without user-defined rules, and goal feasibility analysis with actionable recommendations. JP Morgan research cited by PortfolioPilot indicates continuous tax optimisation can deliver an additional 1.94% yearly return — a margin that compounds significantly over decades. Document parsing via LLMs can extract data from uploaded tax returns and brokerage statements, removing manual entry friction.
Tech Stack & Deployment
The project anticipates a cloud-hosted default with a privacy-first local or self-hosted deployment option for users unwilling to share financial data with third parties. Account aggregation will use open banking APIs (Plaid, MX, TrueLayer, FDX-compliant providers) with CSV import fallback. The portfolio analytics engine handles time-weighted return, IRR, Sharpe ratio, beta, and asset allocation. Security expectations include bank-level encryption, read-only access tokens, and SOC 2 alignment. AI features are framed as "insights" and "education" with disclaimers to avoid crossing into regulated investment advice.
Market Context
The AI-powered personal finance management market was valued at $1.37 billion in 2024 and is projected to reach $2.36 billion by 2032 at a 7% CAGR (Financial Deep Dive). Incumbent pricing ranges from $35.88/yr (Quicken Simplifi) and $99.99/yr (Monarch Core) to $249–$2,499/yr (Kubera) and $99/mo (PortfolioPilot Platinum). Primary buyers are millennials and high-income professionals managing complex, multi-asset portfolios.
Project Status
This project is in the research and specification phase.
Contributions, feedback, and domain expertise are welcome.
Contributing
We welcome contributions from developers, domain experts, and potential users. See CONTRIBUTING.md for guidelines.
Important: All contributions must be your own original work or clearly attributed open-source material with a compatible licence. Copyright infringement and licence violations will not be tolerated and will result in immediate removal of the offending contribution. If you are unsure whether a piece of code, text, or other material is safe to contribute, open an issue and ask before submitting.
Architecture
- Backend: Python 3.12 FastAPI (
src/pftracker/), SQLAlchemy 2.0 async + Alembic, PostgreSQL 16, Celery + Redis. domain/: pure, I/O-free financial/tax math (Money, TWR/XIRR/Sharpe/beta, allocation, fee drag, FIFO/LIFO/HIFO/specific-lot cost basis, §1091 wash-sale, federal+state tax estimate, TLH ranking, seeded Monte Carlo, recurring & insight detection) — every function golden-value tested.integrations/: every vendor (Plaid, Polygon, CoinGecko, OpenFIGI, Anthropic) sits behind aProtocol; no vendor name appears indomain/orservices/(enforced by a guard test).- Frontend: Next.js 15 App Router (
web/) on port 3000; owns every browser-facing auth URL (/signin,/api/auth/signin|callback|signout|local) and proxies/api/v1/*to FastAPI. - Auth: a plain OIDC (authorization code + PKCE) client driven entirely by the provider's discovery document (
src/pftracker/auth/oidc.py), so hosted login, broker SSO or a different IdP are configuration rather than code. Users are keyed on the stablesub. A visitor already signed in with the destination's provider is recognised on their first page load (prompt=none, attempted once — never a loop). Offline self-host installs fall back to local credentials. See docs/login-troubleshooting.md. - MCP: an opt-in, read-only, audited assistant surface (
src/pftracker/mcp/).
Configuration
Connections are built from discrete platform-injected variables — there is no DATABASE_URL / REDIS_URL anywhere.
| Group | Variables |
|---|---|
| Database | DATABASE_HOST DATABASE_PORT DATABASE_NAME DATABASE_USER DATABASE_PASSWORD DATABASE_SSL |
| Redis | REDIS_HOST REDIS_PORT REDIS_PASSWORD REDIS_NAMESPACE REDIS_TLS |
| Auth (OIDC) | AUTH_ISSUER (tenant-scoped, e.g. https://hap.wbsp.ai/t/wbsp) AUTH_CLIENT_ID AUTH_CLIENT_SECRET APP_URL (the callback is derived from it) AUTH_REDIRECT_URI (local override) AUTH_SILENT_SSO AUTH_INTERNAL_ISSUER (split-horizon, in-cluster only) |
| App crypto/session | APP_MASTER_KEY / ENCRYPTION_KEY (base64 32 bytes; stable — it wraps every per-user data key) SESSION_SECRET / AUTH_SECRET |
| Providers (optional) | PLAID_* POLYGON_API_KEY COINGECKO_API_KEY OPENFIGI_API_KEY ANTHROPIC_API_KEY |
Secrets are declared by reference only — real values live in git-ignored .env.<destination> files; committed .env.*.example templates document each destination. Copy .env.local.example → .env.local to start.
Run locally
uv sync # backend deps + toolchain
cp .env.local.example .env.local # fill AUTH_*, leave provider keys empty
docker compose up -d postgres redis # PG 54356, Redis 63356
uv run alembic upgrade head # apply schema
uv run alembic downgrade base && uv run alembic upgrade head # up+down (Constitution VI)
docker compose up -d api worker beat # API on 30356
cd web && npm install && npm run dev # frontend on 3000
Seed demo data
scripts/seed_demo_data.py loads a realistic, deterministic demo household so
every screen (net worth, accounts, transactions, budgets, investments/holdings,
tax, goals, insights) looks populated for demos and screen recordings. It is
idempotent — the demo user has a stable id and each run clears-then-reseeds
their rows, so re-running never duplicates or crashes. Money stays integer minor
units via the Money value object; home currency USD, FIFO cost basis.
It reuses the app's Settings loader and models, and connects from the discrete
platform-injected DATABASE_* vars (never a DATABASE_URL). Pick the target
database with --destination; the schema must already be migrated
(uv run alembic upgrade head).
uv run python scripts/seed_demo_data.py --destination dev # local Postgres (54356)
uv run python scripts/seed_demo_data.py --destination compose # docker compose stack (host-side)
uv run python scripts/seed_demo_data.py --destination standalone # self-host overlay
uv run python scripts/seed_demo_data.py --destination aws # WBSP/managed Postgres (DATABASE_* injected, or .env.aws)
dev/compose fall back to .env.local; standalone/aws require explicit
DATABASE_* (injected at runtime, or .env.<destination>) and refuse the
localhost defaults. Flags: --check (resolve + build the plan with no DB
connection), --dry-run (build against the live schema, then roll back),
--list-destinations. Seeds ~683 rows: 2 users + household, 11 accounts across
all types, 15 categories, 11 securities, 12 holdings, 25 tax lots, 6 tax events
(incl. a wash sale + LT/ST gains and dividends), ~550 transactions over ~20
months, 8 budgets, 3 goals, 5 insight alerts, 2 documents and 21 monthly
net-worth snapshots. Demo login (self-host): demo@pftracker.app / demo1234.
Quality gates (per phase Definition of Done)
uv run pytest # unit + integration (golden values)
uv run ruff check . && uv run ruff format --check .
uv run mypy --strict src
uv run bandit -r src -ll # no high/medium
uv run pytest tests/integration/test_migrations.py # Alembic up+down on fresh PG
docker compose build
Self-hosted / offline
docker compose -f docker-compose.yml -f docker-compose.selfhost.yml up -d
With no provider keys and egress blocked the product is fully usable via local credentials, manual accounts, and CSV/OFX import; aggregation and AI surfaces degrade gracefully (aggregation returns 503, the AI coach uses a deterministic tool-grounded fallback).
WBSP deployment
wbsp.yaml declares a single component (database.enabled/redis.enabled: true, s3.enabled: false), a gating release: alembic upgrade head, and secrets by reference. Compose services carry wbsp.tenant/wbsp.app/wbsp.managed-by labels; .gitignore ignores .env* and un-ignores !.env.*.example.
Licence
Licence to be determined. See discussion for context.