FA-84386 / Betting odds conversion / Open access
Implied probability uses one formula for both signs · case 01
Underdog probabilities come out above 50 percent.
ROOT CAUSE
The favourite formula N / (N + 100) is applied to every line.
VERIFIED REPAIR
Use 100 / (N + 100) for positive lines and N / (N + 100) for negative lines.
Unsuccessful approach: Using the underdog formula everywhere gives favourites probabilities below 50 percent.
Case contract
Expand an American moneyline ("+150", "150" or "-200"; magnitude at least 100, otherwise "invalid"). Profit per unit is N/100 for positive or unsigned lines and 100/N for negative lines. Return [decimal price with two decimals, reduced fractional profit "a/b", implied probability percent with one decimal], all computed exactly and rounded half up.
Why this case matters
Odds screens show American, decimal, fractional and implied-probability columns for one price.
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(american):
s = american.strip()
neg = s.startswith('-')
n = int(s.lstrip('+-'))
if n < 100:
return 'invalid'
profit = Fraction(100, n) if neg else Fraction(n, 100)
dec = 1 + profit
def fmt(x, places):
q = 10 ** places
v = math.floor(x * q + Fraction(1, 2))
return '%d.%0*d' % (v // q, places, v % q)
prob = Fraction(n, n + 100) * 100
return [fmt(dec, 2), '%d/%d' % (profit.numerator, profit.denominator), fmt(prob, 1)]
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 underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-247',), ['1.40', '100/247', '71.2']),
('regression: implied probability sign', ('491',), ['5.91', '491/100', '16.9']),
('variant scenario 1', ('-446',), ['1.22', '50/223', '81.7']),
('variant scenario 2', ('-636',), ['1.16', '25/159', '86.4'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('602',), ['7.02', '301/50', '14.2']),
('regression: implied probability sign', ('-310',), ['1.32', '10/31', '75.6']),
('variant scenario 1', ('+328',), ['4.28', '82/25', '23.4']),
('variant scenario 2', ('+732',), ['8.32', '183/25', '12.0'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-283',), ['1.35', '100/283', '73.9']),
('regression: implied probability sign', ('+757',), ['8.57', '757/100', '11.7']),
('variant scenario 1', ('-466',), ['1.21', '50/233', '82.3']),
('variant scenario 2', ('100',), ['2.00', '1/1', '50.0'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('+284',), ['3.84', '71/25', '26.0']),
('variant scenario 1', ('+448',), ['5.48', '112/25', '18.2']),
('variant scenario 2', ('-131',), ['1.76', '100/131', '56.7'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('+234',), ['3.34', '117/50', '29.9']),
('regression: implied probability sign', ('-110',), ['1.91', '10/11', '52.4']),
('variant scenario 1', ('430',), ['5.30', '43/10', '18.9']),
('variant scenario 2', ('+115',), ['2.15', '23/20', '46.5'])]]
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 underdog | ['2.50', '3/2', '60.0'] | ['2.50', '3/2', '40.0'] | Failed |
| control favourite | ['1.50', '1/2', '66.7'] | ['1.50', '1/2', '66.7'] | Passed |
| boundary even money | ['2.00', '1/1', '50.0'] | ['2.00', '1/1', '50.0'] | Passed |
| boundary unsigned line | ['3.50', '5/2', '71.4'] | ['3.50', '5/2', '28.6'] | Failed |
| boundary below minimum | invalid | invalid | Passed |
| control half-up decimal | ['1.13', '1/8', '88.9'] | ['1.13', '1/8', '88.9'] | Passed |
| regression: implied probability sign | ['1.40', '100/247', '71.2'] | ['1.40', '100/247', '71.2'] | Passed |
| regression: implied probability sign | ['5.91', '491/100', '83.1'] | ['5.91', '491/100', '16.9'] | Failed |
| variant scenario 1 | ['1.22', '50/223', '81.7'] | ['1.22', '50/223', '81.7'] | Passed |
| variant scenario 2 | ['1.16', '25/159', '86.4'] | ['1.16', '25/159', '86.4'] | Passed |
SHA-256 / b280b92d3d170a91f83be5a9d9880dfe2dab769f5bbf7a2c030f8be9e89d5eb0
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(american):
s = american.strip()
neg = s.startswith('-')
n = int(s.lstrip('+-'))
if n < 100:
return 'invalid'
profit = Fraction(100, n) if neg else Fraction(n, 100)
dec = 1 + profit
def fmt(x, places):
q = 10 ** places
v = math.floor(x * q + Fraction(1, 2))
return '%d.%0*d' % (v // q, places, v % q)
prob = Fraction(100, n + 100) * 100
return [fmt(dec, 2), '%d/%d' % (profit.numerator, profit.denominator), fmt(prob, 1)]
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 underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-247',), ['1.40', '100/247', '71.2']),
('regression: implied probability sign', ('491',), ['5.91', '491/100', '16.9']),
('variant scenario 1', ('-446',), ['1.22', '50/223', '81.7']),
('variant scenario 2', ('-636',), ['1.16', '25/159', '86.4'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('602',), ['7.02', '301/50', '14.2']),
('regression: implied probability sign', ('-310',), ['1.32', '10/31', '75.6']),
('variant scenario 1', ('+328',), ['4.28', '82/25', '23.4']),
('variant scenario 2', ('+732',), ['8.32', '183/25', '12.0'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-283',), ['1.35', '100/283', '73.9']),
('regression: implied probability sign', ('+757',), ['8.57', '757/100', '11.7']),
('variant scenario 1', ('-466',), ['1.21', '50/233', '82.3']),
('variant scenario 2', ('100',), ['2.00', '1/1', '50.0'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('+284',), ['3.84', '71/25', '26.0']),
('variant scenario 1', ('+448',), ['5.48', '112/25', '18.2']),
('variant scenario 2', ('-131',), ['1.76', '100/131', '56.7'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('+234',), ['3.34', '117/50', '29.9']),
('regression: implied probability sign', ('-110',), ['1.91', '10/11', '52.4']),
('variant scenario 1', ('430',), ['5.30', '43/10', '18.9']),
('variant scenario 2', ('+115',), ['2.15', '23/20', '46.5'])]]
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 underdog | ['2.50', '3/2', '40.0'] | ['2.50', '3/2', '40.0'] | Passed |
| control favourite | ['1.50', '1/2', '33.3'] | ['1.50', '1/2', '66.7'] | Failed |
| boundary even money | ['2.00', '1/1', '50.0'] | ['2.00', '1/1', '50.0'] | Passed |
| boundary unsigned line | ['3.50', '5/2', '28.6'] | ['3.50', '5/2', '28.6'] | Passed |
| boundary below minimum | invalid | invalid | Passed |
| control half-up decimal | ['1.13', '1/8', '11.1'] | ['1.13', '1/8', '88.9'] | Failed |
| regression: implied probability sign | ['1.40', '100/247', '28.8'] | ['1.40', '100/247', '71.2'] | Failed |
| regression: implied probability sign | ['5.91', '491/100', '16.9'] | ['5.91', '491/100', '16.9'] | Passed |
| variant scenario 1 | ['1.22', '50/223', '18.3'] | ['1.22', '50/223', '81.7'] | Failed |
| variant scenario 2 | ['1.16', '25/159', '13.6'] | ['1.16', '25/159', '86.4'] | Failed |
SHA-256 / bff2bfc46f92370b3c0ba9b05dbb803b9ca77cb5309ec6b62a42b4b8ae5b0e1d
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(american):
s = american.strip()
neg = s.startswith('-')
n = int(s.lstrip('+-'))
if n < 100:
return 'invalid'
profit = Fraction(100, n) if neg else Fraction(n, 100)
dec = 1 + profit
def fmt(x, places):
q = 10 ** places
v = math.floor(x * q + Fraction(1, 2))
return '%d.%0*d' % (v // q, places, v % q)
prob = Fraction(n, n + 100) * 100 if neg else Fraction(100, n + 100) * 100
return [fmt(dec, 2), '%d/%d' % (profit.numerator, profit.denominator), fmt(prob, 1)]
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 underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-247',), ['1.40', '100/247', '71.2']),
('regression: implied probability sign', ('491',), ['5.91', '491/100', '16.9']),
('variant scenario 1', ('-446',), ['1.22', '50/223', '81.7']),
('variant scenario 2', ('-636',), ['1.16', '25/159', '86.4'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('602',), ['7.02', '301/50', '14.2']),
('regression: implied probability sign', ('-310',), ['1.32', '10/31', '75.6']),
('variant scenario 1', ('+328',), ['4.28', '82/25', '23.4']),
('variant scenario 2', ('+732',), ['8.32', '183/25', '12.0'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-283',), ['1.35', '100/283', '73.9']),
('regression: implied probability sign', ('+757',), ['8.57', '757/100', '11.7']),
('variant scenario 1', ('-466',), ['1.21', '50/233', '82.3']),
('variant scenario 2', ('100',), ['2.00', '1/1', '50.0'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('+284',), ['3.84', '71/25', '26.0']),
('variant scenario 1', ('+448',), ['5.48', '112/25', '18.2']),
('variant scenario 2', ('-131',), ['1.76', '100/131', '56.7'])],
[('control underdog', ('+150',), ['2.50', '3/2', '40.0']),
('control favourite', ('-200',), ['1.50', '1/2', '66.7']),
('boundary even money', ('+100',), ['2.00', '1/1', '50.0']),
('boundary unsigned line', ('250',), ['3.50', '5/2', '28.6']),
('boundary below minimum', ('+50',), 'invalid'),
('control half-up decimal', ('-800',), ['1.13', '1/8', '88.9']),
('regression: implied probability sign', ('+234',), ['3.34', '117/50', '29.9']),
('regression: implied probability sign', ('-110',), ['1.91', '10/11', '52.4']),
('variant scenario 1', ('430',), ['5.30', '43/10', '18.9']),
('variant scenario 2', ('+115',), ['2.15', '23/20', '46.5'])]]
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 underdog | ['2.50', '3/2', '40.0'] | ['2.50', '3/2', '40.0'] | Passed |
| control favourite | ['1.50', '1/2', '66.7'] | ['1.50', '1/2', '66.7'] | Passed |
| boundary even money | ['2.00', '1/1', '50.0'] | ['2.00', '1/1', '50.0'] | Passed |
| boundary unsigned line | ['3.50', '5/2', '28.6'] | ['3.50', '5/2', '28.6'] | Passed |
| boundary below minimum | invalid | invalid | Passed |
| control half-up decimal | ['1.13', '1/8', '88.9'] | ['1.13', '1/8', '88.9'] | Passed |
| regression: implied probability sign | ['1.40', '100/247', '71.2'] | ['1.40', '100/247', '71.2'] | Passed |
| regression: implied probability sign | ['5.91', '491/100', '16.9'] | ['5.91', '491/100', '16.9'] | Passed |
| variant scenario 1 | ['1.22', '50/223', '81.7'] | ['1.22', '50/223', '81.7'] | Passed |
| variant scenario 2 | ['1.16', '25/159', '86.4'] | ['1.16', '25/159', '86.4'] | Passed |
SHA-256 / 56aca2d1b67bf35290c6ee80ec06e43fca85024f2ac338b71d33b1dea6b9794a
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.441185+00:00.
Case digest / 0b1b3abe0a0bb9cbf71fde742fd9931bbe8f0f280b9bb6350724ac36a8bf81ef