FA-61551 / Options payoff and settlement / Open access
European option value with continuous dividend yield: the call leaves the spot term undiscounted for dividends · case 01
Calls on dividend payers are overpriced.
ROOT CAUSE
The call formula uses S*N(d1) without e^{-qT}.
VERIFIED REPAIR
Discount the spot leg by e^{-qT}.
Unsuccessful approach: Discounting the spot leg at the interest rate confuses the carry.
Case contract
Inputs kind, spot S, strike K, rate r, dividend yield q, volatility sigma and calendar days to expiry. T = days/365. At days == 0 return intrinsic value. Otherwise d1 = (ln(S/K) + (r - q + sigma^2/2)T)/(sigma sqrt T), d2 = d1 - sigma sqrt T, call = S e^{-qT} N(d1) - K e^{-rT} N(d2), put = K e^{-rT} N(-d2) - S e^{-qT} N(-d1). 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
import math
N = 1
observations = []
def solve(kind, S, K, r, q, sigma, days):
def N(x):
return 0.5 * (1 + math.erf(x / math.sqrt(2)))
T = days / 365
if days == 0:
return round(max(S - K, 0.0) if kind == 'C' else max(K - S, 0.0), 6)
d1 = (math.log(S / K) + (r - q + 0.5 * sigma ** 2) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
if kind == 'C':
v = S * N(d1) - K * math.exp(-r * T) * N(d2)
else:
v = K * math.exp(-r * T) * N(-d2) - S * math.exp(-q * T) * N(-d1)
return round(v, 6)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression call spot discounting 1', ['C', 110.0, 105.0, 0.0, 0.015, 0.35, 91], 9.987818], ['regression call spot discounting 2', ['C', 110.0, 100.0, 0.02, 0.03, 0.2, 30], 10.017783], ['partial repair probe 1', ['C', 100.0, 105.0, 0.05, 0.0, 0.1, 730], 8.348306], ['partial repair probe 2', ['C', 100.0, 95.0, 0.02, 0.0, 0.1, 365], 8.228981], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 100.0, 105.0, 0.0, 0.0, 0.2, 7], 5.044601], ['normal control 2', ['P', 110.0, 100.0, 0.02, 0.015, 0.2, 0], 0.0]], [['regression call spot discounting 1', ['C', 110.0, 105.0, 0.0, 0.015, 0.35, 7], 5.441716], ['regression call spot discounting 2', ['C', 110.0, 95.0, 0.0, 0.015, 0.1, 182], 14.246408], ['partial repair probe 1', ['C', 90.0, 100.0, 0.05, 0.0, 0.2, 7], 5.1e-05], ['partial repair probe 2', ['C', 90.0, 95.0, 0.02, 0.0, 0.35, 182], 7.16504], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 90.0, 100.0, 0.0, 0.03, 0.1, 1], 10.007397], ['normal control 2', ['P', 100.0, 100.0, 0.0, 0.0, 0.2, 1], 0.41763]], [['regression call spot discounting 1', ['C', 110.0, 105.0, 0.05, 0.015, 0.1, 91], 6.250733], ['regression call spot discounting 2', ['C', 110.0, 100.0, 0.0, 0.03, 0.35, 365], 17.981981], ['partial repair probe 1', ['C', 110.0, 95.0, 0.05, 0.0, 0.2, 730], 26.930371], ['partial repair probe 2', ['C', 110.0, 95.0, 0.05, 0.0, 0.1, 91], 16.177886], ['boundary control 1', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 110.0, 100.0, 0.05, 0.0, 0.1, 0], 0.0], ['normal control 2', ['P', 90.0, 95.0, 0.0, 0.0, 0.2, 0], 5.0]], [['regression call spot discounting 1', ['C', 90.0, 95.0, 0.02, 0.015, 0.1, 730], 3.308995], ['regression call spot discounting 2', ['C', 110.0, 95.0, 0.05, 0.03, 0.1, 730], 18.216377], ['partial repair probe 1', ['C', 90.0, 100.0, 0.05, 0.0, 0.35, 730], 17.398625], ['partial repair probe 2', ['C', 110.0, 105.0, 0.02, 0.0, 0.2, 365], 12.482761], ['boundary control 1', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 100.0, 95.0, 0.02, 0.0, 0.2, 0], 0.0], ['normal control 2', ['P', 110.0, 105.0, 0.02, 0.015, 0.1, 1], 0.0]], [['regression call spot discounting 1', ['C', 100.0, 105.0, 0.02, 0.015, 0.1, 7], 7.8e-05], ['regression call spot discounting 2', ['C', 90.0, 100.0, 0.02, 0.015, 0.35, 7], 0.02433], ['partial repair probe 1', ['C', 100.0, 105.0, 0.02, 0.0, 0.2, 7], 0.04615], ['partial repair probe 2', ['C', 110.0, 105.0, 0.02, 0.0, 0.1, 182], 6.949255], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['C', 100.0, 100.0, 0.02, 0.015, 0.1, 0], 0.0], ['normal control 2', ['P', 110.0, 105.0, 0.05, 0.015, 0.2, 91], 1.934882]]]
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 call spot discounting 1 | 10.246547 | 9.987818 | Failed |
| regression call spot discounting 2 | 10.276 | 10.017783 | Failed |
| partial repair probe 1 | 8.348306 | 8.348306 | Passed |
| partial repair probe 2 | 8.228981 | 8.228981 | Passed |
| boundary control 1 | 10.0 | 10.0 | Passed |
| boundary control 2 | 10.0 | 10.0 | Passed |
| normal control 1 | 5.044601 | 5.044601 | Passed |
| normal control 2 | 0.0 | 0.0 | Passed |
SHA-256 / c256e0b9426ba9ed2cba234aad3c7a225019a4f99efa6d068270a35846fad820
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(kind, S, K, r, q, sigma, days):
def N(x):
return 0.5 * (1 + math.erf(x / math.sqrt(2)))
T = days / 365
if days == 0:
return round(max(S - K, 0.0) if kind == 'C' else max(K - S, 0.0), 6)
d1 = (math.log(S / K) + (r - q + 0.5 * sigma ** 2) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
if kind == 'C':
v = S * math.exp(-r * T) * N(d1) - K * math.exp(-r * T) * N(d2)
else:
v = K * math.exp(-r * T) * N(-d2) - S * math.exp(-q * T) * N(-d1)
return round(v, 6)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression call spot discounting 1', ['C', 110.0, 105.0, 0.0, 0.015, 0.35, 91], 9.987818], ['regression call spot discounting 2', ['C', 110.0, 100.0, 0.02, 0.03, 0.2, 30], 10.017783], ['partial repair probe 1', ['C', 100.0, 105.0, 0.05, 0.0, 0.1, 730], 8.348306], ['partial repair probe 2', ['C', 100.0, 95.0, 0.02, 0.0, 0.1, 365], 8.228981], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 100.0, 105.0, 0.0, 0.0, 0.2, 7], 5.044601], ['normal control 2', ['P', 110.0, 100.0, 0.02, 0.015, 0.2, 0], 0.0]], [['regression call spot discounting 1', ['C', 110.0, 105.0, 0.0, 0.015, 0.35, 7], 5.441716], ['regression call spot discounting 2', ['C', 110.0, 95.0, 0.0, 0.015, 0.1, 182], 14.246408], ['partial repair probe 1', ['C', 90.0, 100.0, 0.05, 0.0, 0.2, 7], 5.1e-05], ['partial repair probe 2', ['C', 90.0, 95.0, 0.02, 0.0, 0.35, 182], 7.16504], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 90.0, 100.0, 0.0, 0.03, 0.1, 1], 10.007397], ['normal control 2', ['P', 100.0, 100.0, 0.0, 0.0, 0.2, 1], 0.41763]], [['regression call spot discounting 1', ['C', 110.0, 105.0, 0.05, 0.015, 0.1, 91], 6.250733], ['regression call spot discounting 2', ['C', 110.0, 100.0, 0.0, 0.03, 0.35, 365], 17.981981], ['partial repair probe 1', ['C', 110.0, 95.0, 0.05, 0.0, 0.2, 730], 26.930371], ['partial repair probe 2', ['C', 110.0, 95.0, 0.05, 0.0, 0.1, 91], 16.177886], ['boundary control 1', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 110.0, 100.0, 0.05, 0.0, 0.1, 0], 0.0], ['normal control 2', ['P', 90.0, 95.0, 0.0, 0.0, 0.2, 0], 5.0]], [['regression call spot discounting 1', ['C', 90.0, 95.0, 0.02, 0.015, 0.1, 730], 3.308995], ['regression call spot discounting 2', ['C', 110.0, 95.0, 0.05, 0.03, 0.1, 730], 18.216377], ['partial repair probe 1', ['C', 90.0, 100.0, 0.05, 0.0, 0.35, 730], 17.398625], ['partial repair probe 2', ['C', 110.0, 105.0, 0.02, 0.0, 0.2, 365], 12.482761], ['boundary control 1', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 100.0, 95.0, 0.02, 0.0, 0.2, 0], 0.0], ['normal control 2', ['P', 110.0, 105.0, 0.02, 0.015, 0.1, 1], 0.0]], [['regression call spot discounting 1', ['C', 100.0, 105.0, 0.02, 0.015, 0.1, 7], 7.8e-05], ['regression call spot discounting 2', ['C', 90.0, 100.0, 0.02, 0.015, 0.35, 7], 0.02433], ['partial repair probe 1', ['C', 100.0, 105.0, 0.02, 0.0, 0.2, 7], 0.04615], ['partial repair probe 2', ['C', 110.0, 105.0, 0.02, 0.0, 0.1, 182], 6.949255], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['C', 100.0, 100.0, 0.02, 0.015, 0.1, 0], 0.0], ['normal control 2', ['P', 110.0, 105.0, 0.05, 0.015, 0.2, 91], 1.934882]]]
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 call spot discounting 1 | 10.246547 | 9.987818 | Failed |
| regression call spot discounting 2 | 10.103785 | 10.017783 | Failed |
| partial repair probe 1 | 1.9969 | 8.348306 | Failed |
| partial repair probe 2 | 6.689926 | 8.228981 | Failed |
| boundary control 1 | 10.0 | 10.0 | Passed |
| boundary control 2 | 10.0 | 10.0 | Passed |
| normal control 1 | 5.044601 | 5.044601 | Passed |
| normal control 2 | 0.0 | 0.0 | Passed |
SHA-256 / f7c806a5fb21e7c321d24b52fc5cbd34e476c23e4a8cf711dd5acc6462385249
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(kind, S, K, r, q, sigma, days):
def N(x):
return 0.5 * (1 + math.erf(x / math.sqrt(2)))
T = days / 365
if days == 0:
return round(max(S - K, 0.0) if kind == 'C' else max(K - S, 0.0), 6)
d1 = (math.log(S / K) + (r - q + 0.5 * sigma ** 2) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
if kind == 'C':
v = S * math.exp(-q * T) * N(d1) - K * math.exp(-r * T) * N(d2)
else:
v = K * math.exp(-r * T) * N(-d2) - S * math.exp(-q * T) * N(-d1)
return round(v, 6)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression call spot discounting 1', ['C', 110.0, 105.0, 0.0, 0.015, 0.35, 91], 9.987818], ['regression call spot discounting 2', ['C', 110.0, 100.0, 0.02, 0.03, 0.2, 30], 10.017783], ['partial repair probe 1', ['C', 100.0, 105.0, 0.05, 0.0, 0.1, 730], 8.348306], ['partial repair probe 2', ['C', 100.0, 95.0, 0.02, 0.0, 0.1, 365], 8.228981], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 100.0, 105.0, 0.0, 0.0, 0.2, 7], 5.044601], ['normal control 2', ['P', 110.0, 100.0, 0.02, 0.015, 0.2, 0], 0.0]], [['regression call spot discounting 1', ['C', 110.0, 105.0, 0.0, 0.015, 0.35, 7], 5.441716], ['regression call spot discounting 2', ['C', 110.0, 95.0, 0.0, 0.015, 0.1, 182], 14.246408], ['partial repair probe 1', ['C', 90.0, 100.0, 0.05, 0.0, 0.2, 7], 5.1e-05], ['partial repair probe 2', ['C', 90.0, 95.0, 0.02, 0.0, 0.35, 182], 7.16504], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 90.0, 100.0, 0.0, 0.03, 0.1, 1], 10.007397], ['normal control 2', ['P', 100.0, 100.0, 0.0, 0.0, 0.2, 1], 0.41763]], [['regression call spot discounting 1', ['C', 110.0, 105.0, 0.05, 0.015, 0.1, 91], 6.250733], ['regression call spot discounting 2', ['C', 110.0, 100.0, 0.0, 0.03, 0.35, 365], 17.981981], ['partial repair probe 1', ['C', 110.0, 95.0, 0.05, 0.0, 0.2, 730], 26.930371], ['partial repair probe 2', ['C', 110.0, 95.0, 0.05, 0.0, 0.1, 91], 16.177886], ['boundary control 1', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 110.0, 100.0, 0.05, 0.0, 0.1, 0], 0.0], ['normal control 2', ['P', 90.0, 95.0, 0.0, 0.0, 0.2, 0], 5.0]], [['regression call spot discounting 1', ['C', 90.0, 95.0, 0.02, 0.015, 0.1, 730], 3.308995], ['regression call spot discounting 2', ['C', 110.0, 95.0, 0.05, 0.03, 0.1, 730], 18.216377], ['partial repair probe 1', ['C', 90.0, 100.0, 0.05, 0.0, 0.35, 730], 17.398625], ['partial repair probe 2', ['C', 110.0, 105.0, 0.02, 0.0, 0.2, 365], 12.482761], ['boundary control 1', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['P', 100.0, 95.0, 0.02, 0.0, 0.2, 0], 0.0], ['normal control 2', ['P', 110.0, 105.0, 0.02, 0.015, 0.1, 1], 0.0]], [['regression call spot discounting 1', ['C', 100.0, 105.0, 0.02, 0.015, 0.1, 7], 7.8e-05], ['regression call spot discounting 2', ['C', 90.0, 100.0, 0.02, 0.015, 0.35, 7], 0.02433], ['partial repair probe 1', ['C', 100.0, 105.0, 0.02, 0.0, 0.2, 7], 0.04615], ['partial repair probe 2', ['C', 110.0, 105.0, 0.02, 0.0, 0.1, 182], 6.949255], ['boundary control 1', ['P', 90.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['boundary control 2', ['C', 110.0, 100.0, 0.05, 0.0, 0.2, 0], 10.0], ['normal control 1', ['C', 100.0, 100.0, 0.02, 0.015, 0.1, 0], 0.0], ['normal control 2', ['P', 110.0, 105.0, 0.05, 0.015, 0.2, 91], 1.934882]]]
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 call spot discounting 1 | 9.987818 | 9.987818 | Passed |
| regression call spot discounting 2 | 10.017783 | 10.017783 | Passed |
| partial repair probe 1 | 8.348306 | 8.348306 | Passed |
| partial repair probe 2 | 8.228981 | 8.228981 | Passed |
| boundary control 1 | 10.0 | 10.0 | Passed |
| boundary control 2 | 10.0 | 10.0 | Passed |
| normal control 1 | 5.044601 | 5.044601 | Passed |
| normal control 2 | 0.0 | 0.0 | Passed |
SHA-256 / 69bd2d500a054859024158f498bb72a772aa3e3a60e4cc7176ef150171cbc0f2
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:56.242394+00:00.
Case digest / 4bd75a0b2e682f39bded591cda5166a50fa0b9695b8fc6e2a6b5005d1fa71d25