FA-84581 / Betting odds conversion / Open access
Equal best prices attributed to the wrong bookmaker · case 01
The stake is routed to a different bookmaker than the stated tie rule picks.
ROOT CAUSE
Ties on price overwrite the stored bookmaker.
VERIFIED REPAIR
On equal prices keep the alphabetically first bookmaker.
Unsuccessful approach: Preferring the alphabetically last bookmaker still breaks the stated rule.
Case contract
Arbitrage finder. books rows are [bookmaker, outcome, decimal price]. For each outcome take the highest price; ties go to the alphabetically first bookmaker. S = sum of 1/best price. If S >= 1 return ["no arb"]. Otherwise stake_i = floor(total * (1/d_i) / S) cents; guaranteed return = min over outcomes of floor(stake_i * d_i). Return ["arb", [[outcome, bookmaker, stake] sorted by outcome], guaranteed return - sum of stakes].
Why this case matters
Odds comparison tools flag sure bets and split a bankroll across bookmakers.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(books, total_cents):
best = {}
for book, outcome, price in books:
d = Fraction(price)
cur = best.get(outcome)
if cur is None or d > cur[0] or (d == cur[0]):
best[outcome] = (d, book)
S = sum(1 / d for d, _ in best.values())
if S >= 1:
return ['no arb']
rows = []
ret = None
for outcome in sorted(best):
d, book = best[outcome]
stake = math.floor(total_cents * (1 / d) / S)
rows.append([outcome, book, stake])
r = math.floor(stake * d)
ret = r if ret is None else min(ret, r)
return ['arb', rows, ret - sum(r[2] for r in rows)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '2.12'],
['alpha', 'home', '1.85'],
['kilo', 'away', '1.94'],
['delta', 'away', '1.86'],
['bravo', 'away', '1.95'],
['alpha', 'home', '2.12']],
25000),
['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392]),
('regression: bookmaker tiebreak',
([['bravo', 'home', '3.51'],
['delta', 'home', '3.20'],
['delta', 'draw', '3.26'],
['bravo', 'draw', '3.43'],
['bravo', 'away', '2.58'],
['delta', 'away', '2.38'],
['kilo', 'home', '3.51']],
9999),
['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'bravo', 2954]], 371]),
('variant scenario 1',
([['delta', 'home', '2.93'],
['bravo', 'home', '2.86'],
['bravo', 'draw', '3.36'],
['delta', 'draw', '3.11'],
['kilo', 'away', '2.81']],
9999),
['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51]),
('variant scenario 2',
([['delta', 'home', '2.19'],
['bravo', 'home', '2.28'],
['alpha', 'home', '2.14'],
['bravo', 'away', '1.88'],
['delta', 'home', '2.19']],
10000),
['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['alpha', 'home', '2.68'],
['kilo', 'home', '2.64'],
['bravo', 'draw', '3.55'],
['delta', 'draw', '3.29'],
['alpha', 'draw', '3.29'],
['kilo', 'away', '3.06'],
['alpha', 'away', '2.62'],
['bravo', 'home', '2.68']],
25000),
['arb', [['away', 'kilo', 8322], ['draw', 'bravo', 7174], ['home', 'alpha', 9503]], 466]),
('variant scenario 1',
([['alpha', 'home', '2.85'],
['kilo', 'home', '2.89'],
['bravo', 'home', '3.01'],
['alpha', 'away', '1.51']],
10000),
['arb', [['away', 'alpha', 6659], ['home', 'bravo', 3340]], 54]),
('variant scenario 2',
([['kilo', 'home', '1.45'],
['alpha', 'home', '1.60'],
['delta', 'home', '1.63'],
['alpha', 'away', '2.60'],
['alpha', 'home', '1.45']],
9999),
['arb', [['away', 'alpha', 3853], ['home', 'delta', 6145]], 18])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '1.93'],
['delta', 'home', '1.77'],
['delta', 'away', '2.14'],
['alpha', 'home', '1.93']],
25000),
['arb', [['away', 'delta', 11855], ['home', 'alpha', 13144]], 368]),
('regression: bookmaker tiebreak',
([['delta', 'home', '2.69'],
['alpha', 'home', '2.64'],
['kilo', 'away', '1.70'],
['kilo', 'home', '2.69']],
25000),
['arb', [['away', 'kilo', 15318], ['home', 'delta', 9681]], 1041]),
('variant scenario 1',
([['alpha', 'home', '4.67'],
['alpha', 'draw', '2.53'],
['bravo', 'draw', '2.58'],
['delta', 'draw', '2.26'],
['bravo', 'away', '2.81'],
['alpha', 'home', '4.67']],
25000),
['arb', [['away', 'bravo', 9290], ['draw', 'bravo', 10118], ['home', 'alpha', 5590]], 1106]),
('variant scenario 2',
([['delta', 'home', '1.82'],
['alpha', 'home', '1.83'],
['bravo', 'home', '1.81'],
['alpha', 'away', '2.58'],
['delta', 'away', '2.49'],
['kilo', 'away', '2.27']],
10000),
['arb', [['away', 'alpha', 4149], ['home', 'alpha', 5850]], 705])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '3.83'],
['bravo', 'draw', '3.33'],
['kilo', 'draw', '3.68'],
['delta', 'draw', '3.51'],
['alpha', 'away', '2.23'],
['kilo', 'away', '2.23'],
['alpha', 'home', '3.83']],
25000),
['arb', [['away', 'alpha', 11424], ['draw', 'kilo', 6923], ['home', 'alpha', 6652]], 476]),
('variant scenario 1',
([['delta', 'home', '1.97'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('variant scenario 2',
([['delta', 'home', '1.68'], ['bravo', 'home', '1.62'], ['alpha', 'away', '2.82']], 9999),
['arb', [['away', 'alpha', 3732], ['home', 'delta', 6266]], 526])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['alpha', 'home', '2.67'],
['bravo', 'home', '2.37'],
['alpha', 'draw', '3.41'],
['bravo', 'draw', '3.82'],
['bravo', 'away', '3.16'],
['bravo', 'home', '2.67']],
9999),
['arb', [['away', 'bravo', 3321], ['draw', 'bravo', 2747], ['home', 'alpha', 3930]], 495]),
('variant scenario 1',
([['alpha', 'home', '1.73'],
['kilo', 'home', '1.71'],
['delta', 'home', '1.57'],
['kilo', 'away', '2.26'],
['delta', 'home', '1.73']],
10000),
['no arb']),
('variant scenario 2',
([['delta', 'home', '2.20'],
['bravo', 'away', '2.04'],
['delta', 'away', '1.85'],
['kilo', 'away', '2.00']],
25000),
['arb', [['away', 'bravo', 12971], ['home', 'delta', 12028]], 1461])]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| control two-way arb | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500] | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500] | Passed |
| boundary exactly fair book | ['no arb'] | ['no arb'] | Passed |
| boundary tie goes to first name | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000] | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000] | Passed |
| control no arb | ['no arb'] | ['no arb'] | Passed |
| regression: bookmaker tiebreak | ['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392] | ['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392] | Passed |
| regression: bookmaker tiebreak | ['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'kilo', 2954]], 371] | ['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'bravo', 2954]], 371] | Failed |
| variant scenario 1 | ['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51] | ['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51] | Passed |
| variant scenario 2 | ['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303] | ['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303] | Passed |
SHA-256 / 0a914058aa768f669affa7bb66f715fc1c00a82a1a0f54c09cf1e2afe559e492
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(books, total_cents):
best = {}
for book, outcome, price in books:
d = Fraction(price)
cur = best.get(outcome)
if cur is None or d > cur[0] or (d == cur[0] and book > cur[1]):
best[outcome] = (d, book)
S = sum(1 / d for d, _ in best.values())
if S >= 1:
return ['no arb']
rows = []
ret = None
for outcome in sorted(best):
d, book = best[outcome]
stake = math.floor(total_cents * (1 / d) / S)
rows.append([outcome, book, stake])
r = math.floor(stake * d)
ret = r if ret is None else min(ret, r)
return ['arb', rows, ret - sum(r[2] for r in rows)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '2.12'],
['alpha', 'home', '1.85'],
['kilo', 'away', '1.94'],
['delta', 'away', '1.86'],
['bravo', 'away', '1.95'],
['alpha', 'home', '2.12']],
25000),
['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392]),
('regression: bookmaker tiebreak',
([['bravo', 'home', '3.51'],
['delta', 'home', '3.20'],
['delta', 'draw', '3.26'],
['bravo', 'draw', '3.43'],
['bravo', 'away', '2.58'],
['delta', 'away', '2.38'],
['kilo', 'home', '3.51']],
9999),
['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'bravo', 2954]], 371]),
('variant scenario 1',
([['delta', 'home', '2.93'],
['bravo', 'home', '2.86'],
['bravo', 'draw', '3.36'],
['delta', 'draw', '3.11'],
['kilo', 'away', '2.81']],
9999),
['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51]),
('variant scenario 2',
([['delta', 'home', '2.19'],
['bravo', 'home', '2.28'],
['alpha', 'home', '2.14'],
['bravo', 'away', '1.88'],
['delta', 'home', '2.19']],
10000),
['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['alpha', 'home', '2.68'],
['kilo', 'home', '2.64'],
['bravo', 'draw', '3.55'],
['delta', 'draw', '3.29'],
['alpha', 'draw', '3.29'],
['kilo', 'away', '3.06'],
['alpha', 'away', '2.62'],
['bravo', 'home', '2.68']],
25000),
['arb', [['away', 'kilo', 8322], ['draw', 'bravo', 7174], ['home', 'alpha', 9503]], 466]),
('variant scenario 1',
([['alpha', 'home', '2.85'],
['kilo', 'home', '2.89'],
['bravo', 'home', '3.01'],
['alpha', 'away', '1.51']],
10000),
['arb', [['away', 'alpha', 6659], ['home', 'bravo', 3340]], 54]),
('variant scenario 2',
([['kilo', 'home', '1.45'],
['alpha', 'home', '1.60'],
['delta', 'home', '1.63'],
['alpha', 'away', '2.60'],
['alpha', 'home', '1.45']],
9999),
['arb', [['away', 'alpha', 3853], ['home', 'delta', 6145]], 18])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '1.93'],
['delta', 'home', '1.77'],
['delta', 'away', '2.14'],
['alpha', 'home', '1.93']],
25000),
['arb', [['away', 'delta', 11855], ['home', 'alpha', 13144]], 368]),
('regression: bookmaker tiebreak',
([['delta', 'home', '2.69'],
['alpha', 'home', '2.64'],
['kilo', 'away', '1.70'],
['kilo', 'home', '2.69']],
25000),
['arb', [['away', 'kilo', 15318], ['home', 'delta', 9681]], 1041]),
('variant scenario 1',
([['alpha', 'home', '4.67'],
['alpha', 'draw', '2.53'],
['bravo', 'draw', '2.58'],
['delta', 'draw', '2.26'],
['bravo', 'away', '2.81'],
['alpha', 'home', '4.67']],
25000),
['arb', [['away', 'bravo', 9290], ['draw', 'bravo', 10118], ['home', 'alpha', 5590]], 1106]),
('variant scenario 2',
([['delta', 'home', '1.82'],
['alpha', 'home', '1.83'],
['bravo', 'home', '1.81'],
['alpha', 'away', '2.58'],
['delta', 'away', '2.49'],
['kilo', 'away', '2.27']],
10000),
['arb', [['away', 'alpha', 4149], ['home', 'alpha', 5850]], 705])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '3.83'],
['bravo', 'draw', '3.33'],
['kilo', 'draw', '3.68'],
['delta', 'draw', '3.51'],
['alpha', 'away', '2.23'],
['kilo', 'away', '2.23'],
['alpha', 'home', '3.83']],
25000),
['arb', [['away', 'alpha', 11424], ['draw', 'kilo', 6923], ['home', 'alpha', 6652]], 476]),
('variant scenario 1',
([['delta', 'home', '1.97'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('variant scenario 2',
([['delta', 'home', '1.68'], ['bravo', 'home', '1.62'], ['alpha', 'away', '2.82']], 9999),
['arb', [['away', 'alpha', 3732], ['home', 'delta', 6266]], 526])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['alpha', 'home', '2.67'],
['bravo', 'home', '2.37'],
['alpha', 'draw', '3.41'],
['bravo', 'draw', '3.82'],
['bravo', 'away', '3.16'],
['bravo', 'home', '2.67']],
9999),
['arb', [['away', 'bravo', 3321], ['draw', 'bravo', 2747], ['home', 'alpha', 3930]], 495]),
('variant scenario 1',
([['alpha', 'home', '1.73'],
['kilo', 'home', '1.71'],
['delta', 'home', '1.57'],
['kilo', 'away', '2.26'],
['delta', 'home', '1.73']],
10000),
['no arb']),
('variant scenario 2',
([['delta', 'home', '2.20'],
['bravo', 'away', '2.04'],
['delta', 'away', '1.85'],
['kilo', 'away', '2.00']],
25000),
['arb', [['away', 'bravo', 12971], ['home', 'delta', 12028]], 1461])]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| control two-way arb | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500] | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500] | Passed |
| boundary exactly fair book | ['no arb'] | ['no arb'] | Passed |
| boundary tie goes to first name | ['arb', [['away', 'bravo', 5000], ['home', 'kilo', 5000]], 1000] | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000] | Failed |
| control no arb | ['no arb'] | ['no arb'] | Passed |
| regression: bookmaker tiebreak | ['arb', [['away', 'bravo', 13022], ['home', 'bravo', 11977]], 392] | ['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392] | Failed |
| regression: bookmaker tiebreak | ['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'kilo', 2954]], 371] | ['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'bravo', 2954]], 371] | Failed |
| variant scenario 1 | ['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51] | ['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51] | Passed |
| variant scenario 2 | ['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303] | ['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303] | Passed |
SHA-256 / 604dae251bf817dbaabaa17d5d0ff585bec61cbf2a75f7147c0e61dc2349bd27
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(books, total_cents):
best = {}
for book, outcome, price in books:
d = Fraction(price)
cur = best.get(outcome)
if cur is None or d > cur[0] or (d == cur[0] and book < cur[1]):
best[outcome] = (d, book)
S = sum(1 / d for d, _ in best.values())
if S >= 1:
return ['no arb']
rows = []
ret = None
for outcome in sorted(best):
d, book = best[outcome]
stake = math.floor(total_cents * (1 / d) / S)
rows.append([outcome, book, stake])
r = math.floor(stake * d)
ret = r if ret is None else min(ret, r)
return ['arb', rows, ret - sum(r[2] for r in rows)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '2.12'],
['alpha', 'home', '1.85'],
['kilo', 'away', '1.94'],
['delta', 'away', '1.86'],
['bravo', 'away', '1.95'],
['alpha', 'home', '2.12']],
25000),
['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392]),
('regression: bookmaker tiebreak',
([['bravo', 'home', '3.51'],
['delta', 'home', '3.20'],
['delta', 'draw', '3.26'],
['bravo', 'draw', '3.43'],
['bravo', 'away', '2.58'],
['delta', 'away', '2.38'],
['kilo', 'home', '3.51']],
9999),
['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'bravo', 2954]], 371]),
('variant scenario 1',
([['delta', 'home', '2.93'],
['bravo', 'home', '2.86'],
['bravo', 'draw', '3.36'],
['delta', 'draw', '3.11'],
['kilo', 'away', '2.81']],
9999),
['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51]),
('variant scenario 2',
([['delta', 'home', '2.19'],
['bravo', 'home', '2.28'],
['alpha', 'home', '2.14'],
['bravo', 'away', '1.88'],
['delta', 'home', '2.19']],
10000),
['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['alpha', 'home', '2.68'],
['kilo', 'home', '2.64'],
['bravo', 'draw', '3.55'],
['delta', 'draw', '3.29'],
['alpha', 'draw', '3.29'],
['kilo', 'away', '3.06'],
['alpha', 'away', '2.62'],
['bravo', 'home', '2.68']],
25000),
['arb', [['away', 'kilo', 8322], ['draw', 'bravo', 7174], ['home', 'alpha', 9503]], 466]),
('variant scenario 1',
([['alpha', 'home', '2.85'],
['kilo', 'home', '2.89'],
['bravo', 'home', '3.01'],
['alpha', 'away', '1.51']],
10000),
['arb', [['away', 'alpha', 6659], ['home', 'bravo', 3340]], 54]),
('variant scenario 2',
([['kilo', 'home', '1.45'],
['alpha', 'home', '1.60'],
['delta', 'home', '1.63'],
['alpha', 'away', '2.60'],
['alpha', 'home', '1.45']],
9999),
['arb', [['away', 'alpha', 3853], ['home', 'delta', 6145]], 18])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '1.93'],
['delta', 'home', '1.77'],
['delta', 'away', '2.14'],
['alpha', 'home', '1.93']],
25000),
['arb', [['away', 'delta', 11855], ['home', 'alpha', 13144]], 368]),
('regression: bookmaker tiebreak',
([['delta', 'home', '2.69'],
['alpha', 'home', '2.64'],
['kilo', 'away', '1.70'],
['kilo', 'home', '2.69']],
25000),
['arb', [['away', 'kilo', 15318], ['home', 'delta', 9681]], 1041]),
('variant scenario 1',
([['alpha', 'home', '4.67'],
['alpha', 'draw', '2.53'],
['bravo', 'draw', '2.58'],
['delta', 'draw', '2.26'],
['bravo', 'away', '2.81'],
['alpha', 'home', '4.67']],
25000),
['arb', [['away', 'bravo', 9290], ['draw', 'bravo', 10118], ['home', 'alpha', 5590]], 1106]),
('variant scenario 2',
([['delta', 'home', '1.82'],
['alpha', 'home', '1.83'],
['bravo', 'home', '1.81'],
['alpha', 'away', '2.58'],
['delta', 'away', '2.49'],
['kilo', 'away', '2.27']],
10000),
['arb', [['away', 'alpha', 4149], ['home', 'alpha', 5850]], 705])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['bravo', 'home', '3.83'],
['bravo', 'draw', '3.33'],
['kilo', 'draw', '3.68'],
['delta', 'draw', '3.51'],
['alpha', 'away', '2.23'],
['kilo', 'away', '2.23'],
['alpha', 'home', '3.83']],
25000),
['arb', [['away', 'alpha', 11424], ['draw', 'kilo', 6923], ['home', 'alpha', 6652]], 476]),
('variant scenario 1',
([['delta', 'home', '1.97'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('variant scenario 2',
([['delta', 'home', '1.68'], ['bravo', 'home', '1.62'], ['alpha', 'away', '2.82']], 9999),
['arb', [['away', 'alpha', 3732], ['home', 'delta', 6266]], 526])],
[('control two-way arb',
([['alpha', 'home', '2.10'], ['bravo', 'away', '2.10'], ['bravo', 'home', '1.90']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500]),
('boundary exactly fair book',
([['alpha', 'home', '2.00'], ['bravo', 'away', '2.00']], 10000),
['no arb']),
('boundary tie goes to first name',
([['kilo', 'home', '2.20'], ['alpha', 'home', '2.20'], ['bravo', 'away', '2.20']], 10000),
['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000]),
('control no arb', ([['alpha', 'home', '1.90'], ['alpha', 'away', '1.90']], 10000), ['no arb']),
('regression: bookmaker tiebreak',
([['alpha', 'home', '2.67'],
['bravo', 'home', '2.37'],
['alpha', 'draw', '3.41'],
['bravo', 'draw', '3.82'],
['bravo', 'away', '3.16'],
['bravo', 'home', '2.67']],
9999),
['arb', [['away', 'bravo', 3321], ['draw', 'bravo', 2747], ['home', 'alpha', 3930]], 495]),
('variant scenario 1',
([['alpha', 'home', '1.73'],
['kilo', 'home', '1.71'],
['delta', 'home', '1.57'],
['kilo', 'away', '2.26'],
['delta', 'home', '1.73']],
10000),
['no arb']),
('variant scenario 2',
([['delta', 'home', '2.20'],
['bravo', 'away', '2.04'],
['delta', 'away', '1.85'],
['kilo', 'away', '2.00']],
25000),
['arb', [['away', 'bravo', 12971], ['home', 'delta', 12028]], 1461])]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| control two-way arb | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500] | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 500] | Passed |
| boundary exactly fair book | ['no arb'] | ['no arb'] | Passed |
| boundary tie goes to first name | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000] | ['arb', [['away', 'bravo', 5000], ['home', 'alpha', 5000]], 1000] | Passed |
| control no arb | ['no arb'] | ['no arb'] | Passed |
| regression: bookmaker tiebreak | ['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392] | ['arb', [['away', 'bravo', 13022], ['home', 'alpha', 11977]], 392] | Passed |
| regression: bookmaker tiebreak | ['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'bravo', 2954]], 371] | ['arb', [['away', 'bravo', 4020], ['draw', 'bravo', 3023], ['home', 'bravo', 2954]], 371] | Passed |
| variant scenario 1 | ['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51] | ['arb', [['away', 'kilo', 3577], ['draw', 'bravo', 2991], ['home', 'delta', 3430]], 51] | Passed |
| variant scenario 2 | ['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303] | ['arb', [['away', 'bravo', 5480], ['home', 'bravo', 4519]], 303] | Passed |
SHA-256 / 8948a5f562683335687c49c6854b544439ff6e2e7272f8215382fdd2a35087d8
Verification & scope
Stipulated, bounded toy contract stated in the contract field; not a claim of conformance with any operator, exchange or regulator rule set. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:50:32.351544+00:00.
Case digest / 71fcb173b6af8b8859a1c3fe427729eed3ddb74e3cb1eebd685c8d752f5b1fdf