This actor watches crypto options (BTC and ETH) and flags unusual activity - a contract trading on volume that spikes relative to its open interest, backed by real premium behind the trade, not just noise. Three checks per contract: liquidity, freshness (volume vs open interest ratio), and money behind the trade.
It's a crypto port of an equity options scanner I already run - same three rules, same detection logic, ported to a market that turned out to be shaped differently than expected.
The data source is a different shape
Equities options data (I was pulling from a public CDN) comes back per-ticker: one call, one full chain for that symbol. Crypto options don't work that way — there's really one dominant venue for BTC/ETH options, and its public API returns every strike and expiry for a whole currency in a single call. So the "loop over tickers" became a "loop over currencies" — structurally similar, but the unit of iteration changed.
No fixed contract multiplier
US equity options are always 1 contract = 100 shares. That "x100" was hardcoded in my premium calculation. Crypto options are 1 contract = 1 unit of the underlying (1 BTC, 1 ETH) — no multiplier. I ended up parameterizing the premium function instead of hardcoding the multiplier, which also made the pure signal-logic module reusable as-is between both versions. Same detection math, same tests, different constant.
Prices aren't in USD
Crypto options are quoted in the base currency (a BTC option's price is itself a fraction of a BTC), not in dollars. So every price has to be converted using the current index price before any of the USD-premium thresholds make sense. Easy to get right, easy to silently get wrong if you forget it in one code path.
The bug that actually mattered
While writing tests for the instrument-name parser (something like BTC-28AUG26-59000-P), I'd assumed the date chunk was always a fixed length. It's not — a 1-digit day ("7AUG26") is shorter than a 2-digit day ("28AUG26"). My first length check silently rejected every single-digit-day contract as unparseable. That's roughly 10% of live instruments gone, quietly, with no error — and they skew toward near-dated (often the most actively traded) expiries.
Nothing caught it until I wrote a dedicated test for the parser itself, separate from the end-to-end "does it produce output" test. The lesson isn't really about crypto or options — it's that a parsing function deserves its own unit tests with real edge-case inputs, not just a smoke test that happens to pass because your sample data avoided the edge case.
Same three rules, same pure detection logic, ported across a genuinely different market — most of the actual work was in the boring conversion layer, not the "signal" part.
The crypto version is live on Apify if you want to poke at it: https://apify.com/0xgollum/unusual-crypto-options-activity
Top comments (0)