FA-61441 / Options payoff and settlement / Open access
Discretely monitored barrier option payoff: an observation exactly at the barrier is not a hit · case 01
Paths that touch the barrier level exactly are treated as never touching it.
ROOT CAUSE
Both barrier comparisons are strict.
VERIFIED REPAIR
Treat an observation equal to the barrier as a hit.
Unsuccessful approach: Fixing only the up-barrier comparison leaves down barriers strict.
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) 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 touch inclusivity 1', ['down-in-put', [100.0, 90.0, 90.0, 90.0, 94.5], 95, 90.0, 1.5], 0.5], ['regression touch inclusivity 2', ['up-out-call', [100.0, 90.0, 94.5], 95, 100.0, 1.5], 1.5], ['partial repair probe 1', ['down-in-call', [100.0, 110.0, 115.5, 115.5, 115.5], 105, 100.0, 0.0], 10.5], ['partial repair probe 2', ['down-in-put', [100.0, 93.0, 102.3, 97.18, 87.46, 96.21], 105, 87.46, 0.0], 8.79], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-in-call', [100.0, 105.0, 113.4, 124.74], 105, 113.4, 3.0], 19.74], ['normal control 2', ['down-in-call', [100.0, 105.0, 105.0, 110.25], 100, 80.0, 0.0], 0.0], ['normal control 3', ['up-in-call', [100.0, 100.0, 100.0, 93.0], 105, 115.0, 0.0], 0.0]], [['regression touch inclusivity 1', ['up-out-put', [100.0, 110.0, 104.5, 97.19, 90.39, 84.06, 79.86], 105, 110.0, 1.5], 1.5], ['regression touch inclusivity 2', ['up-out-put', [100.0, 90.0, 99.0, 89.1, 84.64, 76.18, 70.85, 67.31], 105, 100.0, 0.0], 0.0], ['partial repair probe 1', ['down-out-put', [100.0, 90.0, 81.0, 76.95, 71.56, 77.28, 69.55, 73.03], 100, 69.55, 1.5], 1.5], ['partial repair probe 2', ['down-out-put', [100.0, 108.0, 100.44, 110.48, 119.32], 105, 100.0, 1.5], 1.5], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 100.0, 100.0, 90.0, 94.5, 102.06, 112.27, 123.5], 100, 80.0, 1.5], 0], ['normal control 2', ['up-out-call', [100.0, 110.0, 121.0, 130.68], 100, 95.0, 3.0], 3.0], ['normal control 3', ['down-in-put', [100.0, 108.0, 118.8], 95, 80.0, 3.0], 3.0]], [['regression touch inclusivity 1', ['down-in-put', [100.0, 108.0, 116.64, 125.97, 138.57, 124.71], 100, 100.0, 3.0], 0], ['regression touch inclusivity 2', ['down-in-call', [100.0, 105.0, 115.5, 109.72, 98.75, 93.81, 93.81], 95, 93.81, 1.5], 0], ['partial repair probe 1', ['down-in-put', [100.0, 90.0, 83.7, 79.52, 75.54, 75.54], 105, 75.54, 1.5], 29.46], ['partial repair probe 2', ['down-in-put', [100.0, 95.0, 88.35], 95, 88.35, 0.0], 6.65], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 110.0, 115.5, 124.74, 130.98, 117.88], 105, 90.0, 0.0], 0], ['normal control 2', ['up-in-call', [100.0, 95.0, 95.0, 102.6, 97.47, 105.27, 97.9], 105, 115.0, 1.5], 1.5], ['normal control 3', ['up-out-call', [100.0, 93.0, 93.0, 102.3, 107.42], 95, 110.0, 0.0], 12.42]], [['regression touch inclusivity 1', ['up-out-call', [100.0, 110.0, 110.0, 99.0], 105, 110.0, 3.0], 3.0], ['regression touch inclusivity 2', ['up-in-call', [100.0, 90.0, 81.0], 95, 100.0, 3.0], 0], ['partial repair probe 1', ['down-out-put', [100.0, 100.0, 93.0], 95, 93.0, 3.0], 3.0], ['partial repair probe 2', ['down-in-call', [100.0, 90.0, 99.0, 99.0, 99.0, 92.07, 92.07], 105, 90.0, 3.0], 0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-out-call', [100.0, 93.0, 93.0, 83.7, 87.89], 105, 120.0, 1.5], 0], ['normal control 2', ['down-in-call', [100.0, 93.0, 83.7, 83.7, 77.84, 77.84, 72.39], 100, 105.0, 0.0], 0], ['normal control 3', ['down-out-put', [100.0, 100.0, 95.0, 95.0, 88.35], 100, 95.0, 0.0], 0.0]], [['regression touch inclusivity 1', ['down-out-put', [100.0, 93.0, 83.7], 105, 83.7, 3.0], 3.0], ['regression touch inclusivity 2', ['down-in-call', [100.0, 110.0, 121.0], 95, 100.0, 0.0], 26.0], ['partial repair probe 1', ['down-in-put', [100.0, 108.0, 102.6, 112.86, 107.22, 115.8, 125.06], 105, 100.0, 3.0], 0], ['partial repair probe 2', ['down-out-put', [100.0, 90.0, 94.5, 102.06, 102.06, 107.16, 117.88], 95, 90.0, 3.0], 3.0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 90.0, 99.0, 89.1, 89.1], 105, 105.0, 3.0], 3.0], ['normal control 2', ['up-out-call', [100.0, 108.0, 100.44], 100, 100.0, 1.5], 1.5], ['normal control 3', ['up-out-put', [100.0, 90.0, 97.2, 92.34, 85.88, 77.29], 105, 120.0, 3.0], 27.71]]]
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 touch inclusivity 1 | 1.5 | 0.5 | Failed |
| regression touch inclusivity 2 | 0 | 1.5 | Failed |
| partial repair probe 1 | 0.0 | 10.5 | Failed |
| partial repair probe 2 | 0.0 | 8.79 | Failed |
| boundary control 1 | 1.0 | 1.0 | Passed |
| normal control 1 | 19.74 | 19.74 | Passed |
| normal control 2 | 0.0 | 0.0 | Passed |
| normal control 3 | 0.0 | 0.0 | Passed |
SHA-256 / 9354b5346f9841d9687b0dcadc2523166de40f60a529af6aeacf71e084435bfc
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) 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 touch inclusivity 1', ['down-in-put', [100.0, 90.0, 90.0, 90.0, 94.5], 95, 90.0, 1.5], 0.5], ['regression touch inclusivity 2', ['up-out-call', [100.0, 90.0, 94.5], 95, 100.0, 1.5], 1.5], ['partial repair probe 1', ['down-in-call', [100.0, 110.0, 115.5, 115.5, 115.5], 105, 100.0, 0.0], 10.5], ['partial repair probe 2', ['down-in-put', [100.0, 93.0, 102.3, 97.18, 87.46, 96.21], 105, 87.46, 0.0], 8.79], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-in-call', [100.0, 105.0, 113.4, 124.74], 105, 113.4, 3.0], 19.74], ['normal control 2', ['down-in-call', [100.0, 105.0, 105.0, 110.25], 100, 80.0, 0.0], 0.0], ['normal control 3', ['up-in-call', [100.0, 100.0, 100.0, 93.0], 105, 115.0, 0.0], 0.0]], [['regression touch inclusivity 1', ['up-out-put', [100.0, 110.0, 104.5, 97.19, 90.39, 84.06, 79.86], 105, 110.0, 1.5], 1.5], ['regression touch inclusivity 2', ['up-out-put', [100.0, 90.0, 99.0, 89.1, 84.64, 76.18, 70.85, 67.31], 105, 100.0, 0.0], 0.0], ['partial repair probe 1', ['down-out-put', [100.0, 90.0, 81.0, 76.95, 71.56, 77.28, 69.55, 73.03], 100, 69.55, 1.5], 1.5], ['partial repair probe 2', ['down-out-put', [100.0, 108.0, 100.44, 110.48, 119.32], 105, 100.0, 1.5], 1.5], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 100.0, 100.0, 90.0, 94.5, 102.06, 112.27, 123.5], 100, 80.0, 1.5], 0], ['normal control 2', ['up-out-call', [100.0, 110.0, 121.0, 130.68], 100, 95.0, 3.0], 3.0], ['normal control 3', ['down-in-put', [100.0, 108.0, 118.8], 95, 80.0, 3.0], 3.0]], [['regression touch inclusivity 1', ['down-in-put', [100.0, 108.0, 116.64, 125.97, 138.57, 124.71], 100, 100.0, 3.0], 0], ['regression touch inclusivity 2', ['down-in-call', [100.0, 105.0, 115.5, 109.72, 98.75, 93.81, 93.81], 95, 93.81, 1.5], 0], ['partial repair probe 1', ['down-in-put', [100.0, 90.0, 83.7, 79.52, 75.54, 75.54], 105, 75.54, 1.5], 29.46], ['partial repair probe 2', ['down-in-put', [100.0, 95.0, 88.35], 95, 88.35, 0.0], 6.65], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 110.0, 115.5, 124.74, 130.98, 117.88], 105, 90.0, 0.0], 0], ['normal control 2', ['up-in-call', [100.0, 95.0, 95.0, 102.6, 97.47, 105.27, 97.9], 105, 115.0, 1.5], 1.5], ['normal control 3', ['up-out-call', [100.0, 93.0, 93.0, 102.3, 107.42], 95, 110.0, 0.0], 12.42]], [['regression touch inclusivity 1', ['up-out-call', [100.0, 110.0, 110.0, 99.0], 105, 110.0, 3.0], 3.0], ['regression touch inclusivity 2', ['up-in-call', [100.0, 90.0, 81.0], 95, 100.0, 3.0], 0], ['partial repair probe 1', ['down-out-put', [100.0, 100.0, 93.0], 95, 93.0, 3.0], 3.0], ['partial repair probe 2', ['down-in-call', [100.0, 90.0, 99.0, 99.0, 99.0, 92.07, 92.07], 105, 90.0, 3.0], 0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-out-call', [100.0, 93.0, 93.0, 83.7, 87.89], 105, 120.0, 1.5], 0], ['normal control 2', ['down-in-call', [100.0, 93.0, 83.7, 83.7, 77.84, 77.84, 72.39], 100, 105.0, 0.0], 0], ['normal control 3', ['down-out-put', [100.0, 100.0, 95.0, 95.0, 88.35], 100, 95.0, 0.0], 0.0]], [['regression touch inclusivity 1', ['down-out-put', [100.0, 93.0, 83.7], 105, 83.7, 3.0], 3.0], ['regression touch inclusivity 2', ['down-in-call', [100.0, 110.0, 121.0], 95, 100.0, 0.0], 26.0], ['partial repair probe 1', ['down-in-put', [100.0, 108.0, 102.6, 112.86, 107.22, 115.8, 125.06], 105, 100.0, 3.0], 0], ['partial repair probe 2', ['down-out-put', [100.0, 90.0, 94.5, 102.06, 102.06, 107.16, 117.88], 95, 90.0, 3.0], 3.0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 90.0, 99.0, 89.1, 89.1], 105, 105.0, 3.0], 3.0], ['normal control 2', ['up-out-call', [100.0, 108.0, 100.44], 100, 100.0, 1.5], 1.5], ['normal control 3', ['up-out-put', [100.0, 90.0, 97.2, 92.34, 85.88, 77.29], 105, 120.0, 3.0], 27.71]]]
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 touch inclusivity 1 | 1.5 | 0.5 | Failed |
| regression touch inclusivity 2 | 1.5 | 1.5 | Passed |
| partial repair probe 1 | 0.0 | 10.5 | Failed |
| partial repair probe 2 | 0.0 | 8.79 | Failed |
| boundary control 1 | 1.0 | 1.0 | Passed |
| normal control 1 | 19.74 | 19.74 | Passed |
| normal control 2 | 0.0 | 0.0 | Passed |
| normal control 3 | 0.0 | 0.0 | Passed |
SHA-256 / fb52f5b3dc57612878fbd464108e547e27beaccf8cd949a73fa9eb425c307495
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 touch inclusivity 1', ['down-in-put', [100.0, 90.0, 90.0, 90.0, 94.5], 95, 90.0, 1.5], 0.5], ['regression touch inclusivity 2', ['up-out-call', [100.0, 90.0, 94.5], 95, 100.0, 1.5], 1.5], ['partial repair probe 1', ['down-in-call', [100.0, 110.0, 115.5, 115.5, 115.5], 105, 100.0, 0.0], 10.5], ['partial repair probe 2', ['down-in-put', [100.0, 93.0, 102.3, 97.18, 87.46, 96.21], 105, 87.46, 0.0], 8.79], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-in-call', [100.0, 105.0, 113.4, 124.74], 105, 113.4, 3.0], 19.74], ['normal control 2', ['down-in-call', [100.0, 105.0, 105.0, 110.25], 100, 80.0, 0.0], 0.0], ['normal control 3', ['up-in-call', [100.0, 100.0, 100.0, 93.0], 105, 115.0, 0.0], 0.0]], [['regression touch inclusivity 1', ['up-out-put', [100.0, 110.0, 104.5, 97.19, 90.39, 84.06, 79.86], 105, 110.0, 1.5], 1.5], ['regression touch inclusivity 2', ['up-out-put', [100.0, 90.0, 99.0, 89.1, 84.64, 76.18, 70.85, 67.31], 105, 100.0, 0.0], 0.0], ['partial repair probe 1', ['down-out-put', [100.0, 90.0, 81.0, 76.95, 71.56, 77.28, 69.55, 73.03], 100, 69.55, 1.5], 1.5], ['partial repair probe 2', ['down-out-put', [100.0, 108.0, 100.44, 110.48, 119.32], 105, 100.0, 1.5], 1.5], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 100.0, 100.0, 90.0, 94.5, 102.06, 112.27, 123.5], 100, 80.0, 1.5], 0], ['normal control 2', ['up-out-call', [100.0, 110.0, 121.0, 130.68], 100, 95.0, 3.0], 3.0], ['normal control 3', ['down-in-put', [100.0, 108.0, 118.8], 95, 80.0, 3.0], 3.0]], [['regression touch inclusivity 1', ['down-in-put', [100.0, 108.0, 116.64, 125.97, 138.57, 124.71], 100, 100.0, 3.0], 0], ['regression touch inclusivity 2', ['down-in-call', [100.0, 105.0, 115.5, 109.72, 98.75, 93.81, 93.81], 95, 93.81, 1.5], 0], ['partial repair probe 1', ['down-in-put', [100.0, 90.0, 83.7, 79.52, 75.54, 75.54], 105, 75.54, 1.5], 29.46], ['partial repair probe 2', ['down-in-put', [100.0, 95.0, 88.35], 95, 88.35, 0.0], 6.65], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 110.0, 115.5, 124.74, 130.98, 117.88], 105, 90.0, 0.0], 0], ['normal control 2', ['up-in-call', [100.0, 95.0, 95.0, 102.6, 97.47, 105.27, 97.9], 105, 115.0, 1.5], 1.5], ['normal control 3', ['up-out-call', [100.0, 93.0, 93.0, 102.3, 107.42], 95, 110.0, 0.0], 12.42]], [['regression touch inclusivity 1', ['up-out-call', [100.0, 110.0, 110.0, 99.0], 105, 110.0, 3.0], 3.0], ['regression touch inclusivity 2', ['up-in-call', [100.0, 90.0, 81.0], 95, 100.0, 3.0], 0], ['partial repair probe 1', ['down-out-put', [100.0, 100.0, 93.0], 95, 93.0, 3.0], 3.0], ['partial repair probe 2', ['down-in-call', [100.0, 90.0, 99.0, 99.0, 99.0, 92.07, 92.07], 105, 90.0, 3.0], 0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['up-out-call', [100.0, 93.0, 93.0, 83.7, 87.89], 105, 120.0, 1.5], 0], ['normal control 2', ['down-in-call', [100.0, 93.0, 83.7, 83.7, 77.84, 77.84, 72.39], 100, 105.0, 0.0], 0], ['normal control 3', ['down-out-put', [100.0, 100.0, 95.0, 95.0, 88.35], 100, 95.0, 0.0], 0.0]], [['regression touch inclusivity 1', ['down-out-put', [100.0, 93.0, 83.7], 105, 83.7, 3.0], 3.0], ['regression touch inclusivity 2', ['down-in-call', [100.0, 110.0, 121.0], 95, 100.0, 0.0], 26.0], ['partial repair probe 1', ['down-in-put', [100.0, 108.0, 102.6, 112.86, 107.22, 115.8, 125.06], 105, 100.0, 3.0], 0], ['partial repair probe 2', ['down-out-put', [100.0, 90.0, 94.5, 102.06, 102.06, 107.16, 117.88], 95, 90.0, 3.0], 3.0], ['boundary control 1', ['down-in-put', [100.0, 95.0], 100, 90.0, 1.0], 1.0], ['normal control 1', ['down-out-put', [100.0, 90.0, 99.0, 89.1, 89.1], 105, 105.0, 3.0], 3.0], ['normal control 2', ['up-out-call', [100.0, 108.0, 100.44], 100, 100.0, 1.5], 1.5], ['normal control 3', ['up-out-put', [100.0, 90.0, 97.2, 92.34, 85.88, 77.29], 105, 120.0, 3.0], 27.71]]]
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 touch inclusivity 1 | 0.5 | 0.5 | Passed |
| regression touch inclusivity 2 | 1.5 | 1.5 | Passed |
| partial repair probe 1 | 10.5 | 10.5 | Passed |
| partial repair probe 2 | 8.79 | 8.79 | Passed |
| boundary control 1 | 1.0 | 1.0 | Passed |
| normal control 1 | 19.74 | 19.74 | Passed |
| normal control 2 | 0.0 | 0.0 | Passed |
| normal control 3 | 0.0 | 0.0 | Passed |
SHA-256 / e0247e08ec622d09bd24781b1737498a4ae20a555a5c6264ba1052c21ecfa584
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.226537+00:00.
Case digest / f3ecbf06fc738b5cf0ffe3a245c5b4f2cd0a2ce8c3fce3c33b73a62dee98bd27