FAILURE MAP
← Case archive

FA-61716 / Options payoff and settlement / Open access

FX option premium quote conversion: pip quotes are applied without the pip size · case 01

Pip-quoted premiums are thousands of times too large.

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

ROOT CAUSE

The pip quote is multiplied by notional without the pip size.

VERIFIED REPAIR

Multiply the pip quote by the pair's pip size.

Unsuccessful approach: Hard-coding a pip of 0.0001 is wrong for yen pairs.

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 * 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 pip scaling 1', [0.85, 'pips', 250000, 1.2712, 0.0001], [21.25, 16.72]], ['regression pip scaling 2', [12.5, 'pips', 250000, 1.0845, 0.0001], [312.5, 288.15]], ['partial repair probe 1', [1.25, 'pips', 250000, 149.35, 0.01], [3125.0, 20.92]], ['partial repair probe 2', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['normal control 1', [0.85, 'pct_base', 5000000, 149.35, 0.01], [6347375.0, 42500.0]], ['normal control 2', [110.0, 'pct_base', 5000000, 1.0845, 0.0001], [5964750.0, 5500000.0]], ['normal control 3', [45.0, 'pct_base', 250000, 1.2712, 0.0001], [143010.0, 112500.0]], ['normal control 4', [1.25, 'pct_base', 1000000, 1.2712, 0.0001], [15890.0, 12500.0]]], [['regression pip scaling 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['regression pip scaling 2', [45.0, 'pips', 1000000, 1.2712, 0.0001], [4500.0, 3539.96]], ['partial repair probe 1', [110.0, 'pips', 250000, 149.35, 0.01], [275000.0, 1841.31]], ['partial repair probe 2', [110.0, 'pips', 5000000, 149.35, 0.01], [5500000.0, 36826.25]], ['normal control 1', [110.0, 'pct_term', 5000000, 149.35, 0.01], [821425000.0, 5500000.0]], ['normal control 2', [12.5, 'pct_base', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['normal control 3', [12.5, 'pct_term', 1000000, 1.0845, 0.0001], [135562.5, 125000.0]], ['normal control 4', [45.0, 'pct_term', 1000000, 1.0845, 0.0001], [488025.0, 450000.0]]], [['regression pip scaling 1', [45.0, 'pips', 1000000, 149.35, 0.01], [450000.0, 3013.06]], ['regression pip scaling 2', [110.0, 'pips', 1000000, 149.35, 0.01], [1100000.0, 7365.25]], ['partial repair probe 1', [45.0, 'pips', 250000, 149.35, 0.01], [112500.0, 753.26]], ['partial repair probe 2', [110.0, 'pips', 5000000, 149.35, 0.01], [5500000.0, 36826.25]], ['normal control 1', [12.5, 'pct_base', 1000000, 1.2712, 0.0001], [158900.0, 125000.0]], ['normal control 2', [1.25, 'pct_term', 250000, 1.2712, 0.0001], [3972.5, 3125.0]], ['normal control 3', [110.0, 'pct_term', 1000000, 1.0845, 0.0001], [1192950.0, 1100000.0]], ['normal control 4', [0.85, 'pct_term', 1000000, 1.2712, 0.0001], [10805.2, 8500.0]]], [['regression pip scaling 1', [12.5, 'pips', 250000, 1.2712, 0.0001], [312.5, 245.83]], ['regression pip scaling 2', [0.85, 'pips', 1000000, 149.35, 0.01], [8500.0, 56.91]], ['partial repair probe 1', [12.5, 'pips', 5000000, 149.35, 0.01], [625000.0, 4184.8]], ['partial repair probe 2', [45.0, 'pips', 5000000, 149.35, 0.01], [2250000.0, 15065.28]], ['normal control 1', [0.85, 'pct_base', 5000000, 1.2712, 0.0001], [54026.0, 42500.0]], ['normal control 2', [1.25, 'pct_term', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['normal control 3', [45.0, 'pct_base', 1000000, 149.35, 0.01], [67207500.0, 450000.0]], ['normal control 4', [12.5, 'pct_base', 5000000, 149.35, 0.01], [93343750.0, 625000.0]]], [['regression pip scaling 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['regression pip scaling 2', [1.25, 'pips', 250000, 149.35, 0.01], [3125.0, 20.92]], ['partial repair probe 1', [45.0, 'pips', 250000, 149.35, 0.01], [112500.0, 753.26]], ['partial repair probe 2', [0.85, 'pips', 5000000, 149.35, 0.01], [42500.0, 284.57]], ['normal control 1', [0.85, 'pct_term', 5000000, 1.2712, 0.0001], [54026.0, 42500.0]], ['normal control 2', [45.0, 'pct_term', 1000000, 1.0845, 0.0001], [488025.0, 450000.0]], ['normal control 3', [1.25, 'pct_term', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['normal control 4', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]]]]
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 pip scaling 1[212500.0, 167164.88][21.25, 16.72]Failed
regression pip scaling 2[3125000.0, 2881512.22][312.5, 288.15]Failed
partial repair probe 1[312500.0, 2092.4][3125.0, 20.92]Failed
partial repair probe 2[212500.0, 1422.83][2125.0, 14.23]Failed
normal control 1[6347375.0, 42500.0][6347375.0, 42500.0]Passed
normal control 2[5964750.0, 5500000.0][5964750.0, 5500000.0]Passed
normal control 3[143010.0, 112500.0][143010.0, 112500.0]Passed
normal control 4[15890.0, 12500.0][15890.0, 12500.0]Passed

SHA-256 / fc5b0c8da6170648e4e7b1630efe9035914296aef5ab831b325021944daf0e61

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 * Fraction('0.0001') * 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 pip scaling 1', [0.85, 'pips', 250000, 1.2712, 0.0001], [21.25, 16.72]], ['regression pip scaling 2', [12.5, 'pips', 250000, 1.0845, 0.0001], [312.5, 288.15]], ['partial repair probe 1', [1.25, 'pips', 250000, 149.35, 0.01], [3125.0, 20.92]], ['partial repair probe 2', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['normal control 1', [0.85, 'pct_base', 5000000, 149.35, 0.01], [6347375.0, 42500.0]], ['normal control 2', [110.0, 'pct_base', 5000000, 1.0845, 0.0001], [5964750.0, 5500000.0]], ['normal control 3', [45.0, 'pct_base', 250000, 1.2712, 0.0001], [143010.0, 112500.0]], ['normal control 4', [1.25, 'pct_base', 1000000, 1.2712, 0.0001], [15890.0, 12500.0]]], [['regression pip scaling 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['regression pip scaling 2', [45.0, 'pips', 1000000, 1.2712, 0.0001], [4500.0, 3539.96]], ['partial repair probe 1', [110.0, 'pips', 250000, 149.35, 0.01], [275000.0, 1841.31]], ['partial repair probe 2', [110.0, 'pips', 5000000, 149.35, 0.01], [5500000.0, 36826.25]], ['normal control 1', [110.0, 'pct_term', 5000000, 149.35, 0.01], [821425000.0, 5500000.0]], ['normal control 2', [12.5, 'pct_base', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['normal control 3', [12.5, 'pct_term', 1000000, 1.0845, 0.0001], [135562.5, 125000.0]], ['normal control 4', [45.0, 'pct_term', 1000000, 1.0845, 0.0001], [488025.0, 450000.0]]], [['regression pip scaling 1', [45.0, 'pips', 1000000, 149.35, 0.01], [450000.0, 3013.06]], ['regression pip scaling 2', [110.0, 'pips', 1000000, 149.35, 0.01], [1100000.0, 7365.25]], ['partial repair probe 1', [45.0, 'pips', 250000, 149.35, 0.01], [112500.0, 753.26]], ['partial repair probe 2', [110.0, 'pips', 5000000, 149.35, 0.01], [5500000.0, 36826.25]], ['normal control 1', [12.5, 'pct_base', 1000000, 1.2712, 0.0001], [158900.0, 125000.0]], ['normal control 2', [1.25, 'pct_term', 250000, 1.2712, 0.0001], [3972.5, 3125.0]], ['normal control 3', [110.0, 'pct_term', 1000000, 1.0845, 0.0001], [1192950.0, 1100000.0]], ['normal control 4', [0.85, 'pct_term', 1000000, 1.2712, 0.0001], [10805.2, 8500.0]]], [['regression pip scaling 1', [12.5, 'pips', 250000, 1.2712, 0.0001], [312.5, 245.83]], ['regression pip scaling 2', [0.85, 'pips', 1000000, 149.35, 0.01], [8500.0, 56.91]], ['partial repair probe 1', [12.5, 'pips', 5000000, 149.35, 0.01], [625000.0, 4184.8]], ['partial repair probe 2', [45.0, 'pips', 5000000, 149.35, 0.01], [2250000.0, 15065.28]], ['normal control 1', [0.85, 'pct_base', 5000000, 1.2712, 0.0001], [54026.0, 42500.0]], ['normal control 2', [1.25, 'pct_term', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['normal control 3', [45.0, 'pct_base', 1000000, 149.35, 0.01], [67207500.0, 450000.0]], ['normal control 4', [12.5, 'pct_base', 5000000, 149.35, 0.01], [93343750.0, 625000.0]]], [['regression pip scaling 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['regression pip scaling 2', [1.25, 'pips', 250000, 149.35, 0.01], [3125.0, 20.92]], ['partial repair probe 1', [45.0, 'pips', 250000, 149.35, 0.01], [112500.0, 753.26]], ['partial repair probe 2', [0.85, 'pips', 5000000, 149.35, 0.01], [42500.0, 284.57]], ['normal control 1', [0.85, 'pct_term', 5000000, 1.2712, 0.0001], [54026.0, 42500.0]], ['normal control 2', [45.0, 'pct_term', 1000000, 1.0845, 0.0001], [488025.0, 450000.0]], ['normal control 3', [1.25, 'pct_term', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['normal control 4', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]]]]
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 pip scaling 1[21.25, 16.72][21.25, 16.72]Passed
regression pip scaling 2[312.5, 288.15][312.5, 288.15]Passed
partial repair probe 1[31.25, 0.21][3125.0, 20.92]Failed
partial repair probe 2[21.25, 0.14][2125.0, 14.23]Failed
normal control 1[6347375.0, 42500.0][6347375.0, 42500.0]Passed
normal control 2[5964750.0, 5500000.0][5964750.0, 5500000.0]Passed
normal control 3[143010.0, 112500.0][143010.0, 112500.0]Passed
normal control 4[15890.0, 12500.0][15890.0, 12500.0]Passed

SHA-256 / dbaba026074ab711a4452311a1bcc160871168e1bcf5b5b5c83ac750c2993786

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 pip scaling 1', [0.85, 'pips', 250000, 1.2712, 0.0001], [21.25, 16.72]], ['regression pip scaling 2', [12.5, 'pips', 250000, 1.0845, 0.0001], [312.5, 288.15]], ['partial repair probe 1', [1.25, 'pips', 250000, 149.35, 0.01], [3125.0, 20.92]], ['partial repair probe 2', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['normal control 1', [0.85, 'pct_base', 5000000, 149.35, 0.01], [6347375.0, 42500.0]], ['normal control 2', [110.0, 'pct_base', 5000000, 1.0845, 0.0001], [5964750.0, 5500000.0]], ['normal control 3', [45.0, 'pct_base', 250000, 1.2712, 0.0001], [143010.0, 112500.0]], ['normal control 4', [1.25, 'pct_base', 1000000, 1.2712, 0.0001], [15890.0, 12500.0]]], [['regression pip scaling 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['regression pip scaling 2', [45.0, 'pips', 1000000, 1.2712, 0.0001], [4500.0, 3539.96]], ['partial repair probe 1', [110.0, 'pips', 250000, 149.35, 0.01], [275000.0, 1841.31]], ['partial repair probe 2', [110.0, 'pips', 5000000, 149.35, 0.01], [5500000.0, 36826.25]], ['normal control 1', [110.0, 'pct_term', 5000000, 149.35, 0.01], [821425000.0, 5500000.0]], ['normal control 2', [12.5, 'pct_base', 5000000, 1.0845, 0.0001], [677812.5, 625000.0]], ['normal control 3', [12.5, 'pct_term', 1000000, 1.0845, 0.0001], [135562.5, 125000.0]], ['normal control 4', [45.0, 'pct_term', 1000000, 1.0845, 0.0001], [488025.0, 450000.0]]], [['regression pip scaling 1', [45.0, 'pips', 1000000, 149.35, 0.01], [450000.0, 3013.06]], ['regression pip scaling 2', [110.0, 'pips', 1000000, 149.35, 0.01], [1100000.0, 7365.25]], ['partial repair probe 1', [45.0, 'pips', 250000, 149.35, 0.01], [112500.0, 753.26]], ['partial repair probe 2', [110.0, 'pips', 5000000, 149.35, 0.01], [5500000.0, 36826.25]], ['normal control 1', [12.5, 'pct_base', 1000000, 1.2712, 0.0001], [158900.0, 125000.0]], ['normal control 2', [1.25, 'pct_term', 250000, 1.2712, 0.0001], [3972.5, 3125.0]], ['normal control 3', [110.0, 'pct_term', 1000000, 1.0845, 0.0001], [1192950.0, 1100000.0]], ['normal control 4', [0.85, 'pct_term', 1000000, 1.2712, 0.0001], [10805.2, 8500.0]]], [['regression pip scaling 1', [12.5, 'pips', 250000, 1.2712, 0.0001], [312.5, 245.83]], ['regression pip scaling 2', [0.85, 'pips', 1000000, 149.35, 0.01], [8500.0, 56.91]], ['partial repair probe 1', [12.5, 'pips', 5000000, 149.35, 0.01], [625000.0, 4184.8]], ['partial repair probe 2', [45.0, 'pips', 5000000, 149.35, 0.01], [2250000.0, 15065.28]], ['normal control 1', [0.85, 'pct_base', 5000000, 1.2712, 0.0001], [54026.0, 42500.0]], ['normal control 2', [1.25, 'pct_term', 250000, 1.0845, 0.0001], [3389.06, 3125.0]], ['normal control 3', [45.0, 'pct_base', 1000000, 149.35, 0.01], [67207500.0, 450000.0]], ['normal control 4', [12.5, 'pct_base', 5000000, 149.35, 0.01], [93343750.0, 625000.0]]], [['regression pip scaling 1', [0.85, 'pips', 250000, 149.35, 0.01], [2125.0, 14.23]], ['regression pip scaling 2', [1.25, 'pips', 250000, 149.35, 0.01], [3125.0, 20.92]], ['partial repair probe 1', [45.0, 'pips', 250000, 149.35, 0.01], [112500.0, 753.26]], ['partial repair probe 2', [0.85, 'pips', 5000000, 149.35, 0.01], [42500.0, 284.57]], ['normal control 1', [0.85, 'pct_term', 5000000, 1.2712, 0.0001], [54026.0, 42500.0]], ['normal control 2', [45.0, 'pct_term', 1000000, 1.0845, 0.0001], [488025.0, 450000.0]], ['normal control 3', [1.25, 'pct_term', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]], ['normal control 4', [1.25, 'pct_base', 5000000, 1.2712, 0.0001], [79450.0, 62500.0]]]]
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 pip scaling 1[21.25, 16.72][21.25, 16.72]Passed
regression pip scaling 2[312.5, 288.15][312.5, 288.15]Passed
partial repair probe 1[3125.0, 20.92][3125.0, 20.92]Passed
partial repair probe 2[2125.0, 14.23][2125.0, 14.23]Passed
normal control 1[6347375.0, 42500.0][6347375.0, 42500.0]Passed
normal control 2[5964750.0, 5500000.0][5964750.0, 5500000.0]Passed
normal control 3[143010.0, 112500.0][143010.0, 112500.0]Passed
normal control 4[15890.0, 12500.0][15890.0, 12500.0]Passed

SHA-256 / fa7ab858db71984cd6146af995b5014c821e0a0fbd65da04108c368a4ffb9e17

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

Case digest / 10642fe74ffc01a38285d975831fcaf9041fb91477350b08f629ecbd5ec0f364