A sports-arbitrage engine that turns market overlap into set algebra. It finds and prices only; it never places a bet.
Overview
Every betting selection is lifted to the region of an event’s outcome grid it wins on. Finding covers, arbs, and middles then becomes bitmask set algebra plus a branch-and-bound set-cover search — which catches differently-named markets that jointly cover an event (“Clean Sheet: Yes” + “Over 0.5 Goals”), something name matching can never do. Live odds come in from several sportsbooks, a devig model turns book odds into true probabilities, a game registry matches the same real-world game across sources, and an interactive web board serves the results.
It is the current, mature generation of a multi-year effort (three earlier engines preceded it), spanning roughly 24 modules with property-based tests throughout. The engine finds and prices opportunities; placing bets is out of scope by design.
Design decisions 06
Standardize market meaning, not market names: every selection is lifted to the set of outcome-grid cells it wins on, so overlap detection is bitmask AND/OR algebra. String-matching names can never find that “Clean Sheet: Yes” + “Over 0.5” jointly cover an event; their region union can.
The engine is sport-agnostic — regions and pricing only ever see a bitmask and a cell count — so adding a sport is a new outcome-grid definition plus market templates, zero engine change. The tennis grid deliberately models the six set-by-set sequences rather than the four final tallies, because two 2–1 matches can disagree on who won set one.
Books and markets are split behind an adapter/template/alias layer: a new book is a ~30-line adapter describing only how it talks, a new market is one template describing only what it means, and adapters auto-register on import — routine extension work never touches the algebra.
Hardcoded pair/triple search was replaced with a general branch-and-bound set-cover enumeration after real use showed the pair limit hid multi-leg covers; now any covering combination at any leg count is found, with profit as an optional filter.
Coverage is measured as probability mass, not cell count: over 1.5 is devigged against its exact complement at the same book, consensus is pooled across books weighted by overround, and a quasi-arb writing off 30% of cells may risk only 0.5% of probability — the number that actually matters.
Cross-source game identity is never guessed: a permanent registry assigns each real-world game a stable id, sources attach exactly and then fuzzily, and uncertain pairs are quarantined to a durable doubts list rather than silently merged or dropped.
Python 3.12 · bitmask set algebra · branch-and-bound set cover · Hypothesis · stdlib web server
listed under projects → · code link lands at go-live