A local-first research terminal that combines SEC filings, deterministic financial ratios, valuation scorecards, portfolio risk, and an explainable UI.
Quickstart · Features · Architecture · Commands · License
Asterion is not financial advice. It does not issue buy/sell recommendations. It is a research and risk-analysis tool. All outputs are for informational and educational purposes only. Markets are noisy, reflexive, and adversarial — Asterion estimates probability, expected value, uncertainty, and downside risk. It does not promise prediction. Do your own research; consult a licensed professional before investing.
Deterministic math is the skeleton. A local LLM is the analyst, not the oracle. No fake predictions, no invented numbers, no LLM-calculated ratios, no buy/sell signals without confidence, risk, and a thesis-invalidation condition. Everything runs on your machine: Postgres + Ollama, no data sent to a vendor by default.
- Local-first portfolio research cockpit — your holdings never leave your machine.
- SEC / XBRL ingestion — rate-limited, backoff, full provenance on every fact.
- Deterministic financial ratios — reproducible, no LLM arithmetic.
- Forensic scores — accrual, dilution, reflexivity, thesis-fragility signals.
- Reverse DCF — solves for the growth the market is already pricing in.
- Dynamic WACC — CAPM with FRED risk-free rate + provider/sector beta (honest fallbacks).
- FCF / capex coverage — cash-flow durability checks from SEC facts.
- Portfolio concentration risk — single-name and theme exposure policy warnings.
- Daily contribution analysis — what moved the book and why.
- Market data provider abstraction — Finnhub / FMP / FRED, swappable, optional.
- Opportunity Scanner — ranks the ingested universe by a transparent composite (value / quality / safety / change) with confidence + evidence links. Two calibration layers: a cross-sectional screen score (percentile vs the current scan, drives the ranking) and an absolute grade A–E (anchored to a pinned reference distribution, so it's stable across scans). A screen, never a buy/sell call.
- IPO / private-company mode — verifies an S-1 against SEC EDGAR, parses the
filing, and produces a research-only IPO scorecard (valuation, scenario model
for negative-FCF names, 7-category risk engine). Never invents numbers, never
recommends. Used to analyze e.g. SpaceX (
SPCX). - Beginner / Pro UI — progressive disclosure for two audiences.
- One-command local launcher —
make start, no Docker required.
make scan # rank the current universe (writes a snapshot)
make calibrate # pin the absolute-calibration reference distribution
make expand ARGS='--starter' # add a curated cross-sector set (SEC ingest + score)
make expand ARGS='--sector semiconductors' # or a sector presetThe scanner reads the deterministic valuation scorecards and ranks them — it
never recommends buying or selling, and confidence drops when inputs are
missing. expand_universe.py is idempotent and resumable (existing scorecards
are skipped unless --force); a name it can't ingest or score is reported and
skipped, never faked.
Each name carries two reads: a cross-sectional screen score (its percentile
vs the current scan — this drives the ranking) and an absolute grade A–E.
The grade is anchored to a pinned reference distribution
(reports/calibration_profile.json, built by make calibrate), so it means the
same thing across scans even as the live universe changes — unlike the
cross-sectional score, which floats with whoever's in the scan. Re-run
make calibrate after a material universe expansion to re-pin. (Bands are
anchored to the observed score distribution; fitting them to forward outcomes is
future work — see roadmap.)
make ipo # verify SpaceX's S-1 on SEC EDGAR + build scorecard
# or, directly:
cd backend && .venv/bin/python ../scripts/analyze_ipo_candidate.py SPACEX
.venv/bin/python ../scripts/analyze_ipo_candidate.py SPACEX --unverified-news-modeIt checks the official source first (never assumes IPO news is real), parses the
filing for verified figures (with provenance), and writes
reports/spacex_source_verification.{md,json} +
reports/SPACEX_IPO_scorecard.{md,json}. When free cash flow can't be confirmed
positive it uses a labeled-speculative scenario model, not a normal reverse
DCF. View it in the UI at /ipo/SPACEX. Research only — no buy/sell.
A generated company valuation scorecard (public-company data, no personal info):
examples/reports/NVDA_valuation_scorecard.md.
Demo data only — no personal holdings, no broker data, no secrets.
The ingested universe ranked by a transparent composite (value / quality / safety / change), cross-sectionally calibrated so each score is a percentile vs the universe. Confidence + evidence links on every row. A screen, never a buy/sell call.
Verifies the S-1 against SEC EDGAR first, parses it for figures with provenance, and builds a research-only scorecard: valuation, a labeled-speculative scenario model (FCF can't be confirmed positive), and a 7-category IPO risk engine. Missing data is flagged, never invented. No buy/sell.
Accrual, dilution, reflexivity, and thesis-fragility signals on a ticker, each with confidence and provenance. No LLM arithmetic.
Single-name / theme exposure policy warnings, and honest data-coverage reporting (missing is shown as missing).
Same engine, gentler surface: guided onboarding and a simplified market read for non-pros.
┌──────────────┐ ┌─────────────────────┐ ┌──────────────┐
│ Frontend │ │ Backend (FastAPI) │ │ Postgres 16 │
│ Next.js +TS │◄─►│ ingestion · quant │◄─►│ +Timescale │
│ Beginner/Pro│ │ scoring · valuation│ │ +pgvector │
└──────────────┘ │ rag · llm · policy │ └──────────────┘
└──────────┬──────────┘
│
┌─────────────┼──────────────┐
▼ ▼ ▼
Market providers Ollama (local reports/
Finnhub/FMP/FRED LLM + embed) (generated)
- Frontend — Next.js + TypeScript dashboard (Beginner & Pro modes).
- Backend — FastAPI: SEC ingestion → deterministic quant → valuation/WACC → local RAG → local LLM memos → rules-based policy engine.
- Postgres — Timescale + pgvector for facts, prices, and embeddings.
- Market providers — thin, optional abstraction (quotes, beta, macro).
- Reports — deterministic markdown/JSON scorecards (gitignored when private).
- Local launcher —
scripts/*.sh+Makefilefor one-command dev.
# 1. Clone
git clone <your-fork-url> Asterion
cd Asterion
# 2. Config — copy templates, then fill (all API keys are optional)
cp .env.example .env # DB, Ollama, SEC user-agent
cp backend/.env.example backend/.env # optional provider keys
# edit ASTERION_SEC_USER_AGENT to "Your Name (you@example.com)" — SEC requires it
# 3. Backend
cd backend
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# 4. Database (Postgres 16, or `docker compose up -d postgres`)
python ../scripts/migrate.py # apply migrations
# 5. Frontend
cd ../frontend && npm install && cd ..
# 6. Run everything (no Docker)
make start # boots :8000 + :3000, opens /marketThen open http://localhost:3000/market.
Want to see it working before wiring up Postgres or SEC? Asterion ships a sanitized sample dataset (deterministic public-company scorecards + the SpaceX IPO scorecard). One command seeds it and boots the app:
# after steps 1–3 + 5 above (backend venv + frontend deps; no DB needed)
make demomake demo runs scripts/load_demo.py (copies examples/demo/reports/ into
reports/, pins the calibration profile, builds the scanner snapshot) then
starts both servers. The file-backed surfaces work immediately:
- http://localhost:3000/scanner — ranked screen (cross-sectional + absolute grade)
- http://localhost:3000/ipo/SPACEX — IPO / private-company mode
- http://localhost:3000/reports — generated scorecards
Pages that need live market/portfolio data (market, portfolio, dashboard) show their honest empty states until you ingest real data. Demo data only — no holdings, no broker data, no secrets.
For the portfolio/risk surfaces, import the fake demo holdings (requires step 4, the database):
cd backend && .venv/bin/python ../scripts/import_portfolio.py ../examples/sample_portfolio.csv
.venv/bin/python ../scripts/generate_portfolio_report.pyAll keys are optional. Without them, Asterion uses fallback / stored data where possible (and clearly labels the source).
| Key | Purpose | Without it |
|---|---|---|
FINNHUB_API_KEY |
Live quotes | Uses stored prices |
FRED_API_KEY |
10Y Treasury → risk-free rate | Static 4.5% fallback |
FMP_API_KEY |
Beta / fundamentals | Sector-fallback beta |
ASTERION_SEC_USER_AGENT |
SEC EDGAR ingestion (real email required) | SEC ingestion disabled |
make start # boot backend (:8000) + frontend (:3000), open /market
make stop # stop both servers (only ports 3000/8000; nothing else)
make health # green/yellow/red: providers configured? portfolio total sane?
make logs # tail logs/backend.log + logs/frontend.logOptional shell aliases — add to ~/.zshrc (point the path at your clone):
alias ast='cd /path/to/Asterion && make start'
alias astop='cd /path/to/Asterion && make stop'
alias ahealth='cd /path/to/Asterion && make health'This is the core contract:
- Missing data is shown as missing. Asterion never fakes unavailable financial data.
- Scores degrade confidence when inputs are missing — every output carries a confidence and a list of missing inputs.
- No LLM arithmetic. All ratios, multiples, and valuations are computed deterministically from SEC facts; the LLM only explains, never calculates.
- Every number is traceable to a SEC fact, price bar, or named provider.
- Provider beta + macro calibration (live FRED/FMP across the universe)
- Outcome-anchored calibration — fit the absolute A–E bands to forward outcomes (cross-sectional + pinned-distribution absolute calibration already shipped; the remaining step is anchoring the bands to realized results)
- Richer report exports
- Optional compliance / risk layer (later)
See CONTRIBUTING.md for local setup, tests, coding
standards, and the no-secrets / no-recommendation rules. Security policy:
SECURITY.md.
Licensed under AGPL-3.0 — see LICENSE. Open-core protection: if
someone runs a modified Asterion as a hosted/network service, their changes must
remain open-source.









