Skip to content
dvecyPublic

About

Local-first investment research cockpit for SEC filings, valuation scorecards, portfolio risk, and explainable financial analysis.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Asterion market terminal

Asterion — Local-First Investment Research Cockpit

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


⚠️ Disclaimer

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.


Why Asterion

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.

Features

  • 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.

Market scanner & expanding the universe

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 preset

The 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.)

IPO / private-company mode

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-mode

It 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.

Example output

A generated company valuation scorecard (public-company data, no personal info): examples/reports/NVDA_valuation_scorecard.md.

Screenshots

Demo data only — no personal holdings, no broker data, no secrets.

Opportunity Scanner — calibrated ranked screen

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.

Opportunity Scanner — cross-sectionally calibrated ranked screen

IPO / private-company mode — SpaceX

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.

IPO / private-company mode — SpaceX research-only scorecard

Forensic scores — every number traceable

Accrual, dilution, reflexivity, and thesis-fragility signals on a ticker, each with confidence and provenance. No LLM arithmetic.

Ticker forensic scores with provenance

Dashboard & portfolio

Asterion dashboard Portfolio view

Concentration risk & coverage

Single-name / theme exposure policy warnings, and honest data-coverage reporting (missing is shown as missing).

Portfolio concentration risk Data coverage

Beginner mode — progressive disclosure

Same engine, gentler surface: guided onboarding and a simplified market read for non-pros.

Beginner onboarding Beginner market view

Architecture

┌──────────────┐   ┌─────────────────────┐   ┌──────────────┐
│  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 + Makefile for one-command dev.

Quickstart

# 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 /market

Then open http://localhost:3000/market.

Public demo mode — no database, no keys

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 demo

make 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:

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.

Try it with the sample portfolio (needs the database)

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.py

API keys

All 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

Commands

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.log

Optional 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'

Data honesty

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.

Roadmap

  • 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)

Contributing

See CONTRIBUTING.md for local setup, tests, coding standards, and the no-secrets / no-recommendation rules. Security policy: SECURITY.md.

License

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.

About

Local-first investment research cockpit for SEC filings, valuation scorecards, portfolio risk, and explainable financial analysis.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages