An alert I couldn’t buy
I wanted a notification the moment a SPAC signed a definitive agreement — not a headline an hour later. Nothing I could pay for did that, so I started writing it.
SPAC Watch reads every filing a SPAC makes with the SEC — prospectuses, annual reports, merger proxies — and turns 150 pages of legal prose into something you can compare. This is why it exists, and why it’s built the way it is.
I’m Sergey Monin. I write the code behind SPAC Watch, and I trade with my own money.
I look for asymmetric trades — the kind where a dollar at risk can come back as fifteen. That leads me to SPACs most of the time, to biotechs often, and now and then to a company that simply pays a dividend.
SPACs hold my attention because the market is still inefficient in a way forex and crypto stopped being long ago. Warrants regularly trade at deep discounts to what their terms are worth. The catch is thinner liquidity, and the work of telling a real discount from a deserved one.
It started with an alert I wanted and couldn’t find: tell me the moment a SPAC announces its deal. Getting there meant reading filings that were never meant to be read by a machine.
I wanted a notification the moment a SPAC signed a definitive agreement — not a headline an hour later. Nothing I could pay for did that, so I started writing it.
The first document I parsed was the S-1. No two are laid out alike: one sets a table in rows, the next in columns, and the figure you need sits in a footnote eighty pages in. A regex that works on one filing quietly fails on the next.
Only a language model reliably catches the terms written between the lines — a conditional extension, a sponsor loan that converts into warrants — the kind a person misses on page 140 of 150. Making that dependable took far longer than I expected.
A 10-K runs past 150 pages and a megabyte of HTML. Where a language model reads the filing, the model sets the pace, and no programming language changes that. Everything around it is parsing, and that is where Rust earns its place — most of all on the XBRL financials.
Every tagged figure in a 1.1 MB annual report, with its period and unit.
Peak memory for the whole process. On Lambda, memory is what you pay for.
The production Rust code against Python 3.14 with BeautifulSoup and lxml doing the same steps, on one machine and a 10-K of about 80,000 words. The Python reader skipped XBRL value transformations, so it did less work. Elsewhere the gap is smaller, because Python’s XML parser is itself written in C: converting that 10-K to markdown for the model takes 37 ms against 174 ms, and a Form 4 takes 18 µs against 71 µs.
It has run on AWS since the first commit, and that is what lets it scale. Every filing is its own event: it lands on a queue, a function reads it, and the next stage picks it up. A backlog of thousands spreads across dozens of workers instead of waiting its turn on one server.
| Then and now | Where it started | Where it is now |
|---|---|---|
| Code | 11,000 lines of Rust in one crate | 130,000 lines of Rust across 28 crates |
| Reading | Regular expressions and an S-1 table parser | Language models for the prose, a native parser for XBRL financials, vision models for investor decks |
| Filings | Registration and ownership forms | More than 20 form types, from the S-1 to the merger vote |
| Infrastructure | A handful of Lambdas writing to DynamoDB | Event-driven Lambdas over a bronze, silver and gold data lake, with a queue between every stage |
| What comes out | Tickers, underwriters, management | Trust, deadlines, deal terms, sponsor history, warrant and rights fair value |
Extraction gets the facts right. Deciding what they’re worth still takes judgement, and two parts of the model are built on mine.
Classification starts with the team: who they are, what they have closed before, and how their earlier SPACs ended. A large trust can’t rescue a weak sponsor. The model grades from investment grade to high risk. Distressed is set by rule, never by a model.
Warrants and rights start from a standard pricing model, then get adjusted for what a textbook can’t see: the odds the deal closes, and the sponsor’s record, worth up to 20% either way. Those weights come from years of watching which discounts closed and which went to zero.
Tell me. Every figure traces back to an SEC document, and a correction against the source is the fastest way to make this better.