Simple claim: a curve is legal information at a clock, and the bootstrap is a gain stage, five basis points of leaked spot becomes tens on the long forward. The trench is as-of honesty under filtration, not prettier interpolation.
The leakage I worry about most is not a stolen label. It is a curve.
Everyone on a modern desk knows not to train on the answer. So the obvious cheats get caught: the future return column, the settlement price on the trade date, the outcome flag joined in by accident. What survives review is subtler and structurally worse. A yield curve arrives as a table of tenors and rates, gets a date stamp, and gets treated as reference data. Reference data feels like a constant. Nobody audits a constant. And inside that table, one pillar came from a print that did not exist at the decision clock.
The curve is not reference data. It is a filtration, the set of things you were legally allowed to know at a moment, wearing a spreadsheet costume.
What the bootstrap does to a small lie
The reason a leaked pillar is worse than a leaked feature is that the curve is not consumed raw. It is bootstrapped, and bootstrapping is a recursion that amplifies.
| Bootstrap object | Honest | After +15 bp illegal 2y spot |
|---|---|---|
| 1y spot (strip) | 5.00% | 5.00% (unchanged) |
| 2y spot (bootstrapped) | 5.50% | ~5.65% (leaked) |
| 1y lands near 2y forward (no-arb) | 6.00% | ~6.30% (amplified) |
| Input lie | , | 15 bp |
| Output move (this step) | , | ~30 bp (≈2×) |
At the long end the amplifier is worse: five basis points of leaked spot can become on the order of fifty on long forwards. The curve is not a table of numbers; it is a filtration plus a recursion.
Start honest. A one-year strip gives a spot of 5.00 percent. A two-year coupon bond, with the first coupon stripped at the known one-year spot, solves to a two-year spot of 5.50 percent. The no-arbitrage relation then pins the one-into-two forward: 1.05 times one plus f equals 1.055 squared, so f is 6.00 percent. That forward is not a forecast. It is the only rate at which the two paths cannot be arbitraged against each other.
Now leak fifteen basis points into the two-year spot, say tomorrow's print, because the vendor file was refreshed overnight and the loader takes the latest row. The forward moves to 6.30 percent. Fifteen basis points of input, thirty of output. The recursion doubled it.
At the long end it is far worse, because the amplification runs roughly with tenor. Take a nine-year spot of 5.40 and a ten-year of 5.50: the nine-into-ten forward is 6.40 percent. Move the ten-year spot by five basis points, a rounding difference, the kind of thing nobody would call leakage, and that forward becomes 6.91. Fifty basis points of movement out of five basis points of contamination. Fifteen basis points of contamination moves it by a full 1.52 percent.
So the honest framing is not "a little future information slipped in." It is: the bootstrap is a gain stage, and you put a signal into it that only exists tomorrow.
Why it feels like clean engineering
Because every step in the chain is good practice taken one clock too far.
Vendors publish corrections, so loaders take the latest available row, correct for reporting, catastrophic for a decision table. Curves have gaps, so interpolation fills them, correct for smoothness, and it happily interpolates through an illegal pillar and launders it across neighbouring tenors. Research wants stable inputs, so someone builds a "clean curve" table with one row per date, and the cleaning job ran last month, with last month's information, over dates that are all in that job's past.
That last one is the trap I see most. A batch job is a time machine. Every rebuild of a historical table quietly grants the past access to the future, and the artefact it produces looks more trustworthy than the messy live feed, because it is complete and gap-free. Completeness is the tell. Live information is never that tidy.
Then the backtest works. Of course it works. A model reading a forward that contains tomorrow's print will find that the forward predicts tomorrow. Leakage does not present as an error; it presents as skill, and skill gets funded.
How this shows up in production
- The refreshed pillar. One tenor in the present table carries a print stamped after the as-of clock. Nothing in the schema distinguishes observation time from effective date, so the illegal row is indistinguishable from the legal ones. The bootstrap multiplies it and the whole long end inherits it.
- Soft leakage through aggregates. No individual print is illegal, but a monthly average stamped to month-end was published on the third of the next month. A "latest value" column carries whatever was current at build time. A rolling z-score uses a window centred on the observation. Each of these leaks less than a stolen price and is much harder to see, because the leaking field is a summary and summaries feel like descriptions rather than observations.
- Agent memory as a side channel. The retrieval store holds yesterday's analysis, which discussed a print that is illegal for today's replay. The prompt is clean. The context is not. Filtration discipline that stops at the feature table does not cover a system that remembers.
- Missing pillars papered over. Three of the tenors you need did not trade. Interpolation invents them, the curve looks complete, and a single confident mark ships. The honest answer was a band, or an inconclusive, because part of the curve was not observable at that clock.
- Split clocks across asset classes. Equity marks stamped 14:00, curve pulled from the 17:30 close, both labelled with the same trading date. In calm weeks nobody notices. In a co-break week, when rates and equity move together and the joint move is the whole risk, the three-and-a-half-hour offset is precisely the interval that decides whether the model looked prescient or blind.
A walkthrough on CEH-001
| Frame | Depends on long forwards? | Under leakage |
|---|---|---|
| Spread (~1.50) | No | Backtest error roughly stable |
| Curve (~2.10) | Yes (bootstrap zeros) | Error falls, looks like skill |
| Rights change | , | Curve frame promoted for the wrong reason |
| 1.80 peace | , | Leakage feeds midpoint culture |
The never-traded family again, marks near 1.50 under the spread frame and near 2.10 under the curve frame. The curve-frame mark is the one exposed here, because it is built off the bootstrapped zero curve, and the bootstrap has an amplifier in it.
Rebuild the historical table and the ten-year pillar for several dates carries an overnight refresh. The long forwards move by half a point in the direction the market subsequently went, because that is what the leaked print encodes. The curve-frame mark tightens toward the eventual outcome, so its backtest error falls. The spread-frame mark, which does not touch the long forwards, does not improve. Someone reads the comparison and concludes the curve frame is the better methodology.
That conclusion is now driving a rights change. It is an artefact of a loader.
Worse, the leaked curve makes an arbitrage look available. When the forward implied by legal information is 6.00 and the leaked table implies 6.30, the backtest sees a thirty-basis-point discrepancy between two funding paths, about 0.32 per hundred of notional, and books it as a riskless gain. Arbitrage is positive gain on zero net investment, and real markets equalise it in minutes. A backtest with a clock bug can harvest it every day for a year.
Then the co-break week arrives, the split clock stops being harmless, and 1.50 versus 2.10 reopens as wide as it ever was. The organisation now has a tired argument and a favourite methodology chosen for the wrong reason. Somebody proposes 1.80, and it lands with more support than usual, because both frames have just been publicly wrong. That is how leakage ends up defending an invented mark.
What stacks quietly assume
They assume reference data has no clock. They assume a date column is an as-of. They assume the newest value of a field is the best value of that field. They assume interpolation is neutral, when interpolation is the mechanism that spreads one illegal print across the tenors around it. They assume a completed curve is better than a curve with holes, when the holes were the honest part. And they assume leakage announces itself as an error, when it announces itself as performance.
What a solution must do
Problem: a curve is a snapshot of legal information at a clock; the bootstrap amplifies illegal prints and soft leakage (aggregates, memory, latest-row loaders) looks like clean engineering. Solution: make the clock structural, observation time ≠ effective date; legal information set at each as-of; bootstrap recipe hashed with the curve; post-clock prints refuse hard; missing pillars then band/inconclusive, not silent interpolation; audit aggregates and agent memory under the same filtration rule.
That full stack continues into typed jobs and Clearance (S2-04+). This essay still ships a gate you can run on Monday.
What to lock
- Separate fields: observation time vs effective date; a date column is not an as-of.
- Any pillar stamped after the decision clock then
LEAKAGE_FUTURE_PRINThard refuse (no soft yellow, no midpoint). - Bootstrap recipe hash (instruments, order, interpolation) travels with the curve artefact.
- Missing pillars then dual band / inconclusive, not a single interpolated “clean” number.
- Aggregates, z-scores, agent memory, and “latest value” columns audited under the same filtration rule as prints.
- Shared clock across asset classes: equity mark and curve mark cannot claim the same as-of while standing hours apart.
- CEH curve-frame “skill” vs spread-frame under co-break leakage is a unit test, not a promotion story.
Clearance coupling: tomorrow's 10y in today's table is LEAKAGE_FUTURE_PRINT. Soft cousins (batch z-scores, agent memory, latest-tool defaults) are soft filtration fails beside the hard timestamp canary. Co-break stress must move equity and rates joints together. Five basis points of illegal spot, gained through bootstrap into long forwards, can exceed the dual-frame gap the desk is arguing as model skill on CEH-001's funding leg.