FAILURE MAP
← Case archive

FA-84446 / Betting odds conversion / Open access

Negative additive probabilities returned or clamped · case 01

A heavy longshot receives a negative or zero fair probability.

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

ROOT CAUSE

The additive result is not checked for negative probabilities.

VERIFIED REPAIR

Return "additive infeasible" when any adjusted probability is negative.

Unsuccessful approach: Clamping negatives to zero produces probabilities that no longer sum to one.

Case contract

Remove the bookmaker margin from decimal prices (implied p = 1/d, book = sum p > 1 assumed). multiplicative: p / book. additive: p - (book - 1) / n; if any result is negative return "additive infeasible". power: p ** k with k found by 60 bisection steps on [1, 10] so that the powered probabilities sum to 1 (k = midpoint of the final bracket). Any other method returns "invalid method". Return the fair probabilities formatted "%.4f".

Why this case matters

Pricing models strip margins differently; favourite-longshot bias makes the method matter.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(60):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in 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 multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['3.86', '4.27', '33.20', '1.56', '33.31'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['1.86', '53.99', '2.05'], 'multiplicative'),
   ['0.5150', '0.0177', '0.4673']),
  ('variant scenario 2',
   (['13.07', '7.90', '2.08', '2.47'], 'additive'),
   ['0.0543', '0.1044', '0.4586', '0.3827'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['1.49', '2.27', '23.29'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1', (['2.67', '1.32'], 'additive'), ['0.3085', '0.6915']),
  ('variant scenario 2',
   (['5.54', '5.02', '7.65', '3.05', '4.02'], 'power'),
   ['0.1639', '0.1818', '0.1165', '0.3078', '0.2299'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['2.82', '46.21', '2.73', '2.34'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['2.03', '5.34', '4.26', '6.91'], 'power'),
   ['0.4762', '0.1728', '0.2190', '0.1319']),
  ('variant scenario 2', (['1.74', '2.07'], 'additive'), ['0.5458', '0.4542'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['29.25', '11.46', '1.90', '1.91'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['4.98', '2.95', '43.55', '3.16', '6.92'], 'multiplicative'),
   ['0.1962', '0.3311', '0.0224', '0.3091', '0.1412']),
  ('variant scenario 2',
   (['4.10', '6.43', '3.04', '2.92'], 'additive'),
   ['0.2262', '0.1378', '0.3112', '0.3248'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['35.15', '1.83', '1.71'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1', (['14.47', '1.05'], 'power'), ['0.0524', '0.9476']),
  ('variant scenario 2',
   (['5.70', '3.60', '5.75', '5.69', '2.89'], 'power'),
   ['0.1480', '0.2451', '0.1466', '0.1483', '0.3120'])]]
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 multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5285', '0.4715']['0.5285', '0.4715']Passed
boundary additive longshot['0.9709', '0.0475', '-0.0092', '-0.0092']additive infeasibleFailed
boundary unknown methodinvalid methodinvalid methodPassed
regression: additive feasibility['0.2202', '0.1953', '-0.0088', '0.6021', '-0.0089']additive infeasibleFailed
variant scenario 1['0.5150', '0.0177', '0.4673']['0.5150', '0.0177', '0.4673']Passed
variant scenario 2['0.0543', '0.1044', '0.4586', '0.3827']['0.0543', '0.1044', '0.4586', '0.3827']Passed

SHA-256 / 7dc8cce11cb0276324a12f05e2f9d786ba55bb99b0959881fc31cb56dd610890

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        fair = [max(0.0, x) for x in fair]
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(60):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in 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 multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['3.86', '4.27', '33.20', '1.56', '33.31'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['1.86', '53.99', '2.05'], 'multiplicative'),
   ['0.5150', '0.0177', '0.4673']),
  ('variant scenario 2',
   (['13.07', '7.90', '2.08', '2.47'], 'additive'),
   ['0.0543', '0.1044', '0.4586', '0.3827'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['1.49', '2.27', '23.29'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1', (['2.67', '1.32'], 'additive'), ['0.3085', '0.6915']),
  ('variant scenario 2',
   (['5.54', '5.02', '7.65', '3.05', '4.02'], 'power'),
   ['0.1639', '0.1818', '0.1165', '0.3078', '0.2299'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['2.82', '46.21', '2.73', '2.34'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['2.03', '5.34', '4.26', '6.91'], 'power'),
   ['0.4762', '0.1728', '0.2190', '0.1319']),
  ('variant scenario 2', (['1.74', '2.07'], 'additive'), ['0.5458', '0.4542'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['29.25', '11.46', '1.90', '1.91'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['4.98', '2.95', '43.55', '3.16', '6.92'], 'multiplicative'),
   ['0.1962', '0.3311', '0.0224', '0.3091', '0.1412']),
  ('variant scenario 2',
   (['4.10', '6.43', '3.04', '2.92'], 'additive'),
   ['0.2262', '0.1378', '0.3112', '0.3248'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['35.15', '1.83', '1.71'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1', (['14.47', '1.05'], 'power'), ['0.0524', '0.9476']),
  ('variant scenario 2',
   (['5.70', '3.60', '5.75', '5.69', '2.89'], 'power'),
   ['0.1480', '0.2451', '0.1466', '0.1483', '0.3120'])]]
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 multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5285', '0.4715']['0.5285', '0.4715']Passed
boundary additive longshot['0.9709', '0.0475', '0.0000', '0.0000']additive infeasibleFailed
boundary unknown methodinvalid methodinvalid methodPassed
regression: additive feasibility['0.2202', '0.1953', '0.0000', '0.6021', '0.0000']additive infeasibleFailed
variant scenario 1['0.5150', '0.0177', '0.4673']['0.5150', '0.0177', '0.4673']Passed
variant scenario 2['0.0543', '0.1044', '0.4586', '0.3827']['0.0543', '0.1044', '0.4586', '0.3827']Passed

SHA-256 / a4c9797ef5b7db03d80b339f763fd95211215c5a8024407c938fa8d125794cce

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        if any(x < 0 for x in fair):
            return 'additive infeasible'
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(60):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in 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 multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['3.86', '4.27', '33.20', '1.56', '33.31'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['1.86', '53.99', '2.05'], 'multiplicative'),
   ['0.5150', '0.0177', '0.4673']),
  ('variant scenario 2',
   (['13.07', '7.90', '2.08', '2.47'], 'additive'),
   ['0.0543', '0.1044', '0.4586', '0.3827'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['1.49', '2.27', '23.29'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1', (['2.67', '1.32'], 'additive'), ['0.3085', '0.6915']),
  ('variant scenario 2',
   (['5.54', '5.02', '7.65', '3.05', '4.02'], 'power'),
   ['0.1639', '0.1818', '0.1165', '0.3078', '0.2299'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['2.82', '46.21', '2.73', '2.34'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['2.03', '5.34', '4.26', '6.91'], 'power'),
   ['0.4762', '0.1728', '0.2190', '0.1319']),
  ('variant scenario 2', (['1.74', '2.07'], 'additive'), ['0.5458', '0.4542'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['29.25', '11.46', '1.90', '1.91'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1',
   (['4.98', '2.95', '43.55', '3.16', '6.92'], 'multiplicative'),
   ['0.1962', '0.3311', '0.0224', '0.3091', '0.1412']),
  ('variant scenario 2',
   (['4.10', '6.43', '3.04', '2.92'], 'additive'),
   ['0.2262', '0.1378', '0.3112', '0.3248'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: additive feasibility',
   (['35.15', '1.83', '1.71'], 'additive'),
   'additive infeasible'),
  ('variant scenario 1', (['14.47', '1.05'], 'power'), ['0.0524', '0.9476']),
  ('variant scenario 2',
   (['5.70', '3.60', '5.75', '5.69', '2.89'], 'power'),
   ['0.1480', '0.2451', '0.1466', '0.1483', '0.3120'])]]
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 multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5285', '0.4715']['0.5285', '0.4715']Passed
boundary additive longshotadditive infeasibleadditive infeasiblePassed
boundary unknown methodinvalid methodinvalid methodPassed
regression: additive feasibilityadditive infeasibleadditive infeasiblePassed
variant scenario 1['0.5150', '0.0177', '0.4673']['0.5150', '0.0177', '0.4673']Passed
variant scenario 2['0.0543', '0.1044', '0.4586', '0.3827']['0.0543', '0.1044', '0.4586', '0.3827']Passed

SHA-256 / 0be9fc11a1134049848df6b76c2450dd189886e3de3384a01793335d776ae933

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

Case digest / fef0e17b8837f8ba72fe68c89968316a65239baa72f4b62260ab38727cfb9a72