FAILURE MAP
← Case archive

FA-61476 / Options payoff and settlement / Open access

Binary option settlement with an at-strike rule: asset-or-nothing pays the strike · case 01

Asset-or-nothing payouts equal the strike instead of the underlying value.

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

ROOT CAUSE

The payout unit for asset digitals is the strike.

VERIFIED REPAIR

Pay the final underlying price for asset-or-nothing.

Unsuccessful approach: Paying final minus strike turns the digital into a vanilla payoff.

Case contract

Inputs kind (cash-call, cash-put, asset-call, asset-put), strike, final price and cash amount. Calls are in the money when final > strike, puts when final < strike; at final == strike both pay half. Cash-or-nothing pays the cash amount, asset-or-nothing pays the final price, times the state (1, 0.5 or 0). Round to 6.

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

N = 1
observations = []
def solve(kind, strike, final, cash_amount):
    if kind.split('-')[1] == 'call':
        state = 1 if final > strike else (0.5 if final == strike else 0)
    else:
        state = 1 if final < strike else (0.5 if final == strike else 0)
    unit = cash_amount if kind.startswith('cash') else strike
    return round(unit * state, 6)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression asset-or-nothing unit 1', ['asset-call', 100, 107, 100], 107], ['regression asset-or-nothing unit 2', ['asset-put', 100, 99.5, 1000], 99.5], ['partial repair probe 1', ['asset-put', 100, 100, 1000], 50.0], ['partial repair probe 2', ['asset-put', 100, 100, 100], 50.0], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['asset-put', 100, 100.5, 1000], 0.0], ['normal control 2', ['cash-call', 95, 95, 1000], 500.0], ['normal control 3', ['cash-call', 100, 99.5, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-put', 105, 104.5, 1000], 104.5], ['regression asset-or-nothing unit 2', ['asset-put', 95, 94.5, 1000], 94.5], ['partial repair probe 1', ['asset-put', 95, 95, 100], 47.5], ['partial repair probe 2', ['asset-call', 95, 95, 1000], 47.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-put', 100, 88, 100], 100], ['normal control 2', ['cash-put', 100, 100.5, 100], 0], ['normal control 3', ['asset-put', 95, 102, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-put', 105, 93, 100], 93], ['regression asset-or-nothing unit 2', ['asset-put', 105, 104.5, 1000], 104.5], ['partial repair probe 1', ['asset-put', 95, 95, 1000], 47.5], ['partial repair probe 2', ['asset-call', 95, 95, 1000], 47.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-call', 95, 95.5, 100], 100], ['normal control 2', ['cash-put', 100, 88, 10], 10], ['normal control 3', ['cash-put', 100, 107, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-call', 95, 95.5, 10], 95.5], ['regression asset-or-nothing unit 2', ['asset-put', 105, 93, 1000], 93], ['partial repair probe 1', ['asset-call', 105, 105, 10], 52.5], ['partial repair probe 2', ['asset-put', 100, 100, 1000], 50.0], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-put', 105, 104.5, 1000], 1000], ['normal control 2', ['cash-put', 95, 102, 1000], 0], ['normal control 3', ['asset-call', 95, 83, 1000], 0]], [['regression asset-or-nothing unit 1', ['asset-call', 95, 95.5, 10], 95.5], ['regression asset-or-nothing unit 2', ['asset-call', 100, 107, 1000], 107], ['partial repair probe 1', ['asset-call', 105, 105, 100], 52.5], ['partial repair probe 2', ['asset-call', 105, 105, 1000], 52.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-call', 95, 95.5, 10], 10], ['normal control 2', ['cash-put', 95, 83, 10], 10], ['normal control 3', ['asset-call', 105, 104.5, 10], 0.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 asset-or-nothing unit 1100107Failed
regression asset-or-nothing unit 210099.5Failed
partial repair probe 150.050.0Passed
partial repair probe 250.050.0Passed
boundary control 15.05.0Passed
normal control 100.0Passed
normal control 2500.0500.0Passed
normal control 300Passed

SHA-256 / 1541ba4207762cde2e081315cb44df84370071f7ebdb1650993dbbc1626fa3d9

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(kind, strike, final, cash_amount):
    if kind.split('-')[1] == 'call':
        state = 1 if final > strike else (0.5 if final == strike else 0)
    else:
        state = 1 if final < strike else (0.5 if final == strike else 0)
    unit = cash_amount if kind.startswith('cash') else final - strike
    return round(unit * state, 6)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression asset-or-nothing unit 1', ['asset-call', 100, 107, 100], 107], ['regression asset-or-nothing unit 2', ['asset-put', 100, 99.5, 1000], 99.5], ['partial repair probe 1', ['asset-put', 100, 100, 1000], 50.0], ['partial repair probe 2', ['asset-put', 100, 100, 100], 50.0], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['asset-put', 100, 100.5, 1000], 0.0], ['normal control 2', ['cash-call', 95, 95, 1000], 500.0], ['normal control 3', ['cash-call', 100, 99.5, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-put', 105, 104.5, 1000], 104.5], ['regression asset-or-nothing unit 2', ['asset-put', 95, 94.5, 1000], 94.5], ['partial repair probe 1', ['asset-put', 95, 95, 100], 47.5], ['partial repair probe 2', ['asset-call', 95, 95, 1000], 47.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-put', 100, 88, 100], 100], ['normal control 2', ['cash-put', 100, 100.5, 100], 0], ['normal control 3', ['asset-put', 95, 102, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-put', 105, 93, 100], 93], ['regression asset-or-nothing unit 2', ['asset-put', 105, 104.5, 1000], 104.5], ['partial repair probe 1', ['asset-put', 95, 95, 1000], 47.5], ['partial repair probe 2', ['asset-call', 95, 95, 1000], 47.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-call', 95, 95.5, 100], 100], ['normal control 2', ['cash-put', 100, 88, 10], 10], ['normal control 3', ['cash-put', 100, 107, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-call', 95, 95.5, 10], 95.5], ['regression asset-or-nothing unit 2', ['asset-put', 105, 93, 1000], 93], ['partial repair probe 1', ['asset-call', 105, 105, 10], 52.5], ['partial repair probe 2', ['asset-put', 100, 100, 1000], 50.0], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-put', 105, 104.5, 1000], 1000], ['normal control 2', ['cash-put', 95, 102, 1000], 0], ['normal control 3', ['asset-call', 95, 83, 1000], 0]], [['regression asset-or-nothing unit 1', ['asset-call', 95, 95.5, 10], 95.5], ['regression asset-or-nothing unit 2', ['asset-call', 100, 107, 1000], 107], ['partial repair probe 1', ['asset-call', 105, 105, 100], 52.5], ['partial repair probe 2', ['asset-call', 105, 105, 1000], 52.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-call', 95, 95.5, 10], 10], ['normal control 2', ['cash-put', 95, 83, 10], 10], ['normal control 3', ['asset-call', 105, 104.5, 10], 0.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 asset-or-nothing unit 17107Failed
regression asset-or-nothing unit 2-0.599.5Failed
partial repair probe 10.050.0Failed
partial repair probe 20.050.0Failed
boundary control 15.05.0Passed
normal control 10.00.0Passed
normal control 2500.0500.0Passed
normal control 300Passed

SHA-256 / 5f27cc87a596d7b78c16c9e7b371dfae8954f0b46cefc3881a6f66403db6c4de

3 / The verified repair

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

N = 1
observations = []
def solve(kind, strike, final, cash_amount):
    if kind.split('-')[1] == 'call':
        state = 1 if final > strike else (0.5 if final == strike else 0)
    else:
        state = 1 if final < strike else (0.5 if final == strike else 0)
    unit = cash_amount if kind.startswith('cash') else final
    return round(unit * state, 6)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression asset-or-nothing unit 1', ['asset-call', 100, 107, 100], 107], ['regression asset-or-nothing unit 2', ['asset-put', 100, 99.5, 1000], 99.5], ['partial repair probe 1', ['asset-put', 100, 100, 1000], 50.0], ['partial repair probe 2', ['asset-put', 100, 100, 100], 50.0], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['asset-put', 100, 100.5, 1000], 0.0], ['normal control 2', ['cash-call', 95, 95, 1000], 500.0], ['normal control 3', ['cash-call', 100, 99.5, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-put', 105, 104.5, 1000], 104.5], ['regression asset-or-nothing unit 2', ['asset-put', 95, 94.5, 1000], 94.5], ['partial repair probe 1', ['asset-put', 95, 95, 100], 47.5], ['partial repair probe 2', ['asset-call', 95, 95, 1000], 47.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-put', 100, 88, 100], 100], ['normal control 2', ['cash-put', 100, 100.5, 100], 0], ['normal control 3', ['asset-put', 95, 102, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-put', 105, 93, 100], 93], ['regression asset-or-nothing unit 2', ['asset-put', 105, 104.5, 1000], 104.5], ['partial repair probe 1', ['asset-put', 95, 95, 1000], 47.5], ['partial repair probe 2', ['asset-call', 95, 95, 1000], 47.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-call', 95, 95.5, 100], 100], ['normal control 2', ['cash-put', 100, 88, 10], 10], ['normal control 3', ['cash-put', 100, 107, 100], 0]], [['regression asset-or-nothing unit 1', ['asset-call', 95, 95.5, 10], 95.5], ['regression asset-or-nothing unit 2', ['asset-put', 105, 93, 1000], 93], ['partial repair probe 1', ['asset-call', 105, 105, 10], 52.5], ['partial repair probe 2', ['asset-put', 100, 100, 1000], 50.0], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-put', 105, 104.5, 1000], 1000], ['normal control 2', ['cash-put', 95, 102, 1000], 0], ['normal control 3', ['asset-call', 95, 83, 1000], 0]], [['regression asset-or-nothing unit 1', ['asset-call', 95, 95.5, 10], 95.5], ['regression asset-or-nothing unit 2', ['asset-call', 100, 107, 1000], 107], ['partial repair probe 1', ['asset-call', 105, 105, 100], 52.5], ['partial repair probe 2', ['asset-call', 105, 105, 1000], 52.5], ['boundary control 1', ['cash-call', 100, 100, 10], 5.0], ['normal control 1', ['cash-call', 95, 95.5, 10], 10], ['normal control 2', ['cash-put', 95, 83, 10], 10], ['normal control 3', ['asset-call', 105, 104.5, 10], 0.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 asset-or-nothing unit 1107107Passed
regression asset-or-nothing unit 299.599.5Passed
partial repair probe 150.050.0Passed
partial repair probe 250.050.0Passed
boundary control 15.05.0Passed
normal control 10.00.0Passed
normal control 2500.0500.0Passed
normal control 300Passed

SHA-256 / e29a236a15225c3ace3739fd3a2be735020cc8a1364a42bc30e59e60b87c6419

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

Case digest / fca099b60e3f7d160d69154c4d48c17ecdded9687ac70422c752d1b3bd0a3d59