FA-61276 / Bond day-count conventions / Open access
Rate conversion across day-count basis and compounding: the basis ratio is inverted · case 01
Converting an Act/360 rate to Act/365 lowers it instead of raising it.
ROOT CAUSE
The rescaling multiplies by from_basis/to_basis.
VERIFIED REPAIR
Multiply by to_basis/from_basis so interest per day is preserved.
Unsuccessful approach: Hard-coding the 360-to-365 case ignores conversions in the other direction.
Case contract
Inputs a nominal rate, from/to day-count year basis (360 or 365), from/to compounding frequency (0 = continuous). First rescale the nominal rate by to_basis/from_basis, then convert compounding through the effective annual rate: EAR = (1+r/m)^m - 1 or e^r - 1; target nominal = m*((1+EAR)^(1/m)-1) or ln(1+EAR). Return rounded to 10 decimals.
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 math
N = 1
observations = []
def solve(rate, from_basis, to_basis, from_comp, to_comp):
def ear(r, m):
return math.exp(r) - 1 if m == 0 else (1 + r / m) ** m - 1
def nominal(e, m):
return math.log(1 + e) if m == 0 else m * ((1 + e) ** (1 / m) - 1)
scaled = rate * from_basis / to_basis
return round(nominal(ear(scaled, from_comp), to_comp), 10)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression basis ratio direction 1', [0.0475, 365, 360, 4, 12], 0.0466675911], ['regression basis ratio direction 2', [0.0475, 365, 360, 12, 1], 0.047868499], ['partial repair probe 1', [0.0125, 360, 360, 0, 0], 0.0125], ['partial repair probe 2', [0.0125, 360, 360, 2, 1], 0.0125390625], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.0125, 365, 365, 12, 12], 0.0125], ['normal control 2', [0.08, 365, 365, 0, 4], 0.0808053601], ['normal control 3', [0.03, 365, 365, 12, 4], 0.0300750625]], [['regression basis ratio direction 1', [0.03, 360, 365, 12, 12], 0.0304166667], ['regression basis ratio direction 2', [0.001, 365, 360, 1, 12], 0.0009858558], ['partial repair probe 1', [0.08, 360, 360, 1, 4], 0.0777061876], ['partial repair probe 2', [0.15, 360, 360, 4, 2], 0.1528125], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.08, 365, 365, 1, 4], 0.0777061876], ['normal control 2', [0.0125, 365, 365, 4, 0], 0.0124805093], ['normal control 3', [0.15, 365, 365, 2, 12], 0.1455165491]], [['regression basis ratio direction 1', [0.001, 365, 360, 12, 12], 0.0009863014], ['regression basis ratio direction 2', [0.03, 365, 360, 4, 1], 0.0299189799], ['partial repair probe 1', [0.0125, 360, 360, 4, 0], 0.0124805093], ['partial repair probe 2', [0.0125, 360, 360, 4, 2], 0.0125195313], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.0475, 365, 365, 2, 0], 0.0469447124], ['normal control 2', [0.03, 365, 365, 2, 4], 0.0298883359], ['normal control 3', [0.001, 365, 365, 2, 12], 0.0009997917]], [['regression basis ratio direction 1', [0.0475, 365, 360, 1, 12], 0.0458724565], ['regression basis ratio direction 2', [0.03, 365, 360, 4, 4], 0.0295890411], ['partial repair probe 1', [0.0475, 360, 360, 2, 2], 0.0475], ['partial repair probe 2', [0.001, 360, 360, 0, 1], 0.0010005002], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.03, 365, 365, 4, 12], 0.0299253109], ['normal control 2', [0.0125, 365, 365, 12, 1], 0.0125718638], ['normal control 3', [0.15, 365, 365, 1, 1], 0.15]], [['regression basis ratio direction 1', [0.0475, 360, 365, 2, 2], 0.0481597222], ['regression basis ratio direction 2', [0.001, 365, 360, 1, 0], 0.0009858153], ['partial repair probe 1', [0.03, 360, 360, 12, 4], 0.0300750625], ['partial repair probe 2', [0.0125, 360, 360, 4, 2], 0.0125195313], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.15, 365, 365, 0, 4], 0.1528479883], ['normal control 2', [0.001, 365, 365, 1, 4], 0.0009996252], ['normal control 3', [0.15, 365, 365, 4, 4], 0.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 basis ratio direction 1 | 0.0479677249 | 0.0466675911 | Failed |
| regression basis ratio direction 2 | 0.049237112 | 0.047868499 | Failed |
| partial repair probe 1 | 0.0125 | 0.0125 | Passed |
| partial repair probe 2 | 0.0125390625 | 0.0125390625 | Passed |
| boundary control 1 | 0.05 | 0.05 | Passed |
| normal control 1 | 0.0125 | 0.0125 | Passed |
| normal control 2 | 0.0808053601 | 0.0808053601 | Passed |
| normal control 3 | 0.0300750625 | 0.0300750625 | Passed |
SHA-256 / 714f5842fd932730e35cbc8d831e28eac24d446d124be612358fd1380a9835b4
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(rate, from_basis, to_basis, from_comp, to_comp):
def ear(r, m):
return math.exp(r) - 1 if m == 0 else (1 + r / m) ** m - 1
def nominal(e, m):
return math.log(1 + e) if m == 0 else m * ((1 + e) ** (1 / m) - 1)
scaled = rate * 365 / 360 if from_basis == 360 else rate
return round(nominal(ear(scaled, from_comp), to_comp), 10)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression basis ratio direction 1', [0.0475, 365, 360, 4, 12], 0.0466675911], ['regression basis ratio direction 2', [0.0475, 365, 360, 12, 1], 0.047868499], ['partial repair probe 1', [0.0125, 360, 360, 0, 0], 0.0125], ['partial repair probe 2', [0.0125, 360, 360, 2, 1], 0.0125390625], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.0125, 365, 365, 12, 12], 0.0125], ['normal control 2', [0.08, 365, 365, 0, 4], 0.0808053601], ['normal control 3', [0.03, 365, 365, 12, 4], 0.0300750625]], [['regression basis ratio direction 1', [0.03, 360, 365, 12, 12], 0.0304166667], ['regression basis ratio direction 2', [0.001, 365, 360, 1, 12], 0.0009858558], ['partial repair probe 1', [0.08, 360, 360, 1, 4], 0.0777061876], ['partial repair probe 2', [0.15, 360, 360, 4, 2], 0.1528125], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.08, 365, 365, 1, 4], 0.0777061876], ['normal control 2', [0.0125, 365, 365, 4, 0], 0.0124805093], ['normal control 3', [0.15, 365, 365, 2, 12], 0.1455165491]], [['regression basis ratio direction 1', [0.001, 365, 360, 12, 12], 0.0009863014], ['regression basis ratio direction 2', [0.03, 365, 360, 4, 1], 0.0299189799], ['partial repair probe 1', [0.0125, 360, 360, 4, 0], 0.0124805093], ['partial repair probe 2', [0.0125, 360, 360, 4, 2], 0.0125195313], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.0475, 365, 365, 2, 0], 0.0469447124], ['normal control 2', [0.03, 365, 365, 2, 4], 0.0298883359], ['normal control 3', [0.001, 365, 365, 2, 12], 0.0009997917]], [['regression basis ratio direction 1', [0.0475, 365, 360, 1, 12], 0.0458724565], ['regression basis ratio direction 2', [0.03, 365, 360, 4, 4], 0.0295890411], ['partial repair probe 1', [0.0475, 360, 360, 2, 2], 0.0475], ['partial repair probe 2', [0.001, 360, 360, 0, 1], 0.0010005002], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.03, 365, 365, 4, 12], 0.0299253109], ['normal control 2', [0.0125, 365, 365, 12, 1], 0.0125718638], ['normal control 3', [0.15, 365, 365, 1, 1], 0.15]], [['regression basis ratio direction 1', [0.0475, 360, 365, 2, 2], 0.0481597222], ['regression basis ratio direction 2', [0.001, 365, 360, 1, 0], 0.0009858153], ['partial repair probe 1', [0.03, 360, 360, 12, 4], 0.0300750625], ['partial repair probe 2', [0.0125, 360, 360, 4, 2], 0.0125195313], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.15, 365, 365, 0, 4], 0.1528479883], ['normal control 2', [0.001, 365, 365, 1, 4], 0.0009996252], ['normal control 3', [0.15, 365, 365, 4, 4], 0.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 basis ratio direction 1 | 0.0473132098 | 0.0466675911 | Failed |
| regression basis ratio direction 2 | 0.0485478814 | 0.047868499 | Failed |
| partial repair probe 1 | 0.0126736111 | 0.0125 | Failed |
| partial repair probe 2 | 0.0127137662 | 0.0125390625 | Failed |
| boundary control 1 | 0.05 | 0.05 | Passed |
| normal control 1 | 0.0125 | 0.0125 | Passed |
| normal control 2 | 0.0808053601 | 0.0808053601 | Passed |
| normal control 3 | 0.0300750625 | 0.0300750625 | Passed |
SHA-256 / 7b9348638930ce4abe622b42228d6c19f05cc27966766766bd309473271cb49d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(rate, from_basis, to_basis, from_comp, to_comp):
def ear(r, m):
return math.exp(r) - 1 if m == 0 else (1 + r / m) ** m - 1
def nominal(e, m):
return math.log(1 + e) if m == 0 else m * ((1 + e) ** (1 / m) - 1)
scaled = rate * to_basis / from_basis
return round(nominal(ear(scaled, from_comp), to_comp), 10)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression basis ratio direction 1', [0.0475, 365, 360, 4, 12], 0.0466675911], ['regression basis ratio direction 2', [0.0475, 365, 360, 12, 1], 0.047868499], ['partial repair probe 1', [0.0125, 360, 360, 0, 0], 0.0125], ['partial repair probe 2', [0.0125, 360, 360, 2, 1], 0.0125390625], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.0125, 365, 365, 12, 12], 0.0125], ['normal control 2', [0.08, 365, 365, 0, 4], 0.0808053601], ['normal control 3', [0.03, 365, 365, 12, 4], 0.0300750625]], [['regression basis ratio direction 1', [0.03, 360, 365, 12, 12], 0.0304166667], ['regression basis ratio direction 2', [0.001, 365, 360, 1, 12], 0.0009858558], ['partial repair probe 1', [0.08, 360, 360, 1, 4], 0.0777061876], ['partial repair probe 2', [0.15, 360, 360, 4, 2], 0.1528125], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.08, 365, 365, 1, 4], 0.0777061876], ['normal control 2', [0.0125, 365, 365, 4, 0], 0.0124805093], ['normal control 3', [0.15, 365, 365, 2, 12], 0.1455165491]], [['regression basis ratio direction 1', [0.001, 365, 360, 12, 12], 0.0009863014], ['regression basis ratio direction 2', [0.03, 365, 360, 4, 1], 0.0299189799], ['partial repair probe 1', [0.0125, 360, 360, 4, 0], 0.0124805093], ['partial repair probe 2', [0.0125, 360, 360, 4, 2], 0.0125195313], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.0475, 365, 365, 2, 0], 0.0469447124], ['normal control 2', [0.03, 365, 365, 2, 4], 0.0298883359], ['normal control 3', [0.001, 365, 365, 2, 12], 0.0009997917]], [['regression basis ratio direction 1', [0.0475, 365, 360, 1, 12], 0.0458724565], ['regression basis ratio direction 2', [0.03, 365, 360, 4, 4], 0.0295890411], ['partial repair probe 1', [0.0475, 360, 360, 2, 2], 0.0475], ['partial repair probe 2', [0.001, 360, 360, 0, 1], 0.0010005002], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.03, 365, 365, 4, 12], 0.0299253109], ['normal control 2', [0.0125, 365, 365, 12, 1], 0.0125718638], ['normal control 3', [0.15, 365, 365, 1, 1], 0.15]], [['regression basis ratio direction 1', [0.0475, 360, 365, 2, 2], 0.0481597222], ['regression basis ratio direction 2', [0.001, 365, 360, 1, 0], 0.0009858153], ['partial repair probe 1', [0.03, 360, 360, 12, 4], 0.0300750625], ['partial repair probe 2', [0.0125, 360, 360, 4, 2], 0.0125195313], ['boundary control 1', [0.05, 365, 365, 0, 0], 0.05], ['normal control 1', [0.15, 365, 365, 0, 4], 0.1528479883], ['normal control 2', [0.001, 365, 365, 1, 4], 0.0009996252], ['normal control 3', [0.15, 365, 365, 4, 4], 0.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 basis ratio direction 1 | 0.0466675911 | 0.0466675911 | Passed |
| regression basis ratio direction 2 | 0.047868499 | 0.047868499 | Passed |
| partial repair probe 1 | 0.0125 | 0.0125 | Passed |
| partial repair probe 2 | 0.0125390625 | 0.0125390625 | Passed |
| boundary control 1 | 0.05 | 0.05 | Passed |
| normal control 1 | 0.0125 | 0.0125 | Passed |
| normal control 2 | 0.0808053601 | 0.0808053601 | Passed |
| normal control 3 | 0.0300750625 | 0.0300750625 | Passed |
SHA-256 / d8f8cbfa3a80ca6c220632f418014db47b7791804bcea4281202d332776021d7
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.780912+00:00.
Case digest / 31d8364521c6598e01dfa5926935050dc259e806854d9fcfc4019e3ad25db862