FAILURE MAP
← Case archive

FA-61731 / Options payoff and settlement / Open access

FX option premium quote conversion: base-percentage premiums are converted to term by dividing by spot · case 01

Term equivalents of base-percent premiums are wrong for any spot other than one.

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

ROOT CAUSE

The pct_base branch divides by spot.

VERIFIED REPAIR

Multiply the base amount by spot.

Unsuccessful approach: Leaving the amount unconverted reports base currency as term currency.

Case contract

Inputs quote, quote type, base notional, spot and pip size. pips: term premium = quote*pip*notional, base = term/spot. pct_base: base = quote/100*notional, term = base*spot. pct_term: term = quote/100*notional*spot, base = term/spot. Exact fractions; return [term, base] rounded to 2 as floats.

Why this case matters

Option expiry, exercise and settlement engines move cash and shares; a wrong branch misstates obligations.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(quote, quote_type, notional, spot, pip):
    q = Fraction(str(quote))
    s = Fraction(str(spot))
    N = Fraction(notional)
    pp = Fraction(str(pip))
    if quote_type == 'pips':
        term = q * pp * N
        base = term / s
    elif quote_type == 'pct_base':
        base = q / 100 * N
        term = base / s
    else:
        term = q / 100 * N * s
        base = term / s
    return [float(round(term, 2)), float(round(base, 2))]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression pct base term conversion 1', [110.0, 'pct_base', 5000000, 1.2712, 0.0001], [6991600.0, 5500000.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 1000000, 1.2712, 0.0001], [158900.0, 125000.0]], ['partial repair probe 1', [110.0, 'pct_base', 250000, 149.35, 0.01], [41071250.0, 275000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 5000000, 1.0845, 0.0001], [425.0, 391.89]], ['normal control 2', [0.85, 'pct_term', 250000, 1.2712, 0.0001], [2701.3, 2125.0]], ['normal control 3', [45.0, 'pips', 1000000, 1.2712, 0.0001], [4500.0, 3539.96]]], [['regression pct base term conversion 1', [45.0, 'pct_base', 1000000, 1.2712, 0.0001], [572040.0, 450000.0]], ['regression pct base term conversion 2', [110.0, 'pct_base', 5000000, 149.35, 0.01], [821425000.0, 5500000.0]], ['partial repair probe 1', [12.5, 'pct_base', 1000000, 1.0845, 0.0001], [135562.5, 125000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [1.25, 'pips', 5000000, 1.2712, 0.0001], [625.0, 491.66]], ['normal control 2', [12.5, 'pct_term', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['normal control 3', [12.5, 'pct_term', 250000, 1.0845, 0.0001], [33890.62, 31250.0]]], [['regression pct base term conversion 1', [1.25, 'pct_base', 1000000, 1.2712, 0.0001], [15890.0, 12500.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 250000, 149.35, 0.01], [4667187.5, 31250.0]], ['partial repair probe 1', [12.5, 'pct_base', 5000000, 1.2712, 0.0001], [794500.0, 625000.0]], ['partial repair probe 2', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [12.5, 'pips', 250000, 1.0845, 0.0001], [312.5, 288.15]], ['normal control 2', [110.0, 'pct_term', 250000, 149.35, 0.01], [41071250.0, 275000.0]], ['normal control 3', [110.0, 'pips', 1000000, 1.2712, 0.0001], [11000.0, 8653.24]]], [['regression pct base term conversion 1', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['regression pct base term conversion 2', [1.25, 'pct_base', 250000, 149.35, 0.01], [466718.75, 3125.0]], ['partial repair probe 1', [110.0, 'pct_base', 1000000, 1.0845, 0.0001], [1192950.0, 1100000.0]], ['partial repair probe 2', [12.5, 'pct_base', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 5000000, 149.35, 0.01], [42500.0, 284.57]], ['normal control 2', [45.0, 'pct_term', 1000000, 1.2712, 0.0001], [572040.0, 450000.0]], ['normal control 3', [0.85, 'pips', 1000000, 1.2712, 0.0001], [85.0, 66.87]]], [['regression pct base term conversion 1', [45.0, 'pct_base', 250000, 1.0845, 0.0001], [122006.25, 112500.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 250000, 149.35, 0.01], [4667187.5, 31250.0]], ['partial repair probe 1', [12.5, 'pct_base', 5000000, 149.35, 0.01], [93343750.0, 625000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 149.35, 0.01], [466718.75, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['normal control 2', [1.25, 'pct_term', 5000000, 149.35, 0.01], [9334375.0, 62500.0]], ['normal control 3', [0.85, 'pips', 250000, 1.2712, 0.0001], [21.25, 16.72]]]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*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
regression pct base term conversion 1[4326620.52, 5500000.0][6991600.0, 5500000.0]Failed
regression pct base term conversion 2[98332.28, 125000.0][158900.0, 125000.0]Failed
partial repair probe 1[1841.31, 275000.0][41071250.0, 275000.0]Failed
partial repair probe 2[2881.51, 3125.0][3389.06, 3125.0]Failed
boundary control 1[1000.0, 909.09][1000.0, 909.09]Passed
normal control 1[425.0, 391.89][425.0, 391.89]Passed
normal control 2[2701.3, 2125.0][2701.3, 2125.0]Passed
normal control 3[4500.0, 3539.96][4500.0, 3539.96]Passed

SHA-256 / d97365127e9ce377b73c6d2816ab2e3ab07c6ce45d98890317962b112eb35f24

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(quote, quote_type, notional, spot, pip):
    q = Fraction(str(quote))
    s = Fraction(str(spot))
    N = Fraction(notional)
    pp = Fraction(str(pip))
    if quote_type == 'pips':
        term = q * pp * N
        base = term / s
    elif quote_type == 'pct_base':
        base = q / 100 * N
        term = base
    else:
        term = q / 100 * N * s
        base = term / s
    return [float(round(term, 2)), float(round(base, 2))]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression pct base term conversion 1', [110.0, 'pct_base', 5000000, 1.2712, 0.0001], [6991600.0, 5500000.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 1000000, 1.2712, 0.0001], [158900.0, 125000.0]], ['partial repair probe 1', [110.0, 'pct_base', 250000, 149.35, 0.01], [41071250.0, 275000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 5000000, 1.0845, 0.0001], [425.0, 391.89]], ['normal control 2', [0.85, 'pct_term', 250000, 1.2712, 0.0001], [2701.3, 2125.0]], ['normal control 3', [45.0, 'pips', 1000000, 1.2712, 0.0001], [4500.0, 3539.96]]], [['regression pct base term conversion 1', [45.0, 'pct_base', 1000000, 1.2712, 0.0001], [572040.0, 450000.0]], ['regression pct base term conversion 2', [110.0, 'pct_base', 5000000, 149.35, 0.01], [821425000.0, 5500000.0]], ['partial repair probe 1', [12.5, 'pct_base', 1000000, 1.0845, 0.0001], [135562.5, 125000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [1.25, 'pips', 5000000, 1.2712, 0.0001], [625.0, 491.66]], ['normal control 2', [12.5, 'pct_term', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['normal control 3', [12.5, 'pct_term', 250000, 1.0845, 0.0001], [33890.62, 31250.0]]], [['regression pct base term conversion 1', [1.25, 'pct_base', 1000000, 1.2712, 0.0001], [15890.0, 12500.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 250000, 149.35, 0.01], [4667187.5, 31250.0]], ['partial repair probe 1', [12.5, 'pct_base', 5000000, 1.2712, 0.0001], [794500.0, 625000.0]], ['partial repair probe 2', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [12.5, 'pips', 250000, 1.0845, 0.0001], [312.5, 288.15]], ['normal control 2', [110.0, 'pct_term', 250000, 149.35, 0.01], [41071250.0, 275000.0]], ['normal control 3', [110.0, 'pips', 1000000, 1.2712, 0.0001], [11000.0, 8653.24]]], [['regression pct base term conversion 1', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['regression pct base term conversion 2', [1.25, 'pct_base', 250000, 149.35, 0.01], [466718.75, 3125.0]], ['partial repair probe 1', [110.0, 'pct_base', 1000000, 1.0845, 0.0001], [1192950.0, 1100000.0]], ['partial repair probe 2', [12.5, 'pct_base', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 5000000, 149.35, 0.01], [42500.0, 284.57]], ['normal control 2', [45.0, 'pct_term', 1000000, 1.2712, 0.0001], [572040.0, 450000.0]], ['normal control 3', [0.85, 'pips', 1000000, 1.2712, 0.0001], [85.0, 66.87]]], [['regression pct base term conversion 1', [45.0, 'pct_base', 250000, 1.0845, 0.0001], [122006.25, 112500.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 250000, 149.35, 0.01], [4667187.5, 31250.0]], ['partial repair probe 1', [12.5, 'pct_base', 5000000, 149.35, 0.01], [93343750.0, 625000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 149.35, 0.01], [466718.75, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['normal control 2', [1.25, 'pct_term', 5000000, 149.35, 0.01], [9334375.0, 62500.0]], ['normal control 3', [0.85, 'pips', 250000, 1.2712, 0.0001], [21.25, 16.72]]]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*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
regression pct base term conversion 1[5500000.0, 5500000.0][6991600.0, 5500000.0]Failed
regression pct base term conversion 2[125000.0, 125000.0][158900.0, 125000.0]Failed
partial repair probe 1[275000.0, 275000.0][41071250.0, 275000.0]Failed
partial repair probe 2[3125.0, 3125.0][3389.06, 3125.0]Failed
boundary control 1[1000.0, 909.09][1000.0, 909.09]Passed
normal control 1[425.0, 391.89][425.0, 391.89]Passed
normal control 2[2701.3, 2125.0][2701.3, 2125.0]Passed
normal control 3[4500.0, 3539.96][4500.0, 3539.96]Passed

SHA-256 / 09f38f6e650b6bf04811483418d58d8f297b7c7d438792a01c7356ed49382205

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(quote, quote_type, notional, spot, pip):
    q = Fraction(str(quote))
    s = Fraction(str(spot))
    N = Fraction(notional)
    pp = Fraction(str(pip))
    if quote_type == 'pips':
        term = q * pp * N
        base = term / s
    elif quote_type == 'pct_base':
        base = q / 100 * N
        term = base * s
    else:
        term = q / 100 * N * s
        base = term / s
    return [float(round(term, 2)), float(round(base, 2))]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression pct base term conversion 1', [110.0, 'pct_base', 5000000, 1.2712, 0.0001], [6991600.0, 5500000.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 1000000, 1.2712, 0.0001], [158900.0, 125000.0]], ['partial repair probe 1', [110.0, 'pct_base', 250000, 149.35, 0.01], [41071250.0, 275000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 5000000, 1.0845, 0.0001], [425.0, 391.89]], ['normal control 2', [0.85, 'pct_term', 250000, 1.2712, 0.0001], [2701.3, 2125.0]], ['normal control 3', [45.0, 'pips', 1000000, 1.2712, 0.0001], [4500.0, 3539.96]]], [['regression pct base term conversion 1', [45.0, 'pct_base', 1000000, 1.2712, 0.0001], [572040.0, 450000.0]], ['regression pct base term conversion 2', [110.0, 'pct_base', 5000000, 149.35, 0.01], [821425000.0, 5500000.0]], ['partial repair probe 1', [12.5, 'pct_base', 1000000, 1.0845, 0.0001], [135562.5, 125000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [1.25, 'pips', 5000000, 1.2712, 0.0001], [625.0, 491.66]], ['normal control 2', [12.5, 'pct_term', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['normal control 3', [12.5, 'pct_term', 250000, 1.0845, 0.0001], [33890.62, 31250.0]]], [['regression pct base term conversion 1', [1.25, 'pct_base', 1000000, 1.2712, 0.0001], [15890.0, 12500.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 250000, 149.35, 0.01], [4667187.5, 31250.0]], ['partial repair probe 1', [12.5, 'pct_base', 5000000, 1.2712, 0.0001], [794500.0, 625000.0]], ['partial repair probe 2', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [12.5, 'pips', 250000, 1.0845, 0.0001], [312.5, 288.15]], ['normal control 2', [110.0, 'pct_term', 250000, 149.35, 0.01], [41071250.0, 275000.0]], ['normal control 3', [110.0, 'pips', 1000000, 1.2712, 0.0001], [11000.0, 8653.24]]], [['regression pct base term conversion 1', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['regression pct base term conversion 2', [1.25, 'pct_base', 250000, 149.35, 0.01], [466718.75, 3125.0]], ['partial repair probe 1', [110.0, 'pct_base', 1000000, 1.0845, 0.0001], [1192950.0, 1100000.0]], ['partial repair probe 2', [12.5, 'pct_base', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 5000000, 149.35, 0.01], [42500.0, 284.57]], ['normal control 2', [45.0, 'pct_term', 1000000, 1.2712, 0.0001], [572040.0, 450000.0]], ['normal control 3', [0.85, 'pips', 1000000, 1.2712, 0.0001], [85.0, 66.87]]], [['regression pct base term conversion 1', [45.0, 'pct_base', 250000, 1.0845, 0.0001], [122006.25, 112500.0]], ['regression pct base term conversion 2', [12.5, 'pct_base', 250000, 149.35, 0.01], [4667187.5, 31250.0]], ['partial repair probe 1', [12.5, 'pct_base', 5000000, 149.35, 0.01], [93343750.0, 625000.0]], ['partial repair probe 2', [1.25, 'pct_base', 250000, 149.35, 0.01], [466718.75, 3125.0]], ['boundary control 1', [10.0, 'pips', 1000000, 1.1, 0.0001], [1000.0, 909.09]], ['normal control 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['normal control 2', [1.25, 'pct_term', 5000000, 149.35, 0.01], [9334375.0, 62500.0]], ['normal control 3', [0.85, 'pips', 250000, 1.2712, 0.0001], [21.25, 16.72]]]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*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
regression pct base term conversion 1[6991600.0, 5500000.0][6991600.0, 5500000.0]Passed
regression pct base term conversion 2[158900.0, 125000.0][158900.0, 125000.0]Passed
partial repair probe 1[41071250.0, 275000.0][41071250.0, 275000.0]Passed
partial repair probe 2[3389.06, 3125.0][3389.06, 3125.0]Passed
boundary control 1[1000.0, 909.09][1000.0, 909.09]Passed
normal control 1[425.0, 391.89][425.0, 391.89]Passed
normal control 2[2701.3, 2125.0][2701.3, 2125.0]Passed
normal control 3[4500.0, 3539.96][4500.0, 3539.96]Passed

SHA-256 / cbe0b4eb0186c3e02123b703232e1ee350c0bf302218969dc05686c694b0fb7b

Verification & scope

A deterministic toy contract stated explicitly in the contract field; no claim of conformance to any exchange or clearing rulebook. 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:46:58.040124+00:00.

Case digest / 4c42f53765b3424a7ee2218afb3cc582e76e1fe17cfed483b14e2e32a57a4ebc