Inspiration
The crypto space is no stranger to heists. Every few weeks another protocol tweets "we are aware of an incident," and millions of dollars wander off. But stolen crypto has an awkward problem: it's traceable. Exchanges freeze it, stablecoin issuers blacklist it, and on-chain detectives chase it like bloodhounds with block explorers.
So where does a thief go? Monero (XMR), the privacy coin. If hackers have to rush stolen funds into XMR before the walls close in, that's forced, price-insensitive buying, and the people selling XMR on the other side don't see it coming. We wanted to know: can you trade the getaway?
What it does
Follow the Heist tests whether public news of a large crypto theft (over $5M) helps predict a meaningful five-day rise in XMR/USD.
Every hour, an L2-regularized logistic regression estimates
$$ p_h(t) = P\big(R_{5d}(t) > h \mid \text{information available at } t\big), \qquad R_{5d}(t) = \frac{P_{XMR}(t+120\text{h})}{P_{XMR}(t)} - 1 $$
using recent XMR and BTC returns, XMR volatility and, crucially, whether a qualifying hack became public in the last 24 hours. A fixed paper-trading rule buys XMR when the forecast is confident enough ($p \ge 0.60$), holds for 120 hours, and pays a deliberately painful 2% round trip in costs.
We compare four models on identical rows: a constant benchmark, a price-only baseline, a "hack happened" presence model and a full model with loss size and age.
How we built it
- Hypothesis first. We wrote down the economic story, the test and what would kill it, and committed it to GitHub before looking at any result of this model. Every later change went in as a dated amendment with a reason.
- Data. Nearly ten years of hourly XMR/USD from Kraken, gaps filled with Binance XMR/BTC × Kraken BTC/USD; hourly BTC/USD from Kraken; and a hand-built catalog of 588 hack incidents (302 above $5M) from DefiLlama, SlowMist, rekt.news and primary sources.
- No peeking. Purged expanding-window validation (no label overlaps across boundaries), scalers fit on training rows only, and the most recent ~2 years locked away as out-of-sample, scored exactly once after everything was frozen.
- Honest statistics. Hourly labels overlap 119 out of 120 hours, so we used a circular block bootstrap (168-hour blocks, 10,000 resamples) instead of pretending each row is independent.
- One command.
python reproduce.pyruns the tests, recomputes the statistics and checks every number in our note.
Challenges we ran into
- Monero is hard to price. Kraken XMR trades sparsely, and Binance delisted it in 2024. We stitched the two venues together minute by minute and disclosed exactly how many hourly closes came from the conversion (35,371).
- Hacks don't come with timestamps. Our catalog has day-level dates only, so we used a conservative rule: an incident "exists" for the model from 00:00 UTC the day after it was reported. Safe from lookahead, but it costs us the first day's reaction.
- Hindsight is sneaky. Loss amounts in public catalogs are final numbers, not what was known that day. We demoted the loss-size feature and stated the limitation plainly instead of pretending it away.
- Reproducibility is humbling. Matching numbers byte for byte across machines, Python versions and two teammates' laptops at 6 AM is its own sport.
Accomplishments that we're proud of
- A fully pre-registered test, amendments timestamped before the results they could affect.
- A clean answer. In development, adding hack information made forecasts slightly worse (log-loss difference −0.00224, one-sided $p = 1.0$). Out-of-sample, the presence model was marginally better, but not significantly ($p = 0.131$).
- We reported it straight: the trading rule made zero trades in development and one out-of-sample (+0.69% net), while buy-and-hold XMR did far better. Crime pays, just not for us.
- A repo where a stranger can clone, run one command and get our numbers.
What we learned
- A great story isn't a great signal. The laundering mechanism is real; a tradable hourly price footprint, at least with public day-level data, isn't.
- Most of quant research is plumbing: timestamps, venues, purging and cost assumptions decide the answer long before the model does.
- Writing the hypothesis down first is uncomfortable and completely worth it. It turned "we got a bad result" into "we got a trustworthy result."
What's next
- A live incident logger that records the exact minute a hack becomes public, so the next test isn't stuck with day-level dates.
- Point-in-time loss amounts, capturing what was known at the time instead of the final tally.
- More venues and coins, plus on-chain flow data into swap services, to look for the laundering footprint where it actually lands.
- And, inevitably, more heists to follow.
Log in or sign up for Devpost to join the conversation.