FA-61371 / Options payoff and settlement / Open access
Physical delivery on exercise and assignment: the short-side inversion is applied only to calls · case 01
Assigned short puts deliver shares they should receive.
ROOT CAUSE
The inversion for assigned shorts is guarded by kind == C.
VERIFIED REPAIR
Invert the direction for every assigned short position.
Unsuccessful approach: Guarding the inversion by puts instead moves the error to short calls.
Case contract
Inputs kind C/P, strike, signed contracts (+long exercised, -short assigned), deliverable shares per contract and whether exercise happened. Long calls and short puts receive shares and pay strike*shares; long puts and short calls deliver shares and receive strike*shares. Return [share delta, cash delta] (cash in currency, computed in cents); unexercised returns [0, 0.0].
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, contracts, deliverable, exercised):
if not exercised:
return [0, 0.0]
n = abs(contracts) * deliverable
k = round(strike * 100)
direction = 1 if kind == 'C' else -1
if contracts < 0 and kind == 'C':
direction = -direction
shares = direction * n
cash = -direction * n * k
return [shares, cash / 100]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression assignment inversion 1', ['P', 101.25, -3, 100, True], [300, -30375.0]], ['regression assignment inversion 2', ['P', 42.5, -3, 100, True], [300, -12750.0]], ['partial repair probe 1', ['C', 42.5, -3, 150, True], [-450, 19125.0]], ['partial repair probe 2', ['C', 250, -3, 133, True], [-399, 99750.0]], ['boundary control 1', ['C', 50, 1, 100, False], [0, 0.0]], ['boundary control 2', ['C', 50, 1, 100, True], [100, -5000.0]], ['normal control 1', ['C', 250, 1, 100, True], [100, -25000.0]], ['normal control 2', ['P', 42.5, 1, 50, True], [-50, 2125.0]]], [['regression assignment inversion 1', ['P', 250, -1, 133, True], [133, -33250.0]], ['regression assignment inversion 2', ['P', 101.25, -1, 100, True], [100, -10125.0]], ['partial repair probe 1', ['C', 101.25, -3, 150, True], [-450, 45562.5]], ['partial repair probe 2', ['C', 250, -1, 100, True], [-100, 25000.0]], ['boundary control 1', ['C', 50, 1, 100, False], [0, 0.0]], ['boundary control 2', ['C', 50, 1, 100, True], [100, -5000.0]], ['normal control 1', ['C', 10, 5, 100, True], [500, -5000.0]], ['normal control 2', ['C', 101.25, -3, 100, False], [0, 0.0]]], [['regression assignment inversion 1', ['P', 10, -1, 50, True], [50, -500.0]], ['regression assignment inversion 2', ['P', 42.5, -1, 150, True], [150, -6375.0]], ['partial repair probe 1', ['C', 101.25, -1, 150, True], [-150, 15187.5]], ['partial repair probe 2', ['C', 101.25, -1, 50, True], [-50, 5062.5]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['P', 10, 2, 150, True], [-300, 3000.0]], ['normal control 2', ['C', 101.25, 2, 50, False], [0, 0.0]]], [['regression assignment inversion 1', ['P', 42.5, -3, 50, True], [150, -6375.0]], ['regression assignment inversion 2', ['P', 10, -1, 50, True], [50, -500.0]], ['partial repair probe 1', ['C', 42.5, -3, 100, True], [-300, 12750.0]], ['partial repair probe 2', ['C', 250, -1, 150, True], [-150, 37500.0]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['C', 250, 5, 100, True], [500, -125000.0]], ['normal control 2', ['P', 10, 5, 100, True], [-500, 5000.0]]], [['regression assignment inversion 1', ['P', 42.5, -1, 50, True], [50, -2125.0]], ['regression assignment inversion 2', ['P', 10, -1, 150, True], [150, -1500.0]], ['partial repair probe 1', ['C', 101.25, -1, 50, True], [-50, 5062.5]], ['partial repair probe 2', ['C', 42.5, -1, 100, True], [-100, 4250.0]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['C', 250, 2, 133, True], [266, -66500.0]], ['normal control 2', ['C', 10, 5, 100, True], [500, -5000.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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression assignment inversion 1 | [-300, 30375.0] | [300, -30375.0] | Failed |
| regression assignment inversion 2 | [-300, 12750.0] | [300, -12750.0] | Failed |
| partial repair probe 1 | [-450, 19125.0] | [-450, 19125.0] | Passed |
| partial repair probe 2 | [-399, 99750.0] | [-399, 99750.0] | Passed |
| boundary control 1 | [0, 0.0] | [0, 0.0] | Passed |
| boundary control 2 | [100, -5000.0] | [100, -5000.0] | Passed |
| normal control 1 | [100, -25000.0] | [100, -25000.0] | Passed |
| normal control 2 | [-50, 2125.0] | [-50, 2125.0] | Passed |
SHA-256 / f29a1e2218dee9b43a8f7928a29e0caa46f16b2b8db3584418ee060853a99d19
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(kind, strike, contracts, deliverable, exercised):
if not exercised:
return [0, 0.0]
n = abs(contracts) * deliverable
k = round(strike * 100)
direction = 1 if kind == 'C' else -1
if contracts < 0 and kind == 'P':
direction = -direction
shares = direction * n
cash = -direction * n * k
return [shares, cash / 100]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression assignment inversion 1', ['P', 101.25, -3, 100, True], [300, -30375.0]], ['regression assignment inversion 2', ['P', 42.5, -3, 100, True], [300, -12750.0]], ['partial repair probe 1', ['C', 42.5, -3, 150, True], [-450, 19125.0]], ['partial repair probe 2', ['C', 250, -3, 133, True], [-399, 99750.0]], ['boundary control 1', ['C', 50, 1, 100, False], [0, 0.0]], ['boundary control 2', ['C', 50, 1, 100, True], [100, -5000.0]], ['normal control 1', ['C', 250, 1, 100, True], [100, -25000.0]], ['normal control 2', ['P', 42.5, 1, 50, True], [-50, 2125.0]]], [['regression assignment inversion 1', ['P', 250, -1, 133, True], [133, -33250.0]], ['regression assignment inversion 2', ['P', 101.25, -1, 100, True], [100, -10125.0]], ['partial repair probe 1', ['C', 101.25, -3, 150, True], [-450, 45562.5]], ['partial repair probe 2', ['C', 250, -1, 100, True], [-100, 25000.0]], ['boundary control 1', ['C', 50, 1, 100, False], [0, 0.0]], ['boundary control 2', ['C', 50, 1, 100, True], [100, -5000.0]], ['normal control 1', ['C', 10, 5, 100, True], [500, -5000.0]], ['normal control 2', ['C', 101.25, -3, 100, False], [0, 0.0]]], [['regression assignment inversion 1', ['P', 10, -1, 50, True], [50, -500.0]], ['regression assignment inversion 2', ['P', 42.5, -1, 150, True], [150, -6375.0]], ['partial repair probe 1', ['C', 101.25, -1, 150, True], [-150, 15187.5]], ['partial repair probe 2', ['C', 101.25, -1, 50, True], [-50, 5062.5]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['P', 10, 2, 150, True], [-300, 3000.0]], ['normal control 2', ['C', 101.25, 2, 50, False], [0, 0.0]]], [['regression assignment inversion 1', ['P', 42.5, -3, 50, True], [150, -6375.0]], ['regression assignment inversion 2', ['P', 10, -1, 50, True], [50, -500.0]], ['partial repair probe 1', ['C', 42.5, -3, 100, True], [-300, 12750.0]], ['partial repair probe 2', ['C', 250, -1, 150, True], [-150, 37500.0]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['C', 250, 5, 100, True], [500, -125000.0]], ['normal control 2', ['P', 10, 5, 100, True], [-500, 5000.0]]], [['regression assignment inversion 1', ['P', 42.5, -1, 50, True], [50, -2125.0]], ['regression assignment inversion 2', ['P', 10, -1, 150, True], [150, -1500.0]], ['partial repair probe 1', ['C', 101.25, -1, 50, True], [-50, 5062.5]], ['partial repair probe 2', ['C', 42.5, -1, 100, True], [-100, 4250.0]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['C', 250, 2, 133, True], [266, -66500.0]], ['normal control 2', ['C', 10, 5, 100, True], [500, -5000.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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression assignment inversion 1 | [300, -30375.0] | [300, -30375.0] | Passed |
| regression assignment inversion 2 | [300, -12750.0] | [300, -12750.0] | Passed |
| partial repair probe 1 | [450, -19125.0] | [-450, 19125.0] | Failed |
| partial repair probe 2 | [399, -99750.0] | [-399, 99750.0] | Failed |
| boundary control 1 | [0, 0.0] | [0, 0.0] | Passed |
| boundary control 2 | [100, -5000.0] | [100, -5000.0] | Passed |
| normal control 1 | [100, -25000.0] | [100, -25000.0] | Passed |
| normal control 2 | [-50, 2125.0] | [-50, 2125.0] | Passed |
SHA-256 / a99cbbfd98ac3d7525af52d7d87ed5a9c15a1d98824e2daa891313e97f28fce0
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(kind, strike, contracts, deliverable, exercised):
if not exercised:
return [0, 0.0]
n = abs(contracts) * deliverable
k = round(strike * 100)
direction = 1 if kind == 'C' else -1
if contracts < 0:
direction = -direction
shares = direction * n
cash = -direction * n * k
return [shares, cash / 100]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression assignment inversion 1', ['P', 101.25, -3, 100, True], [300, -30375.0]], ['regression assignment inversion 2', ['P', 42.5, -3, 100, True], [300, -12750.0]], ['partial repair probe 1', ['C', 42.5, -3, 150, True], [-450, 19125.0]], ['partial repair probe 2', ['C', 250, -3, 133, True], [-399, 99750.0]], ['boundary control 1', ['C', 50, 1, 100, False], [0, 0.0]], ['boundary control 2', ['C', 50, 1, 100, True], [100, -5000.0]], ['normal control 1', ['C', 250, 1, 100, True], [100, -25000.0]], ['normal control 2', ['P', 42.5, 1, 50, True], [-50, 2125.0]]], [['regression assignment inversion 1', ['P', 250, -1, 133, True], [133, -33250.0]], ['regression assignment inversion 2', ['P', 101.25, -1, 100, True], [100, -10125.0]], ['partial repair probe 1', ['C', 101.25, -3, 150, True], [-450, 45562.5]], ['partial repair probe 2', ['C', 250, -1, 100, True], [-100, 25000.0]], ['boundary control 1', ['C', 50, 1, 100, False], [0, 0.0]], ['boundary control 2', ['C', 50, 1, 100, True], [100, -5000.0]], ['normal control 1', ['C', 10, 5, 100, True], [500, -5000.0]], ['normal control 2', ['C', 101.25, -3, 100, False], [0, 0.0]]], [['regression assignment inversion 1', ['P', 10, -1, 50, True], [50, -500.0]], ['regression assignment inversion 2', ['P', 42.5, -1, 150, True], [150, -6375.0]], ['partial repair probe 1', ['C', 101.25, -1, 150, True], [-150, 15187.5]], ['partial repair probe 2', ['C', 101.25, -1, 50, True], [-50, 5062.5]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['P', 10, 2, 150, True], [-300, 3000.0]], ['normal control 2', ['C', 101.25, 2, 50, False], [0, 0.0]]], [['regression assignment inversion 1', ['P', 42.5, -3, 50, True], [150, -6375.0]], ['regression assignment inversion 2', ['P', 10, -1, 50, True], [50, -500.0]], ['partial repair probe 1', ['C', 42.5, -3, 100, True], [-300, 12750.0]], ['partial repair probe 2', ['C', 250, -1, 150, True], [-150, 37500.0]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['C', 250, 5, 100, True], [500, -125000.0]], ['normal control 2', ['P', 10, 5, 100, True], [-500, 5000.0]]], [['regression assignment inversion 1', ['P', 42.5, -1, 50, True], [50, -2125.0]], ['regression assignment inversion 2', ['P', 10, -1, 150, True], [150, -1500.0]], ['partial repair probe 1', ['C', 101.25, -1, 50, True], [-50, 5062.5]], ['partial repair probe 2', ['C', 42.5, -1, 100, True], [-100, 4250.0]], ['boundary control 1', ['C', 50, 1, 100, True], [100, -5000.0]], ['boundary control 2', ['C', 50, 1, 100, False], [0, 0.0]], ['normal control 1', ['C', 250, 2, 133, True], [266, -66500.0]], ['normal control 2', ['C', 10, 5, 100, True], [500, -5000.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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression assignment inversion 1 | [300, -30375.0] | [300, -30375.0] | Passed |
| regression assignment inversion 2 | [300, -12750.0] | [300, -12750.0] | Passed |
| partial repair probe 1 | [-450, 19125.0] | [-450, 19125.0] | Passed |
| partial repair probe 2 | [-399, 99750.0] | [-399, 99750.0] | Passed |
| boundary control 1 | [0, 0.0] | [0, 0.0] | Passed |
| boundary control 2 | [100, -5000.0] | [100, -5000.0] | Passed |
| normal control 1 | [100, -25000.0] | [100, -25000.0] | Passed |
| normal control 2 | [-50, 2125.0] | [-50, 2125.0] | Passed |
SHA-256 / a92d2c99cb1d3a3511acb3a8761c8d17c722905379f937573e5e91b99381bd8c
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:54.601639+00:00.
Case digest / cc4ce92f3d4573ea05636a8a9936dc4851b50c59301a57b0871d2195d6dfddec