An event-study pipeline that recovers a minute-level distribution of expected US CPI inflation from Kalshi bracket markets and estimates its response to CPI announcement surprises.
The repository separates two claims that are easy to conflate:
- The software is publicly reproducible.
make demobuilds synthetic inputs, runs the same panel, distribution, regression, diagnostic, and figure code, and requires no API key or proprietary file. - The empirical estimates require licensed Bloomberg inputs. Bloomberg's release calendar and consensus data are not distributed. A user with an authorized export can reproduce the research results locally.
For each CPI release, Kalshi's threshold contracts imply exceedance probabilities, such as (P(CPI > 0.3)). Adjacent thresholds recover probability mass over outcome bins. The pipeline uses that distribution to calculate (E[CPI]) and (Var(CPI)), then estimates
[ \Delta E_i^{(h)} = \alpha_h + \beta_h Surprise_i + \varepsilon_i, ]
where the baseline is exactly five minutes before publication and (h \in {5,10,15,30,60,90,120,240}) minutes.
The checked-in aggregate results cover 40 CPI releases in the final consistent sample. The estimated response of expected CPI is positive and becomes clearer at longer horizons. At 120 minutes, (\hat\beta=0.0212) with (p=0.0013). These estimates should be read with the data-quality limitations below: about 27% of events have essentially no measured movement at five minutes, which may represent either genuine non-reaction or stale quotes.
The repository does not claim that the existing random-day placebo validates identification. The stored panel is built around release windows, so it does not contain suitable non-announcement days. The supported public run reports the pre-trend diagnostic and leaves the random-day placebo disabled.
Selected portfolio figures are checked in under reports/figures/; the full
event-level figure set is generated locally.
The reviewed term paper is available at
paper/inflation-expectations-cpi.pdf.
Its title page omits course administration and student identifiers.
Requirements: Python 3.11 or 3.12, make, and roughly 1 GB of free space.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements-lock.txt
make test
make demoThe demo writes only to build/demo/. Its events, surprises, quotes, and results
are deterministic synthetic data and have no empirical meaning. The complete run
produces a compact panel, event-level regression data, diagnostics, tables, and
figures.
- Obtain an authorized Bloomberg Excel export with columns
Event,Date Time,Actual,Surprise,Surv(M), andPrior. - Save it locally as
data/private/bloomberg_events_data.xlsx. That directory is ignored by Git and must never be committed. A different location can be selected withBLOOMBERG_EVENTS_FILE=/absolute/path/to/export.xlsx. - Install dependencies as above.
requirements-lock.txtrecords the verified environment;requirements.txtallows compatible newer versions for development. - Run:
python scripts/01_parse_bloomberg.py
python scripts/02_discover_markets.py
python scripts/03_download_candles.py
python scripts/04_process_panel.py
python scripts/05_prepare_regression.py
python scripts/06_robustness_checks.py --pretrend-only
python scripts/07_make_plots.pyKalshi's historical public endpoints do not require a key in this implementation. API availability and historical coverage can change, so exact raw-data retrieval is not guaranteed indefinitely. Existing downloads are incremental.
| Step | Script | Purpose |
|---|---|---|
| 00 | 00_generate_demo_data.py |
Create public synthetic inputs |
| 01 | 01_parse_bloomberg.py |
Parse the private licensed event export |
| 02 | 02_discover_markets.py |
Discover CPI markets and brackets |
| 03 | 03_download_candles.py |
Download public one-minute quote candles |
| 04 | 04_process_panel.py |
Build compact ([-240,+240])-minute panels |
| 05 | 05_prepare_regression.py |
Infer distributions and estimate OLS models |
| 06 | 06_robustness_checks.py |
Run pre-trend diagnostics; experimental placebo code is disabled by default |
| 07 | 07_make_plots.py |
Generate figures and liquidity diagnostics |
Step 04 has an explicit --full-history option. It can produce a panel hundreds
of megabytes in size and is not necessary for the main event study.
An event enters every reported horizon only when it has:
- an exact observation at (t=-5);
- at least three non-placeholder brackets at baseline;
- finite inferred expectation and variance; and
- valid estimates at all eight horizons.
A quote with bid 0 and ask 100 is treated as an empty-order-book placeholder. Quotes are forward-filled between observed updates. Consequently, a flat path can mean either stable beliefs or no new quote activity; the data cannot identify which explanation applies.
config/ Series configuration
docs/ Data, methodology, and API notes
scripts/ Numbered pipeline entry points
src/ Reusable parsing, panel, and distribution functions
tests/ Unit tests used by GitHub Actions
reports/ Reviewed aggregate empirical tables
build/ Ignored synthetic demo output
data/ Ignored licensed, raw, and intermediate local data
See METHODOLOGY.md for the full method and docs/DATA_AND_REPRODUCIBILITY.md for the publication boundary.
- Bloomberg consensus data cannot be redistributed with this repository.
- Sparse trading and forward-filled quotes can attenuate response estimates.
- The strict baseline selects events with usable pre-release liquidity.
- The current data do not support a credible random non-event-day placebo.
- Bin endpoints require tail assumptions; results are market-implied measures, not direct survey forecasts.
Code is released under the MIT License. That license does not apply to Bloomberg data or third-party market data. If you use the project, cite the repository URL and the version or commit hash used.
