The problem
10-K annual reports are long and dense; the market's reaction to their narrative sections (MD&A, Risk Factors) is hard to anticipate from a manual read.
The load-bearing signal — how much a filing changed from last year, and how much hedging/uncertainty language it carries — is buried in unstructured text.
Analysts need a way to quantify filing 'surprise' and tie it to measurable price and volatility outcomes.
The approach
Ingest 10-Ks from SEC EDGAR, extract the MD&A and Risk Factors sections, and align each filing with T+1/T+3/T+7 market-reaction labels from price data.
Engineer features across sentiment (FinBERT), an uncertainty/hedging lexicon, XBRL financial metadata, and cosine similarity against the prior year's filing as a 'surprise' score.
Feed the features to baseline and FinBERT-based models to predict the direction/magnitude of the post-filing move, benchmarked against sector norms.
What I built
- SEC EDGAR ingestion module (edgartools) plus a market-data connector (yfinance) for post-filing price/volatility labels
- Feature pipeline: FinBERT sentiment scoring, an uncertainty lexicon, XBRL metadata extraction, and prior-year similarity comparison
- Modeling layer with a baseline model, a FinBERT model, and an evaluation harness, plus sector-benchmark scoring
- A prediction/advisory layer that highlights the driving passages in a filing and produces recommendations
- A FastAPI web app (score a filing on demand) with a browser UI, containerized and configured for Railway deployment
- Test suite covering EDGAR ingestion, feature extraction, models, and the advisory/web layers
- Python
- SEC EDGAR (edgartools)
- FinBERT / Transformers
- PyTorch
- scikit-learn
- XGBoost
- yfinance
- FastAPI
- Railway
- pytest
Result
A working prototype pipeline that ingests a 10-K, engineers sentiment/uncertainty/surprise features, and serves a post-filing reaction prediction through a web app — end to end, with tests across every stage.