How it works

A nightly pipeline you can audit

Follow one data point through one 24-hour cycle — from a raw price bar or SEC filing to a graded probability on this site. Every stage below runs unattended, every market day.

Scrape Warehouse Features Train Predict Verify Publish
8:45 ET

Morning scrape — everything that moved overnight

News and sentiment, analyst estimates, earnings dates, dividends and splits, insider filings, and macro releases are pulled before the open. Scraping runs on a Celery task queue with an explicit task registry (no dynamic imports), per-API rate ledgers, and idempotent tasks — a failed call retries without double-writing. At 9:10, real-time pre-market quotes land so the day's predictions price entry realistically.

9:15 ET

Predictions before the bell

A compact morning workflow rebuilds the warehouse increment, refreshes the model-ready dataset, and writes today's probabilities from the latest trained predictors — reviewed by 9:20. Entry is the next session's open; the barrier is entry × target, rounded to the cent.

all day

The warehouse — 30 dbt models, 46 tests, one rule above all

Raw scrapes land in source tables and flow through staging, fact, and dataset layers in a single dbt project. Hourly EDGAR polls catch new 10-K/10-Q filings; a daily sweep picks up Form 4s, 13Fs, and 8-Ks. The SEC chain is self-sequencing: filings → metrics → fiscal assignment → periods and cleaning, each stage queuing the next.

No lookahead, ever. Fundamentals attach to trading dates only through their acceptance timestamps — a filing accepted after the close doesn't exist until the next session. FRED macro data keeps every vintage, so the model sees the value that was knowable that day, not today's revision. dbt expression tests enforce these joins on every build; if a model change breaks the rule, the build fails.
20:00 ET

Evening scrape — the day, frozen at the close

Split-adjusted daily bars for every covered ticker, cross-checked between two independent price vendors. 14,164 daily bars and counting — roughly 26 years of history per ticker.

20:30 ET

Walk-forward training

Models are gradient-boosted classifiers (CatBoost) answering barrier-hit questions: P(high ≥ +5% of next open within 5 trading days). Each model keeps one trained predictor per month-end — 13 of them, rolling — and every retrain only ever sees data available at its train date. Training rows require the full outcome window to be closed, so a label can never leak the future.

22:00 ET

The evening loop — grade everything, rebuild everything

Technical indicators recompute, dbt rebuilds, the dataset re-exports, missing predictions backfill, and then the honest part: every past prediction is scored against realized prices. Out-of-time AUC per retrain, calibration by prediction decile, and realized hit rates of top picks versus the whole scored universe — published, including the misses.

Then it publishes. The last step of the nightly loop re-renders the pages you're reading and ships them to a CDN. If the pipeline fails, yesterday's site keeps serving — the deployment can't break the product.

Tested end to end

209+ pytest tests run offline against recorded API fixtures — no network, no flakiness. The target-labeling logic is characterization-tested against a hand-verified gold fixture that code output is never allowed to regenerate. The 46 dbt tests guard the warehouse invariants on every build. If it isn't tested, it doesn't ship.

Built with AI, guarded by tests

The 2026 rebuild — scrapers, warehouse, models, this site — was executed with agentic AI workflows doing the heavy lifting and the test suite deciding what's true. Design invariants live in version-controlled docs the agents must follow; the result is months of platform work compressed into days without giving up rigor.

The stack

Python · Django · Celery
application & task queue
PostgreSQL · dbt
warehouse (30 models / 46 tests)
CatBoost · pandas
modeling (303 dataset columns)
ECharts
visualization
Docker Compose
runtime
pytest · recorded fixtures
209+ offline tests
AWS S3 · CloudFront
publishing
Engineering commitments

Five rules the code lives by

1

No lookahead

Publish-timestamp joins, vintage-aware macro, outcome-window-closed labels — enforced by tests, not discipline.

2

Honest evaluation

Barrier-hit metrics, out-of-time scoring, calibration by decile, base rates beside every probability.

3

Boring plumbing

One queue and dispatcher, explicit task registry, JSON-only messages, idempotent tasks, per-API rate ledgers.

4

Tested contracts

209+ pytest tests offline by default; a gold fixture no code may overwrite; dbt builds green or nothing ships.

5

Rebuilt daily

The whole system — data, models, grades, and this site — regenerates from source every market evening.

See the output — explore the preview