FA-61206 / Bond day-count conventions / Open access
Settlement date from a business-day lag across two calendars: only the security market calendar is honored · case 01
Settlements land on currency holidays.
ROOT CAUSE
The business day predicate checks only the first holiday list.
VERIFIED REPAIR
Require a day to be open in both calendars.
Unsuccessful approach: Rolling past second-calendar holidays only at the end still counts them inside the lag.
Case contract
Inputs a trade date (a business day), a lag n and two holiday lists. A business day is a weekday that is a holiday in neither calendar. Settlement is the n-th business day strictly after trade (trade date for n=0). Return [y,m,d].
Why this case matters
Bond accrual and pricing systems depend on exact day-count arithmetic; a single-day error changes settlement cash.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime
N = 1
observations = []
def solve(trade, n, hol_a, hol_b):
T = datetime.date(*trade)
HA = {datetime.date(*h) for h in hol_a}
HB = {datetime.date(*h) for h in hol_b}
def biz(x):
return x.weekday() < 5 and x not in HA
x = T
k = 0
while k < n:
x += datetime.timedelta(days=1)
if biz(x):
k += 1
return [x.year, x.month, x.day]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression second calendar 1', [[2023, 10, 30], 1, [[2023, 11, 8], [2023, 11, 1]], [[2023, 10, 31]]], [2023, 11, 2]], ['regression second calendar 2', [[2028, 4, 17], 5, [], [[2028, 4, 24]]], [2028, 4, 25]], ['partial repair probe 1', [[2022, 5, 16], 3, [[2022, 5, 22], [2022, 5, 17]], [[2022, 5, 19], [2022, 5, 25]]], [2022, 5, 23]], ['partial repair probe 2', [[2019, 4, 1], 2, [[2019, 4, 9], [2019, 4, 2]], [[2019, 4, 3]]], [2019, 4, 5]], ['boundary control 1', [[2024, 5, 3], 0, [], []], [2024, 5, 3]], ['boundary control 2', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['normal control 1', [[2026, 10, 5], 3, [[2026, 10, 9]], []], [2026, 10, 8]], ['normal control 2', [[2028, 6, 29], 0, [], []], [2028, 6, 29]]], [['regression second calendar 1', [[2028, 7, 31], 5, [[2028, 8, 3]], [[2028, 8, 3], [2028, 8, 1]]], [2028, 8, 9]], ['regression second calendar 2', [[2024, 7, 19], 5, [[2024, 7, 21]], [[2024, 7, 23], [2024, 7, 20]]], [2024, 7, 29]], ['partial repair probe 1', [[2020, 1, 28], 5, [[2020, 2, 5]], [[2020, 2, 1], [2020, 1, 30]]], [2020, 2, 6]], ['partial repair probe 2', [[2025, 3, 28], 5, [[2025, 3, 31]], [[2025, 4, 2]]], [2025, 4, 8]], ['boundary control 1', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['boundary control 2', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['normal control 1', [[2030, 7, 10], 1, [[2030, 7, 11], [2030, 7, 16]], [[2030, 7, 11], [2030, 7, 15]]], [2030, 7, 12]], ['normal control 2', [[2020, 10, 26], 0, [], [[2020, 10, 30], [2020, 11, 2]]], [2020, 10, 26]]], [['regression second calendar 1', [[2022, 6, 30], 2, [[2022, 7, 6]], [[2022, 7, 4]]], [2022, 7, 5]], ['regression second calendar 2', [[2023, 10, 3], 5, [], [[2023, 10, 10]]], [2023, 10, 11]], ['partial repair probe 1', [[2030, 2, 28], 5, [[2030, 3, 9], [2030, 3, 2]], [[2030, 3, 8], [2030, 3, 4]]], [2030, 3, 11]], ['partial repair probe 2', [[2021, 3, 29], 3, [], [[2021, 3, 31], [2021, 4, 6]]], [2021, 4, 2]], ['boundary control 1', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['boundary control 2', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['normal control 1', [[2023, 11, 28], 2, [[2023, 12, 7]], [[2023, 12, 6]]], [2023, 11, 30]], ['normal control 2', [[2024, 7, 1], 0, [[2024, 7, 4], [2024, 7, 10]], [[2024, 7, 10], [2024, 7, 2]]], [2024, 7, 1]]], [['regression second calendar 1', [[2024, 3, 11], 5, [[2024, 3, 20], [2024, 3, 19]], [[2024, 3, 20], [2024, 3, 14]]], [2024, 3, 21]], ['regression second calendar 2', [[2027, 4, 28], 5, [[2027, 5, 2], [2027, 5, 3]], [[2027, 5, 3], [2027, 5, 4]]], [2027, 5, 7]], ['partial repair probe 1', [[2023, 7, 18], 5, [], [[2023, 7, 22], [2023, 7, 24]]], [2023, 7, 26]], ['partial repair probe 2', [[2025, 9, 1], 5, [[2025, 9, 4]], [[2025, 9, 5]]], [2025, 9, 10]], ['boundary control 1', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['boundary control 2', [[2024, 5, 3], 0, [], []], [2024, 5, 3]], ['normal control 1', [[2027, 11, 15], 2, [], [[2027, 11, 18]]], [2027, 11, 17]], ['normal control 2', [[2020, 6, 11], 1, [[2020, 6, 17], [2020, 6, 12]], [[2020, 6, 13], [2020, 6, 14]]], [2020, 6, 15]]], [['regression second calendar 1', [[2030, 6, 3], 2, [[2030, 6, 12]], [[2030, 6, 5]]], [2030, 6, 6]], ['regression second calendar 2', [[2019, 7, 22], 5, [[2019, 7, 31]], [[2019, 7, 29]]], [2019, 7, 30]], ['partial repair probe 1', [[2023, 2, 27], 2, [], [[2023, 2, 28], [2023, 3, 8]]], [2023, 3, 2]], ['partial repair probe 2', [[2023, 8, 1], 2, [[2023, 8, 7], [2023, 8, 6]], [[2023, 8, 9], [2023, 8, 2]]], [2023, 8, 4]], ['boundary control 1', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['boundary control 2', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['normal control 1', [[2020, 9, 30], 3, [[2020, 10, 7]], [[2020, 10, 8], [2020, 10, 3]]], [2020, 10, 5]], ['normal control 2', [[2025, 7, 14], 1, [[2025, 7, 18], [2025, 7, 16]], [[2025, 7, 19]]], [2025, 7, 15]]]]
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 second calendar 1 | [2023, 10, 31] | [2023, 11, 2] | Failed |
| regression second calendar 2 | [2028, 4, 24] | [2028, 4, 25] | Failed |
| partial repair probe 1 | [2022, 5, 20] | [2022, 5, 23] | Failed |
| partial repair probe 2 | [2019, 4, 4] | [2019, 4, 5] | Failed |
| boundary control 1 | [2024, 5, 3] | [2024, 5, 3] | Passed |
| boundary control 2 | [2024, 5, 8] | [2024, 5, 8] | Passed |
| normal control 1 | [2026, 10, 8] | [2026, 10, 8] | Passed |
| normal control 2 | [2028, 6, 29] | [2028, 6, 29] | Passed |
SHA-256 / f75305dc7b150780e3665fea1233813c4ca72375ebad1162faeeb0ea27ae86eb
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import datetime
N = 1
observations = []
def solve(trade, n, hol_a, hol_b):
T = datetime.date(*trade)
HA = {datetime.date(*h) for h in hol_a}
HB = {datetime.date(*h) for h in hol_b}
def biz(x):
return x.weekday() < 5 and x not in HA and x not in HB
x = T
k = 0
while k < n:
x += datetime.timedelta(days=1)
if x.weekday() < 5 and x not in HA:
k += 1
while n and not biz(x):
x += datetime.timedelta(days=1)
return [x.year, x.month, x.day]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression second calendar 1', [[2023, 10, 30], 1, [[2023, 11, 8], [2023, 11, 1]], [[2023, 10, 31]]], [2023, 11, 2]], ['regression second calendar 2', [[2028, 4, 17], 5, [], [[2028, 4, 24]]], [2028, 4, 25]], ['partial repair probe 1', [[2022, 5, 16], 3, [[2022, 5, 22], [2022, 5, 17]], [[2022, 5, 19], [2022, 5, 25]]], [2022, 5, 23]], ['partial repair probe 2', [[2019, 4, 1], 2, [[2019, 4, 9], [2019, 4, 2]], [[2019, 4, 3]]], [2019, 4, 5]], ['boundary control 1', [[2024, 5, 3], 0, [], []], [2024, 5, 3]], ['boundary control 2', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['normal control 1', [[2026, 10, 5], 3, [[2026, 10, 9]], []], [2026, 10, 8]], ['normal control 2', [[2028, 6, 29], 0, [], []], [2028, 6, 29]]], [['regression second calendar 1', [[2028, 7, 31], 5, [[2028, 8, 3]], [[2028, 8, 3], [2028, 8, 1]]], [2028, 8, 9]], ['regression second calendar 2', [[2024, 7, 19], 5, [[2024, 7, 21]], [[2024, 7, 23], [2024, 7, 20]]], [2024, 7, 29]], ['partial repair probe 1', [[2020, 1, 28], 5, [[2020, 2, 5]], [[2020, 2, 1], [2020, 1, 30]]], [2020, 2, 6]], ['partial repair probe 2', [[2025, 3, 28], 5, [[2025, 3, 31]], [[2025, 4, 2]]], [2025, 4, 8]], ['boundary control 1', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['boundary control 2', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['normal control 1', [[2030, 7, 10], 1, [[2030, 7, 11], [2030, 7, 16]], [[2030, 7, 11], [2030, 7, 15]]], [2030, 7, 12]], ['normal control 2', [[2020, 10, 26], 0, [], [[2020, 10, 30], [2020, 11, 2]]], [2020, 10, 26]]], [['regression second calendar 1', [[2022, 6, 30], 2, [[2022, 7, 6]], [[2022, 7, 4]]], [2022, 7, 5]], ['regression second calendar 2', [[2023, 10, 3], 5, [], [[2023, 10, 10]]], [2023, 10, 11]], ['partial repair probe 1', [[2030, 2, 28], 5, [[2030, 3, 9], [2030, 3, 2]], [[2030, 3, 8], [2030, 3, 4]]], [2030, 3, 11]], ['partial repair probe 2', [[2021, 3, 29], 3, [], [[2021, 3, 31], [2021, 4, 6]]], [2021, 4, 2]], ['boundary control 1', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['boundary control 2', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['normal control 1', [[2023, 11, 28], 2, [[2023, 12, 7]], [[2023, 12, 6]]], [2023, 11, 30]], ['normal control 2', [[2024, 7, 1], 0, [[2024, 7, 4], [2024, 7, 10]], [[2024, 7, 10], [2024, 7, 2]]], [2024, 7, 1]]], [['regression second calendar 1', [[2024, 3, 11], 5, [[2024, 3, 20], [2024, 3, 19]], [[2024, 3, 20], [2024, 3, 14]]], [2024, 3, 21]], ['regression second calendar 2', [[2027, 4, 28], 5, [[2027, 5, 2], [2027, 5, 3]], [[2027, 5, 3], [2027, 5, 4]]], [2027, 5, 7]], ['partial repair probe 1', [[2023, 7, 18], 5, [], [[2023, 7, 22], [2023, 7, 24]]], [2023, 7, 26]], ['partial repair probe 2', [[2025, 9, 1], 5, [[2025, 9, 4]], [[2025, 9, 5]]], [2025, 9, 10]], ['boundary control 1', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['boundary control 2', [[2024, 5, 3], 0, [], []], [2024, 5, 3]], ['normal control 1', [[2027, 11, 15], 2, [], [[2027, 11, 18]]], [2027, 11, 17]], ['normal control 2', [[2020, 6, 11], 1, [[2020, 6, 17], [2020, 6, 12]], [[2020, 6, 13], [2020, 6, 14]]], [2020, 6, 15]]], [['regression second calendar 1', [[2030, 6, 3], 2, [[2030, 6, 12]], [[2030, 6, 5]]], [2030, 6, 6]], ['regression second calendar 2', [[2019, 7, 22], 5, [[2019, 7, 31]], [[2019, 7, 29]]], [2019, 7, 30]], ['partial repair probe 1', [[2023, 2, 27], 2, [], [[2023, 2, 28], [2023, 3, 8]]], [2023, 3, 2]], ['partial repair probe 2', [[2023, 8, 1], 2, [[2023, 8, 7], [2023, 8, 6]], [[2023, 8, 9], [2023, 8, 2]]], [2023, 8, 4]], ['boundary control 1', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['boundary control 2', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['normal control 1', [[2020, 9, 30], 3, [[2020, 10, 7]], [[2020, 10, 8], [2020, 10, 3]]], [2020, 10, 5]], ['normal control 2', [[2025, 7, 14], 1, [[2025, 7, 18], [2025, 7, 16]], [[2025, 7, 19]]], [2025, 7, 15]]]]
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 second calendar 1 | [2023, 11, 2] | [2023, 11, 2] | Passed |
| regression second calendar 2 | [2028, 4, 25] | [2028, 4, 25] | Passed |
| partial repair probe 1 | [2022, 5, 20] | [2022, 5, 23] | Failed |
| partial repair probe 2 | [2019, 4, 4] | [2019, 4, 5] | Failed |
| boundary control 1 | [2024, 5, 3] | [2024, 5, 3] | Passed |
| boundary control 2 | [2024, 5, 8] | [2024, 5, 8] | Passed |
| normal control 1 | [2026, 10, 8] | [2026, 10, 8] | Passed |
| normal control 2 | [2028, 6, 29] | [2028, 6, 29] | Passed |
SHA-256 / 474dcc1d19752ff556892d3d33bd876f5e875a58ad40efff2a2c8b7c2ca68f46
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import datetime
N = 1
observations = []
def solve(trade, n, hol_a, hol_b):
T = datetime.date(*trade)
HA = {datetime.date(*h) for h in hol_a}
HB = {datetime.date(*h) for h in hol_b}
def biz(x):
return x.weekday() < 5 and x not in HA and x not in HB
x = T
k = 0
while k < n:
x += datetime.timedelta(days=1)
if biz(x):
k += 1
return [x.year, x.month, x.day]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression second calendar 1', [[2023, 10, 30], 1, [[2023, 11, 8], [2023, 11, 1]], [[2023, 10, 31]]], [2023, 11, 2]], ['regression second calendar 2', [[2028, 4, 17], 5, [], [[2028, 4, 24]]], [2028, 4, 25]], ['partial repair probe 1', [[2022, 5, 16], 3, [[2022, 5, 22], [2022, 5, 17]], [[2022, 5, 19], [2022, 5, 25]]], [2022, 5, 23]], ['partial repair probe 2', [[2019, 4, 1], 2, [[2019, 4, 9], [2019, 4, 2]], [[2019, 4, 3]]], [2019, 4, 5]], ['boundary control 1', [[2024, 5, 3], 0, [], []], [2024, 5, 3]], ['boundary control 2', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['normal control 1', [[2026, 10, 5], 3, [[2026, 10, 9]], []], [2026, 10, 8]], ['normal control 2', [[2028, 6, 29], 0, [], []], [2028, 6, 29]]], [['regression second calendar 1', [[2028, 7, 31], 5, [[2028, 8, 3]], [[2028, 8, 3], [2028, 8, 1]]], [2028, 8, 9]], ['regression second calendar 2', [[2024, 7, 19], 5, [[2024, 7, 21]], [[2024, 7, 23], [2024, 7, 20]]], [2024, 7, 29]], ['partial repair probe 1', [[2020, 1, 28], 5, [[2020, 2, 5]], [[2020, 2, 1], [2020, 1, 30]]], [2020, 2, 6]], ['partial repair probe 2', [[2025, 3, 28], 5, [[2025, 3, 31]], [[2025, 4, 2]]], [2025, 4, 8]], ['boundary control 1', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['boundary control 2', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['normal control 1', [[2030, 7, 10], 1, [[2030, 7, 11], [2030, 7, 16]], [[2030, 7, 11], [2030, 7, 15]]], [2030, 7, 12]], ['normal control 2', [[2020, 10, 26], 0, [], [[2020, 10, 30], [2020, 11, 2]]], [2020, 10, 26]]], [['regression second calendar 1', [[2022, 6, 30], 2, [[2022, 7, 6]], [[2022, 7, 4]]], [2022, 7, 5]], ['regression second calendar 2', [[2023, 10, 3], 5, [], [[2023, 10, 10]]], [2023, 10, 11]], ['partial repair probe 1', [[2030, 2, 28], 5, [[2030, 3, 9], [2030, 3, 2]], [[2030, 3, 8], [2030, 3, 4]]], [2030, 3, 11]], ['partial repair probe 2', [[2021, 3, 29], 3, [], [[2021, 3, 31], [2021, 4, 6]]], [2021, 4, 2]], ['boundary control 1', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['boundary control 2', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['normal control 1', [[2023, 11, 28], 2, [[2023, 12, 7]], [[2023, 12, 6]]], [2023, 11, 30]], ['normal control 2', [[2024, 7, 1], 0, [[2024, 7, 4], [2024, 7, 10]], [[2024, 7, 10], [2024, 7, 2]]], [2024, 7, 1]]], [['regression second calendar 1', [[2024, 3, 11], 5, [[2024, 3, 20], [2024, 3, 19]], [[2024, 3, 20], [2024, 3, 14]]], [2024, 3, 21]], ['regression second calendar 2', [[2027, 4, 28], 5, [[2027, 5, 2], [2027, 5, 3]], [[2027, 5, 3], [2027, 5, 4]]], [2027, 5, 7]], ['partial repair probe 1', [[2023, 7, 18], 5, [], [[2023, 7, 22], [2023, 7, 24]]], [2023, 7, 26]], ['partial repair probe 2', [[2025, 9, 1], 5, [[2025, 9, 4]], [[2025, 9, 5]]], [2025, 9, 10]], ['boundary control 1', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['boundary control 2', [[2024, 5, 3], 0, [], []], [2024, 5, 3]], ['normal control 1', [[2027, 11, 15], 2, [], [[2027, 11, 18]]], [2027, 11, 17]], ['normal control 2', [[2020, 6, 11], 1, [[2020, 6, 17], [2020, 6, 12]], [[2020, 6, 13], [2020, 6, 14]]], [2020, 6, 15]]], [['regression second calendar 1', [[2030, 6, 3], 2, [[2030, 6, 12]], [[2030, 6, 5]]], [2030, 6, 6]], ['regression second calendar 2', [[2019, 7, 22], 5, [[2019, 7, 31]], [[2019, 7, 29]]], [2019, 7, 30]], ['partial repair probe 1', [[2023, 2, 27], 2, [], [[2023, 2, 28], [2023, 3, 8]]], [2023, 3, 2]], ['partial repair probe 2', [[2023, 8, 1], 2, [[2023, 8, 7], [2023, 8, 6]], [[2023, 8, 9], [2023, 8, 2]]], [2023, 8, 4]], ['boundary control 1', [[2024, 5, 6], 1, [[2024, 5, 7]], []], [2024, 5, 8]], ['boundary control 2', [[2024, 5, 3], 2, [], []], [2024, 5, 7]], ['normal control 1', [[2020, 9, 30], 3, [[2020, 10, 7]], [[2020, 10, 8], [2020, 10, 3]]], [2020, 10, 5]], ['normal control 2', [[2025, 7, 14], 1, [[2025, 7, 18], [2025, 7, 16]], [[2025, 7, 19]]], [2025, 7, 15]]]]
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 second calendar 1 | [2023, 11, 2] | [2023, 11, 2] | Passed |
| regression second calendar 2 | [2028, 4, 25] | [2028, 4, 25] | Passed |
| partial repair probe 1 | [2022, 5, 23] | [2022, 5, 23] | Passed |
| partial repair probe 2 | [2019, 4, 5] | [2019, 4, 5] | Passed |
| boundary control 1 | [2024, 5, 3] | [2024, 5, 3] | Passed |
| boundary control 2 | [2024, 5, 8] | [2024, 5, 8] | Passed |
| normal control 1 | [2026, 10, 8] | [2026, 10, 8] | Passed |
| normal control 2 | [2028, 6, 29] | [2028, 6, 29] | Passed |
SHA-256 / d06164a6702040766c42a5318fb611bd4e2ae2a8c375a0d673b1b6f572ec17a8
Verification & scope
A deterministic toy contract stated explicitly in the contract field; no claim of conformance to any published convention text. 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:53.095393+00:00.
Case digest / 8eb9377382e327072a7418cdb8da450092c646e395f55cb25d11a9f7dec597d7