FA-61446 / Options payoff and settlement / Open access
Discretely monitored barrier option payoff: the final observation is excluded from monitoring · case 01
A barrier crossed only at expiry is ignored.
ROOT CAUSE
Monitoring iterates over path[:-1].
VERIFIED REPAIR
Monitor every observation including the final one.
Unsuccessful approach: Excluding the initial observation instead misses barriers breached at inception.
Case contract
Inputs kind (up/down, in/out, call/put), observed path including initial and final price, strike, barrier and rebate. The barrier is hit if any observation is >= barrier (up) or <= barrier (down). Knock-out: rebate if hit else vanilla on the final price. Knock-in: vanilla if hit else rebate. 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, path, strike, barrier, rebate):
up = kind.startswith('up')
hit = any(p >= barrier for p in path[:-1]) if up else any(p <= barrier for p in path[:-1])
final = path[-1]
vanilla = max(final - strike, 0) if kind.endswith('call') else max(strike - final, 0)
if '-out-' in kind:
pay = rebate if hit else vanilla
else:
pay = vanilla if hit else rebate
return round(pay, 6)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression monitoring window 1', ['down-out-put', [100.0, 105.0, 97.65, 97.65, 90.81, 84.45], 105, 90.0, 0.0], 0.0], ['regression monitoring window 2', ['down-out-put', [100.0, 90.0, 85.5, 76.95, 73.1], 100, 73.1, 3.0], 3.0], ['partial repair probe 1', ['down-out-put', [100.0, 105.0, 105.0, 115.5], 100, 100.0, 1.5], 1.5], ['partial repair probe 2', ['up-out-call', [100.0, 93.0, 86.49, 90.81], 100, 100.0, 1.5], 1.5], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 95.0, 88.35], 95, 85.0, 3.0], 6.65], ['normal control 2', ['up-out-put', [100.0, 105.0, 99.75, 109.73, 115.22, 107.15, 96.44, 89.69], 100, 100.0, 1.5], 1.5]], [['regression monitoring window 1', ['up-out-call', [100.0, 110.0, 118.8], 105, 115.0, 1.5], 1.5], ['regression monitoring window 2', ['down-in-put', [100.0, 93.0, 97.65, 92.77, 97.41, 97.41, 92.54, 83.29], 100, 90.0, 1.5], 16.71], ['partial repair probe 1', ['up-out-put', [100.0, 90.0, 85.5, 94.05, 84.64, 88.87, 79.98], 105, 100.0, 3.0], 3.0], ['partial repair probe 2', ['up-in-call', [100.0, 95.0, 90.25, 81.23, 77.17, 77.17], 105, 100.0, 3.0], 0], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-out-put', [100.0, 108.0, 108.0, 113.4, 119.07], 105, 120.0, 3.0], 0], ['normal control 2', ['up-out-call', [100.0, 105.0, 99.75, 92.77, 86.28, 90.59], 105, 110.0, 3.0], 0]], [['regression monitoring window 1', ['up-in-call', [100.0, 110.0, 115.5, 109.72, 120.69], 100, 120.0, 1.5], 20.69], ['regression monitoring window 2', ['down-in-put', [100.0, 93.0, 88.35, 82.17], 95, 85.0, 1.5], 12.83], ['partial repair probe 1', ['down-out-put', [100.0, 105.0, 110.25, 115.76, 127.34, 118.43], 95, 100.0, 3.0], 3.0], ['partial repair probe 2', ['up-out-call', [100.0, 90.0, 90.0, 90.0, 85.5, 85.5, 76.95], 105, 100.0, 1.5], 1.5], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 90.0, 83.7, 79.52, 87.47, 94.47], 100, 80.0, 1.5], 1.5], ['normal control 2', ['up-out-put', [100.0, 110.0, 99.0, 103.95, 109.15, 120.07], 95, 99.0, 3.0], 3.0]], [['regression monitoring window 1', ['up-out-call', [100.0, 93.0, 86.49, 95.14, 102.75, 102.75, 110.97], 105, 110.0, 0.0], 0.0], ['regression monitoring window 2', ['up-in-call', [100.0, 100.0, 90.0, 94.5, 102.06], 105, 102.06, 1.5], 0], ['partial repair probe 1', ['up-in-call', [100.0, 90.0, 85.5, 92.34, 83.11, 87.27, 82.91], 100, 95.0, 3.0], 0], ['partial repair probe 2', ['up-out-put', [100.0, 93.0, 93.0], 95, 95.0, 0.0], 0.0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['boundary control 2', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['normal control 1', ['up-out-call', [100.0, 110.0, 118.8], 100, 110.0, 0.0], 0.0], ['normal control 2', ['down-in-put', [100.0, 100.0, 93.0], 100, 85.0, 3.0], 3.0]], [['regression monitoring window 1', ['down-in-put', [100.0, 105.0, 94.5], 95, 94.5, 3.0], 0.5], ['regression monitoring window 2', ['down-out-put', [100.0, 105.0, 105.0, 110.25, 110.25, 104.74, 94.27, 89.56], 95, 89.56, 3.0], 3.0], ['partial repair probe 1', ['up-out-call', [100.0, 90.0, 81.0, 81.0], 105, 95.0, 1.5], 1.5], ['partial repair probe 2', ['up-in-call', [100.0, 90.0, 97.2, 92.34], 100, 100.0, 1.5], 0], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-in-call', [100.0, 100.0, 110.0, 104.5, 104.5], 95, 80.0, 0.0], 0.0], ['normal control 2', ['down-in-call', [100.0, 110.0, 99.0, 106.92, 99.44, 107.4, 107.4, 115.99], 95, 105.0, 0.0], 20.99]]]
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 monitoring window 1 | 20.55 | 0.0 | Failed |
| regression monitoring window 2 | 26.9 | 3.0 | Failed |
| partial repair probe 1 | 1.5 | 1.5 | Passed |
| partial repair probe 2 | 1.5 | 1.5 | Passed |
| boundary control 1 | 2.0 | 2.0 | Passed |
| boundary control 2 | 1.0 | 1.0 | Passed |
| normal control 1 | 6.65 | 6.65 | Passed |
| normal control 2 | 1.5 | 1.5 | Passed |
SHA-256 / 242c9bc61fa736a2112adcf9fc7742ccd93ad132dec5b68d5a1b87af1ee6be47
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(kind, path, strike, barrier, rebate):
up = kind.startswith('up')
hit = any(p >= barrier for p in path[1:]) if up else any(p <= barrier for p in path[1:])
final = path[-1]
vanilla = max(final - strike, 0) if kind.endswith('call') else max(strike - final, 0)
if '-out-' in kind:
pay = rebate if hit else vanilla
else:
pay = vanilla if hit else rebate
return round(pay, 6)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression monitoring window 1', ['down-out-put', [100.0, 105.0, 97.65, 97.65, 90.81, 84.45], 105, 90.0, 0.0], 0.0], ['regression monitoring window 2', ['down-out-put', [100.0, 90.0, 85.5, 76.95, 73.1], 100, 73.1, 3.0], 3.0], ['partial repair probe 1', ['down-out-put', [100.0, 105.0, 105.0, 115.5], 100, 100.0, 1.5], 1.5], ['partial repair probe 2', ['up-out-call', [100.0, 93.0, 86.49, 90.81], 100, 100.0, 1.5], 1.5], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 95.0, 88.35], 95, 85.0, 3.0], 6.65], ['normal control 2', ['up-out-put', [100.0, 105.0, 99.75, 109.73, 115.22, 107.15, 96.44, 89.69], 100, 100.0, 1.5], 1.5]], [['regression monitoring window 1', ['up-out-call', [100.0, 110.0, 118.8], 105, 115.0, 1.5], 1.5], ['regression monitoring window 2', ['down-in-put', [100.0, 93.0, 97.65, 92.77, 97.41, 97.41, 92.54, 83.29], 100, 90.0, 1.5], 16.71], ['partial repair probe 1', ['up-out-put', [100.0, 90.0, 85.5, 94.05, 84.64, 88.87, 79.98], 105, 100.0, 3.0], 3.0], ['partial repair probe 2', ['up-in-call', [100.0, 95.0, 90.25, 81.23, 77.17, 77.17], 105, 100.0, 3.0], 0], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-out-put', [100.0, 108.0, 108.0, 113.4, 119.07], 105, 120.0, 3.0], 0], ['normal control 2', ['up-out-call', [100.0, 105.0, 99.75, 92.77, 86.28, 90.59], 105, 110.0, 3.0], 0]], [['regression monitoring window 1', ['up-in-call', [100.0, 110.0, 115.5, 109.72, 120.69], 100, 120.0, 1.5], 20.69], ['regression monitoring window 2', ['down-in-put', [100.0, 93.0, 88.35, 82.17], 95, 85.0, 1.5], 12.83], ['partial repair probe 1', ['down-out-put', [100.0, 105.0, 110.25, 115.76, 127.34, 118.43], 95, 100.0, 3.0], 3.0], ['partial repair probe 2', ['up-out-call', [100.0, 90.0, 90.0, 90.0, 85.5, 85.5, 76.95], 105, 100.0, 1.5], 1.5], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 90.0, 83.7, 79.52, 87.47, 94.47], 100, 80.0, 1.5], 1.5], ['normal control 2', ['up-out-put', [100.0, 110.0, 99.0, 103.95, 109.15, 120.07], 95, 99.0, 3.0], 3.0]], [['regression monitoring window 1', ['up-out-call', [100.0, 93.0, 86.49, 95.14, 102.75, 102.75, 110.97], 105, 110.0, 0.0], 0.0], ['regression monitoring window 2', ['up-in-call', [100.0, 100.0, 90.0, 94.5, 102.06], 105, 102.06, 1.5], 0], ['partial repair probe 1', ['up-in-call', [100.0, 90.0, 85.5, 92.34, 83.11, 87.27, 82.91], 100, 95.0, 3.0], 0], ['partial repair probe 2', ['up-out-put', [100.0, 93.0, 93.0], 95, 95.0, 0.0], 0.0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['boundary control 2', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['normal control 1', ['up-out-call', [100.0, 110.0, 118.8], 100, 110.0, 0.0], 0.0], ['normal control 2', ['down-in-put', [100.0, 100.0, 93.0], 100, 85.0, 3.0], 3.0]], [['regression monitoring window 1', ['down-in-put', [100.0, 105.0, 94.5], 95, 94.5, 3.0], 0.5], ['regression monitoring window 2', ['down-out-put', [100.0, 105.0, 105.0, 110.25, 110.25, 104.74, 94.27, 89.56], 95, 89.56, 3.0], 3.0], ['partial repair probe 1', ['up-out-call', [100.0, 90.0, 81.0, 81.0], 105, 95.0, 1.5], 1.5], ['partial repair probe 2', ['up-in-call', [100.0, 90.0, 97.2, 92.34], 100, 100.0, 1.5], 0], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-in-call', [100.0, 100.0, 110.0, 104.5, 104.5], 95, 80.0, 0.0], 0.0], ['normal control 2', ['down-in-call', [100.0, 110.0, 99.0, 106.92, 99.44, 107.4, 107.4, 115.99], 95, 105.0, 0.0], 20.99]]]
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 monitoring window 1 | 0.0 | 0.0 | Passed |
| regression monitoring window 2 | 3.0 | 3.0 | Passed |
| partial repair probe 1 | 0 | 1.5 | Failed |
| partial repair probe 2 | 0 | 1.5 | Failed |
| boundary control 1 | 2.0 | 2.0 | Passed |
| boundary control 2 | 1.0 | 1.0 | Passed |
| normal control 1 | 6.65 | 6.65 | Passed |
| normal control 2 | 1.5 | 1.5 | Passed |
SHA-256 / 73390af321814c06b1f1f9be7d606a5f62b77bdcf6d4109038272d53cc8748a4
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(kind, path, strike, barrier, rebate):
up = kind.startswith('up')
hit = any(p >= barrier for p in path) if up else any(p <= barrier for p in path)
final = path[-1]
vanilla = max(final - strike, 0) if kind.endswith('call') else max(strike - final, 0)
if '-out-' in kind:
pay = rebate if hit else vanilla
else:
pay = vanilla if hit else rebate
return round(pay, 6)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression monitoring window 1', ['down-out-put', [100.0, 105.0, 97.65, 97.65, 90.81, 84.45], 105, 90.0, 0.0], 0.0], ['regression monitoring window 2', ['down-out-put', [100.0, 90.0, 85.5, 76.95, 73.1], 100, 73.1, 3.0], 3.0], ['partial repair probe 1', ['down-out-put', [100.0, 105.0, 105.0, 115.5], 100, 100.0, 1.5], 1.5], ['partial repair probe 2', ['up-out-call', [100.0, 93.0, 86.49, 90.81], 100, 100.0, 1.5], 1.5], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 95.0, 88.35], 95, 85.0, 3.0], 6.65], ['normal control 2', ['up-out-put', [100.0, 105.0, 99.75, 109.73, 115.22, 107.15, 96.44, 89.69], 100, 100.0, 1.5], 1.5]], [['regression monitoring window 1', ['up-out-call', [100.0, 110.0, 118.8], 105, 115.0, 1.5], 1.5], ['regression monitoring window 2', ['down-in-put', [100.0, 93.0, 97.65, 92.77, 97.41, 97.41, 92.54, 83.29], 100, 90.0, 1.5], 16.71], ['partial repair probe 1', ['up-out-put', [100.0, 90.0, 85.5, 94.05, 84.64, 88.87, 79.98], 105, 100.0, 3.0], 3.0], ['partial repair probe 2', ['up-in-call', [100.0, 95.0, 90.25, 81.23, 77.17, 77.17], 105, 100.0, 3.0], 0], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-out-put', [100.0, 108.0, 108.0, 113.4, 119.07], 105, 120.0, 3.0], 0], ['normal control 2', ['up-out-call', [100.0, 105.0, 99.75, 92.77, 86.28, 90.59], 105, 110.0, 3.0], 0]], [['regression monitoring window 1', ['up-in-call', [100.0, 110.0, 115.5, 109.72, 120.69], 100, 120.0, 1.5], 20.69], ['regression monitoring window 2', ['down-in-put', [100.0, 93.0, 88.35, 82.17], 95, 85.0, 1.5], 12.83], ['partial repair probe 1', ['down-out-put', [100.0, 105.0, 110.25, 115.76, 127.34, 118.43], 95, 100.0, 3.0], 3.0], ['partial repair probe 2', ['up-out-call', [100.0, 90.0, 90.0, 90.0, 85.5, 85.5, 76.95], 105, 100.0, 1.5], 1.5], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 90.0, 83.7, 79.52, 87.47, 94.47], 100, 80.0, 1.5], 1.5], ['normal control 2', ['up-out-put', [100.0, 110.0, 99.0, 103.95, 109.15, 120.07], 95, 99.0, 3.0], 3.0]], [['regression monitoring window 1', ['up-out-call', [100.0, 93.0, 86.49, 95.14, 102.75, 102.75, 110.97], 105, 110.0, 0.0], 0.0], ['regression monitoring window 2', ['up-in-call', [100.0, 100.0, 90.0, 94.5, 102.06], 105, 102.06, 1.5], 0], ['partial repair probe 1', ['up-in-call', [100.0, 90.0, 85.5, 92.34, 83.11, 87.27, 82.91], 100, 95.0, 3.0], 0], ['partial repair probe 2', ['up-out-put', [100.0, 93.0, 93.0], 95, 95.0, 0.0], 0.0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['boundary control 2', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['normal control 1', ['up-out-call', [100.0, 110.0, 118.8], 100, 110.0, 0.0], 0.0], ['normal control 2', ['down-in-put', [100.0, 100.0, 93.0], 100, 85.0, 3.0], 3.0]], [['regression monitoring window 1', ['down-in-put', [100.0, 105.0, 94.5], 95, 94.5, 3.0], 0.5], ['regression monitoring window 2', ['down-out-put', [100.0, 105.0, 105.0, 110.25, 110.25, 104.74, 94.27, 89.56], 95, 89.56, 3.0], 3.0], ['partial repair probe 1', ['up-out-call', [100.0, 90.0, 81.0, 81.0], 105, 95.0, 1.5], 1.5], ['partial repair probe 2', ['up-in-call', [100.0, 90.0, 97.2, 92.34], 100, 100.0, 1.5], 0], ['boundary control 1', ['up-out-call', [100.0, 110.0, 105.0], 100, 110.0, 2.0], 2.0], ['boundary control 2', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-in-call', [100.0, 100.0, 110.0, 104.5, 104.5], 95, 80.0, 0.0], 0.0], ['normal control 2', ['down-in-call', [100.0, 110.0, 99.0, 106.92, 99.44, 107.4, 107.4, 115.99], 95, 105.0, 0.0], 20.99]]]
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 monitoring window 1 | 0.0 | 0.0 | Passed |
| regression monitoring window 2 | 3.0 | 3.0 | Passed |
| partial repair probe 1 | 1.5 | 1.5 | Passed |
| partial repair probe 2 | 1.5 | 1.5 | Passed |
| boundary control 1 | 2.0 | 2.0 | Passed |
| boundary control 2 | 1.0 | 1.0 | Passed |
| normal control 1 | 6.65 | 6.65 | Passed |
| normal control 2 | 1.5 | 1.5 | Passed |
SHA-256 / e35f856c4e06fb8000c3e61d45905270e806fc62041bb4bcc88553b432249d87
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.411727+00:00.
Case digest / db90f13e078ffe8a0665eb39a0e00b45c95662dd1585dfcc693892c7f4f82a0b