FAILURE MAP
← Case archive

FA-84411 / Betting odds conversion / Open access

Bookmaker margin reported as the overround · case 01

The margin column repeats the overround (4.71 instead of 4.50 for 1.91/1.91).

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The margin is computed as book - 1 instead of 1 - 1/book.

THE FAILURE

The margin is computed as book - 1 instead of 1 - 1/book.

Unsuccessful approach: Dividing the overround by the number of outcomes gives a per-outcome figure, not the margin.

Case contract

Market book analysis for decimal prices (strings, each > 1, else "invalid"). Implied probability is 1/d; book = sum of implied probabilities. Return [overround percent (book - 1) * 100, bookmaker margin percent (1 - 1/book) * 100, fair prices d * book for proportional margin removal], every number rounded half up to two decimals (negative values are rounded toward +infinity at the half) and formatted with two decimals.

Why this case matters

Trading tools report overround and margin separately and derive no-vig fair prices.

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(prices):
    def fmt(x):
        c = math.floor(x * 100 + Fraction(1, 2))
        sign = '-' if c < 0 else ''
        c = abs(c)
        return sign + '%d.%02d' % (c // 100, c % 100)
    ds = [Fraction(p) for p in prices]
    if any(d <= 1 for d in ds):
        return 'invalid'
    book = sum(1 / d for d in ds)
    over = (book - 1) * 100
    margin = (book - 1) * 100
    fair = [fmt(d * book) for d in ds]
    return [fmt(over), fmt(margin), fair]
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 fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['2.23', '1.91', '5.75'],),
   ['14.59', '12.73', ['2.56', '2.19', '6.59']]),
  ('variant scenario 1',
   (['5.06', '2.28', '4.51', '3.78'],),
   ['12.25', '10.91', ['5.68', '2.56', '5.06', '4.24']]),
  ('variant scenario 2', (['1.14', '3.87'],), ['13.56', '11.94', ['1.29', '4.39']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['3.85', '3.37', '2.18'],),
   ['1.52', '1.50', ['3.91', '3.42', '2.21']]),
  ('variant scenario 1', (['1.99', '2.86', '3.67'],), ['12.46', '11.08', ['2.24', '3.22', '4.13']]),
  ('variant scenario 2',
   (['2.92', '8.98', '1.89'],),
   ['-1.71', '-1.74', ['2.87', '8.83', '1.86']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['3.10', '8.19', '3.32', '3.05'],),
   ['7.38', '6.87', ['3.33', '8.79', '3.56', '3.27']]),
  ('variant scenario 1',
   (['2.51', '4.38', '4.81', '3.77'],),
   ['9.99', '9.08', ['2.76', '4.82', '5.29', '4.15']]),
  ('variant scenario 2', (['2.41', '2.33', '4.15'],), ['8.51', '7.84', ['2.62', '2.53', '4.50']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['3.20', '3.70', '2.55', '7.93'],),
   ['10.10', '9.18', ['3.52', '4.07', '2.81', '8.73']]),
  ('variant scenario 1', (['1.21', '4.22'],), ['6.34', '5.96', ['1.29', '4.49']]),
  ('variant scenario 2',
   (['19.30', '2.55', '6.75', '2.08'],),
   ['7.29', '6.79', ['20.71', '2.74', '7.24', '2.23']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround', (['4.37', '1.19'],), ['6.92', '6.47', ['4.67', '1.27']]),
  ('variant scenario 1', (['1.29', '4.02'],), ['2.40', '2.34', ['1.32', '4.12']]),
  ('variant scenario 2', (['4.42', '2.56', '2.27'],), ['5.74', '5.43', ['4.67', '2.71', '2.40']])]]
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 fixtureActualExpectedOutcome
control fair coin['0.00', '0.00', ['2.00', '2.00']]['0.00', '0.00', ['2.00', '2.00']]Passed
control standard juice['4.71', '4.71', ['2.00', '2.00']]['4.71', '4.50', ['2.00', '2.00']]Failed
boundary three-way['5.73', '5.73', ['2.64', '3.38', '3.07']]['5.73', '5.42', ['2.64', '3.38', '3.07']]Failed
boundary no-profit priceinvalidinvalidPassed
regression: margin versus overround['14.59', '14.59', ['2.56', '2.19', '6.59']]['14.59', '12.73', ['2.56', '2.19', '6.59']]Failed
variant scenario 1['12.25', '12.25', ['5.68', '2.56', '5.06', '4.24']]['12.25', '10.91', ['5.68', '2.56', '5.06', '4.24']]Failed
variant scenario 2['13.56', '13.56', ['1.29', '4.39']]['13.56', '11.94', ['1.29', '4.39']]Failed

SHA-256 / e53179ba357dcbab17f4e559a846a60d48bc9c045b2157ddb51f5ebd71b54fe9

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(prices):
    def fmt(x):
        c = math.floor(x * 100 + Fraction(1, 2))
        sign = '-' if c < 0 else ''
        c = abs(c)
        return sign + '%d.%02d' % (c // 100, c % 100)
    ds = [Fraction(p) for p in prices]
    if any(d <= 1 for d in ds):
        return 'invalid'
    book = sum(1 / d for d in ds)
    over = (book - 1) * 100
    margin = (book - 1) / len(ds) * 100
    fair = [fmt(d * book) for d in ds]
    return [fmt(over), fmt(margin), fair]
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 fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['2.23', '1.91', '5.75'],),
   ['14.59', '12.73', ['2.56', '2.19', '6.59']]),
  ('variant scenario 1',
   (['5.06', '2.28', '4.51', '3.78'],),
   ['12.25', '10.91', ['5.68', '2.56', '5.06', '4.24']]),
  ('variant scenario 2', (['1.14', '3.87'],), ['13.56', '11.94', ['1.29', '4.39']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['3.85', '3.37', '2.18'],),
   ['1.52', '1.50', ['3.91', '3.42', '2.21']]),
  ('variant scenario 1', (['1.99', '2.86', '3.67'],), ['12.46', '11.08', ['2.24', '3.22', '4.13']]),
  ('variant scenario 2',
   (['2.92', '8.98', '1.89'],),
   ['-1.71', '-1.74', ['2.87', '8.83', '1.86']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['3.10', '8.19', '3.32', '3.05'],),
   ['7.38', '6.87', ['3.33', '8.79', '3.56', '3.27']]),
  ('variant scenario 1',
   (['2.51', '4.38', '4.81', '3.77'],),
   ['9.99', '9.08', ['2.76', '4.82', '5.29', '4.15']]),
  ('variant scenario 2', (['2.41', '2.33', '4.15'],), ['8.51', '7.84', ['2.62', '2.53', '4.50']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround',
   (['3.20', '3.70', '2.55', '7.93'],),
   ['10.10', '9.18', ['3.52', '4.07', '2.81', '8.73']]),
  ('variant scenario 1', (['1.21', '4.22'],), ['6.34', '5.96', ['1.29', '4.49']]),
  ('variant scenario 2',
   (['19.30', '2.55', '6.75', '2.08'],),
   ['7.29', '6.79', ['20.71', '2.74', '7.24', '2.23']])],
 [('control fair coin', (['2.00', '2.00'],), ['0.00', '0.00', ['2.00', '2.00']]),
  ('control standard juice', (['1.91', '1.91'],), ['4.71', '4.50', ['2.00', '2.00']]),
  ('boundary three-way', (['2.50', '3.20', '2.90'],), ['5.73', '5.42', ['2.64', '3.38', '3.07']]),
  ('boundary no-profit price', (['1.00', '5.00'],), 'invalid'),
  ('regression: margin versus overround', (['4.37', '1.19'],), ['6.92', '6.47', ['4.67', '1.27']]),
  ('variant scenario 1', (['1.29', '4.02'],), ['2.40', '2.34', ['1.32', '4.12']]),
  ('variant scenario 2', (['4.42', '2.56', '2.27'],), ['5.74', '5.43', ['4.67', '2.71', '2.40']])]]
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 fixtureActualExpectedOutcome
control fair coin['0.00', '0.00', ['2.00', '2.00']]['0.00', '0.00', ['2.00', '2.00']]Passed
control standard juice['4.71', '2.36', ['2.00', '2.00']]['4.71', '4.50', ['2.00', '2.00']]Failed
boundary three-way['5.73', '1.91', ['2.64', '3.38', '3.07']]['5.73', '5.42', ['2.64', '3.38', '3.07']]Failed
boundary no-profit priceinvalidinvalidPassed
regression: margin versus overround['14.59', '4.86', ['2.56', '2.19', '6.59']]['14.59', '12.73', ['2.56', '2.19', '6.59']]Failed
variant scenario 1['12.25', '3.06', ['5.68', '2.56', '5.06', '4.24']]['12.25', '10.91', ['5.68', '2.56', '5.06', '4.24']]Failed
variant scenario 2['13.56', '6.78', ['1.29', '4.39']]['13.56', '11.94', ['1.29', '4.39']]Failed

SHA-256 / 52d40802950a41e3040733aeeffa40330fe843e45073159d6ae219d669a1ba3e

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 7 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

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:30.523871+00:00.

Case digest / 38477139a36fcaaaf71d58ebd1e9d756464257edb9dae2911ed0e1dfb1f59313