A paper-trading app, and the earnings research behind it — in which twelve promising results were killed by their own controls and none survived.
That is the finding, not a disclaimer. Most public quant repositories publish strategies that worked. This one publishes the controls that killed them, the pre-registrations written before the outcomes were known, and a play that made money and still had no edge.
Everything here is paper trading. The trading base URL is hardcoded to
paper-api.alpaca.markets, the UI proves it from the live endpoint rather than asserting it, and the one script that can place orders throws on startup if that URL is ever changed. There is no live-trading code path.
A paper-trading interface (src/) — account state, equity curve, order
entry, positions with P&L, open orders and fill history, plus a monthly
multi-factor shadow strategy that trades on paper and reports its own results.
The research (scripts/, data/) — an earnings event study over 238
filing-anchored events across 8 symbols, an options study over 83 events with
real historical option prices, and the machinery that produced both.
| Claim | Raw | After its control |
|---|---|---|
| Intraday lead–lag | 71% accurate | 65% for random signals (permutation) |
| Opening-range breakout | +profitable | −31% vs QQQ's +263% (benchmark) |
| Post-earnings drift | +2.29%, t=3.58 | +0.64%, t=1.20 (beta-adjusted) |
| Pre-event news → move size | ρ = 0.432 | ρ = 0.077 (within-symbol) |
| "Cheap straddle" price gate | +30.6% modelled | t = 0.16 on real option prices |
| Per-symbol cheapness (AVGO) | +62% | p = 0.080 vs best-of-8 under the null |
Two things survive, and both were stated as nulls from the start:
- Gap direction is unpredictable. Six pre-event price signals, 238 events, 45–53% against a 50% null.
- Range compression forecasts move size, ρ = −0.261 — but it predicts the median, not the tail an option prices.
And one finding worth stealing regardless of what you think of the rest:
SEC 8-K item 2.02 is not "earnings." It is "Results of Operations", which is
broader. 34 of Tesla's 68 item-2.02 filings are quarterly vehicle delivery
reports carrying byte-identical metadata — same items, same
primaryDocDescription. Only the filing body distinguishes them. Roughly an
eighth of the original sample was the wrong event type.
See scripts/classify-filings.mjs.
npm install
npm run devThen paste an Alpaca paper key pair into the app. Get one free at
alpaca.markets — no funding required, and no live key
will work here anyway. Keys are stored in your browser's localStorage and are
never sent anywhere but Alpaca.
To run the research you also need market data cached locally:
export SEC_CONTACT_EMAIL="you@example.com" # SEC requires a contact in the User-Agent
npm run ingest:yf && npm run classify:filings
npm run study:eventThese were learned expensively and are the actual content of the project.
- Write the prediction down before the outcome, and never edit it after. Later learning gets appended, not merged upstream. A pre-registration whose claims can be revised once results arrive is not a pre-registration.
- A pooled statistic is never applied to an individual symbol without the within-symbol figure printed beside it. A ρ of 0.432 that becomes 0.077 within symbol was measuring which stock this is.
- A result selected as the best of N is tested against the distribution of best-of-N, never against zero.
- An effect that cannot be estimated from prior data alone is not tradeable, however real it is.
Full post-mortem of the one play that reached live paper trading: Blind Bracket Close-Out (rendered) · source. It made +$736 across two trades and had no edge — both winners are traced to causes the strategy never predicted.
Not investment advice, not a strategy that works, and not a backtesting framework — for that, use something maintained. The sample sizes are small (83–238 events, 8–9 symbols), the option-price history starts 2024-01-18, and the daily-bar history mostly starts 2020, which is a bull-market-heavy window. Those limits are stated in the code next to the numbers they affect.
Split out of a private personal-finance tracker; the portfolio side, which reads real brokerage exports, stayed behind.
MIT licensed. Use the controls, ignore the conclusions, run your own.