{"id":"8f240711-3be5-456c-95da-43c1d665ea57","authorId":"08398a34-26f5-4992-82de-0cfba0302908","title":"The Kalman Hedge Ratio Made the Spread Noisier — and Threw Away Its Market Neutrality","slug":"the-kalman-hedge-ratio-made-the-spread-noisier-and-threw-away-its-market-neutrality","excerpt":"A time-varying hedge ratio was supposed to triple the gross edge on 12 alt/BTC spreads. It reduced spread variance by -24.6% (i.e. raised it) on 11 of 12 pairs, cut gross edge to +2.40%/yr against a 9.36%/yr bar, and broke even at 8.14 bps against the 8.81 bps it pays.","content":"**Verdict:** REJECTED · **Assets/TF:** 12 alt/BTC spreads, 1h · **Sample:** 49,186 bars per spread, 2020-11-28 → 2026-07-10, 2,051 daily observations · **Corpus ends 2026-07-10, 47 days before this run**\n\nA static alt/BTC ratio is a hedge ratio of **exactly 1 by assumption**. If the true ratio drifts, that construction carries uncompensated directional exposure and mismeasures the spread. A Kalman filter estimates the hedge ratio as a time-varying state instead. That is a candidate for real gross edge, not a Sharpe cosmetic — which is why it was worth one run.\n\nIt made things worse. Not marginally: the \"hedged\" spread became **noisier** than the fixed ratio it replaced, on 11 of 12 pairs.\n\n## What was fixed before the run\n\nTwo gates, written down before any backtest, and not moved afterwards:\n\n- **K1** — portfolio **gross** annualised return **≥ 9.36%/yr**. That is 3.0× the +3.12%/yr gross our [previous cycle](https://rlxbt.com/articles/the-23-independent-bets-were-a-measurement-artifact-and-fixing-breadth-changed-nothing) measured on the same panel, and it is that article's reopening condition restated.\n- **K2** — portfolio **breakeven per-side commission ≥ 13.2 bps**, inclusive of re-hedge turnover. 1.5× the 8.808 bps two-leg cost.\n\nEither one failing rejects. Validity floor: under 300 trades means inconclusive, not rejected.\n\n**The bar is in gross terms deliberately.** The previous cycle established that a net-return bar just re-measures your cost model. K1 asks whether a drifting hedge ratio *creates* edge. K2 asks whether it survives its own turnover. K1 is computed at zero commission, zero slippage **and zero re-hedge drag**, so it does not depend on the rebalancing rule at all.\n\n## Three arms, one difference\n\nSame rule, same window, same machinery, same costs. Only β changes:\n\n```json\n{\"entry_rules\": [\n   {\"condition\": \"ret_168 > 0.05 && z_168 > 1.0\",  \"direction\": 1},\n   {\"condition\": \"ret_168 < -0.05 && z_168 < -1.0\", \"direction\": -1}],\n \"exit_rules\": [{\"condition\": \"z_168 > -0.5 && z_168 < 0.5\"}],\n \"max_hold_bars\": 336, \"position_size\": 0.15,\n \"stop_loss_pct\": 0.10, \"take_profit_pct\": 0.20}\n```\n\nThe spread return each bar is `r_alt − β·r_btc`, with β the hedge in force at the *start* of the bar — the filter state after the previous bar. Execution is `next_open`, one further bar out.\n\n- **static** — β ≡ 1. The control, dollar-neutral by construction.\n- **kalman** — β from a log-level filter, `log(alt) = β·log(btc) + α`. **The preregistered arm.**\n- **kalret** — β from a return-space filter, `r_alt = β·r_btc + ε`. A steelman, **not preregistered** (see below).\n\nFilter: state `[β, α]`, random-walk transition, `Vw = δ/(1−δ)·I` with **δ = 1e-5 fixed, not swept**, `Ve` = burn-in OLS residual variance per pair. The first 720 bars seed the filter and are never traded.\n\n**The re-hedge budget, fixed in advance.** A Kalman hedge ratio makes the traded instrument a *changing basket*, so rebalancing the BTC leg is its own cost centre. The primary arm rebalances **every bar** — maximal cost, maximal fidelity — and pays `|Δβ| × (commission/2 + slippage_per_leg)` into the spread price path. During the breakeven bisection that drag is **rebuilt at each trial commission**, so the cost curve stays self-consistent.\n\n## The diagnostic that predicted everything\n\nBefore running a single backtest, we measured what the filter actually does to the spread.\n\n| | median across 12 pairs |\n|---|---:|\n| **Spread variance reduction (log-level β)** | **−24.62%** — negative on 11 of 12 |\n| Spread variance reduction (return-space β) | +5.32% — positive on 12 of 12 |\n| Re-hedge turnover, every bar | 2.30 `Σ|Δβ|`/yr = **12.4 bps/yr** |\n\nβ drifts far below 1 and stays there — AVAX **0.133**, BCH 0.247, ATOM 0.354, ETC 0.460 — with `|β−1| > 0.1` on **100% of bars for 8 of the 12 pairs**.\n\nThe reason is specification, not the filter. Regressing `log(alt)` on `log(btc)` estimates a **cointegration slope**, and these pairs are not cointegrated: `hurst_168 ≈ 0.52`, and every mean-reversion variant we have tested on them breaks even at **0.000 bps**. On non-cointegrated series a level regression fits a spurious level relationship, and the filter tracks it faithfully. AVAX/BTC fell 70% over the sample, so the level fit concludes \"AVAX barely responds to BTC\" and sets β ≈ 0.13.\n\nA β of 0.13 does not hedge. It leaves ~87% of the BTC leg naked.\n\n## Results\n\n| | static (control) | **kalman (preregistered)** | kalret (steelman) |\n|---|---:|---:|---:|\n| trades | 5,019 | 5,396 | 4,952 |\n| **gross** | +14.71% (**+2.48%/yr**) | +14.23% (**+2.40%/yr**) | +28.13% (**+4.52%/yr**) |\n| **cost** | −14.29 pp = 97.2% of gross | −15.06 pp = **105.8% of gross** | −15.58 pp = 55.4% |\n| **net** | +0.42% (+0.07%/yr) | **−0.83% (−0.15%/yr)** | +12.55% (+2.13%/yr) |\n| Sharpe · max DD | 0.039 · −9.31% | −0.006 · −14.70% | 0.562 · −8.10% |\n| **breakeven** | 9.14 bps (1.04×) | **8.14 bps (0.93×)** | 18.22 bps (2.07×) |\n| ex-2021 | −1.19%/yr | −1.97%/yr | **−0.31%/yr** |\n| years positive | 3/7 | 4/7 | 4/7 |\n\n**K1: 2.399%/yr against 9.36 required — FAIL, 3.9× short. K2: 8.145 bps against 13.2 required — FAIL.** Validity 5,396 trades, fine. **REJECTED.**\n\nThe K2 failure is worse than a thin margin. **8.145 bps is below the 8.808 bps the arm actually pays.** The previous cycle's best construction at least cleared its raw cost and failed on margin; this one does not clear it.\n\nGross edge and cost, stated separately: the preregistered arm generated **+2.40%/yr of gross edge** and paid **more than all of it** away in commission and slippage.\n\n## Four things this establishes beyond the rejection\n\n**1. It destroys the one property that worked.** Dollar neutrality was the genuine achievement of this family. Measured daily:\n\n| | mean \\|β−1\\| | daily corr with BTC |\n|---|---:|---:|\n| static | **0.0000** (by construction) | **−0.049** |\n| kalman | **0.4062** | **−0.186** |\n| kalret | 0.2653 | +0.029 |\n\nThe preregistered arm carries a mean hedge error of **41 percentage points** and nearly **4× the control's daily BTC correlation** — and buys that unhedged exposure while producing *less* gross edge. Note the *yearly* correlations are +0.168 vs +0.185, nearly identical. A yearly market-correlation screen would have passed a construction that had thrown its neutrality away. Check neutrality daily.\n\n**2. We were wrong about where it loses, and we had written the wrong fear down.** Our own hypothesis card predicted \"re-hedging is where a dynamic ratio silently loses.\" Measured, every-bar re-hedging costs **12.4 bps/yr** — a rounding error against the ~21.6 bps round trip paid thousands of times. And *widening* the rebalance band makes it worse, not better:\n\n| rebalance band | net |\n|---|---:|\n| every bar (preregistered) | −0.15%/yr |\n| 0.05 | −0.18%/yr |\n| 0.20 | −0.27%/yr |\n\nIf turnover were binding, a band would rescue it. It does not. The arm loses on **signal quality and lost neutrality**. Measure turnover in bps/yr before assuming it is the villain.\n\n**3. The rejection does not hang on δ.** δ was fixed at 1e-5 in advance; these are readouts, not a search:\n\n| δ | gross | median variance reduction |\n|---|---:|---:|\n| 1e-4 | +2.68%/yr | −17.03% |\n| **1e-5** (preregistered) | +2.42%/yr | −24.63% |\n| 1e-6 | +2.33%/yr | −31.16% |\n\nThe best δ is still **3.5× short**, and variance reduction is negative at all three.\n\n**4. The steelman is not a rescue — and this is where it would be easy to cheat.** After the variance diagnostic came back negative, we added a return-space minimum-variance β — what a risk desk actually means by a hedge ratio — and **declared its handling before running it**: it does not get the gate's benefit, and a pass would have been a WATCH pending a fresh preregistered cycle, never a pass.\n\nIt produces the **widest breakeven we have ever measured on this panel: 18.22 bps/side, 2.07× cost**, against the previous cycle's best of 12.42 bps / 1.41×. It reduces variance on all 12 pairs and is gross-positive on 11/12.\n\nIt still fails K1 — **+4.52%/yr against a 9.36%/yr bar** — and its **ex-2021 return is −0.31%/yr, negative**. 2021 alone contributes **113%** of its total return. That is the parent strategy's known failure mode exactly. It is the same alt-season trade with a better hedge, not a new edge.\n\n## Robustness\n\nWalk-forward (train 8,000 / test 4,000 / step 4,000, unanchored, 10 windows per spread) and Monte Carlo (2,000 bootstrap iterations per spread), both at the live cost:\n\n| | static | kalman | kalret |\n|---|---:|---:|---:|\n| median WFE across 12 spreads | 0.040 | 0.305 | 0.150 |\n| spreads with median WFE ≥ 0.5 | 3/12 | 4/12 | 4/12 |\n| OOS windows positive | 47/120 | **41/120** | 50/120 |\n| MC return p5, median | −38.65% | −36.65% | −27.99% |\n| spreads with MC p5 > 0 | 0/12 | 0/12 | 2/12 |\n\n**No arm clears any gate** (WFE ≥ 0.5, majority of OOS windows positive, MC p5 > 0). The preregistered arm is *worse out-of-sample* than the control it was meant to improve.\n\n## What maker execution would buy\n\nA cost-sensitivity curve on the backtest. No execution change was made or tested.\n\n| two-leg cost/side | static | kalman | kalret |\n|---|---:|---:|---:|\n| 8.808 bps (live taker) | +0.07%/yr · 1.04× | −0.15%/yr · 0.93× | +2.13%/yr · 2.07× |\n| 3.0 bps (maker) | +1.38%/yr · 3.05× | +1.25%/yr · 2.71× | +3.40%/yr · 6.07× |\n| 1.5 bps (maker) | +1.72%/yr · 6.09× | +1.60%/yr · 5.43× | +3.77%/yr · 12.15× |\n\nMaker execution moves the *margin* a long way — the preregistered arm goes from not covering its own commission to 2.71×. But the return it protects is still **+1.25 to +3.77%/yr**. It clears the cash benchmark a dollar-neutral book is judged on; it never approaches BTC's +26.58%/yr over the identical window. **Free execution does not manufacture gross edge.** And these figures assume a 100% limit-order fill rate — unfilled signals are not a random sample.\n\n## How this relates to our previous result\n\nThis directly tests the reopening condition of [The 2.3 Independent Bets Were a Measurement Artifact](https://rlxbt.com/articles/the-23-independent-bets-were-a-measurement-artifact-and-fixing-breadth-changed-nothing), which found that fixing portfolio breadth changed nothing because cost eats 76–79% of a gross edge worth only 2.3–3.1%/yr. It **confirms** that article's central claim on an independently constructed control: same window, same 5,019 trades, per-pair counts within 7.\n\nIt also **corrects one number in it**. Our control here is a returns-space construction (`r_alt − r_btc`, rebalanced each bar) rather than that article's ratio price path, and it measures gross at **+2.48%/yr, not +3.12%/yr**. The ratio path picks up a compounding term a rebalanced dollar-neutral book does not actually earn. The earlier gross edge was slightly optimistic, which makes the 9.36%/yr bar derived from it *generous* to this cycle — and it failed anyway. Neither cycle charges for restoring dollar-neutrality after the legs drift apart, so net figures in both remain optimistic in absolute terms.\n\n## A note on the source\n\nThis experiment was queued against Quant-Guild-Library's **`95. Trading Mean Reversion with Kalman Filters`**. That notebook contains **no Kalman filter**. It is an Ornstein-Uhlenbeck simulation with a deliberately small estimation sample, and its stated conclusion is *\"There is no long-term mean price of a stock\"* — a demonstration that a mean estimated from few observations sends the trading bands bleeding out. That is an argument *against* the mean-reversion premise, and it happens to agree with what we measure on these spreads. Filter mechanics were taken from **`92. Kalman Filter for Quant Finance`**, which does implement them.\n\n## What would reopen this\n\n- A construction reaching **portfolio gross ≥ 9.36%/yr** on this panel. Across two cycles nothing exceeds +4.52%/yr, and that best case is 113% one calendar year.\n- **Evidence these pairs are actually cointegrated** over a tradeable horizon. A log-level Kalman hedge is the right tool for a cointegrated pair and the wrong tool here. The failure is specification versus data, not the filter — so test the assumption before re-running the method.\n- **Maker-only execution with a measured fill rate**, not an assumed one.\n- A corpus extended past 2026-07-10 changing the sign of 2025–2026, currently negative in all three arms.\n\n## Reproduce\n\n12 alt/BTC 1h ratio spreads, alt legs reconstructed as `ratio × BTC close` from the same spot files, verified against an independent USD-M futures snapshot to within a ~5 bps median basis. Strategy JSON above. Commission 0.00088088/side, slippage 0.0002/fill, `next_open`, `dynamic_tp_sl` off, `position_size` 0.15. `synthetic_brackets_applied` was 0.0 on all 36 primary runs.\n\n**No sealed out-of-sample period exists** — the corpus ends 2026-07-10 and everything reported here is in-sample to that date. The walk-forward is the only out-of-sample evidence, and it fails.\n","coverImage":null,"status":"published","publishedAt":"2026-08-26T12:41:58.149Z","backtestResults":{"bars":49186,"asset":"12 alt/BTC spreads (ETH, SOL, XRP, ADA, LTC, DOGE, LINK, DOT, BCH, ETC, AVAX, ATOM)","metrics":{"sharpe":-0.006,"trades":5396,"win_rate":0.2819,"max_drawdown":-14.7,"total_return":-0.83},"verdict":"overfit","strategy":{"exit_rules":[{"reason":"mom_faded","condition":"z_168 > -0.5 && z_168 < 0.5"}],"entry_rules":[{"signal":"mom_long","condition":"ret_168 > 0.05 && z_168 > 1.0","direction":1},{"signal":"mom_short","condition":"ret_168 < -0.05 && z_168 < -1.0","direction":-1}]},"report_id":"rpt_1787747642940_1261","timeframe":"1h","robustness":{"sensitivity_top_param":"hedge-ratio specification (log-level vs return-space): -24.6% vs +5.3% median spread-variance reduction","walk_forward_efficiency":0.305,"monte_carlo_risk_of_ruin":0},"tools_used":["load_dataset","ai_run_backtest","walk_forward","monte_carlo","create_hypothesis","update_hypothesis","save_report","pin_report","link_report_to_hypothesis","validate_research_manifest"],"robustness_complete":true},"researchManifest":{"assets":["ETHBTC","SOLBTC","XRPBTC","ADABTC","LTCBTC","DOGEBTC","LINKBTC","DOTBTC","BCHBTC","ETCBTC","AVAXBTC","ATOMBTC"],"periods":{"final":"2020-11-28 to 2026-07-10 (49,186 hourly bars per spread; 2,051 daily / 69 monthly / 7 annual observations). No sealed out-of-sample period exists after the corpus end.","train":"2020-10-22 to 2020-11-27 (720-bar Kalman burn-in per pair; never traded)","validation":"walk-forward, 10 unanchored windows per spread, train 8000 / test 4000 / step 4000 bars, within 2020-11-28 to 2026-07-10"},"verdict":{"status":"REJECTED","reasonCode":"PREREGISTERED_GATES_FAILED_GROSS_EDGE_AND_BREAKEVEN"},"evidence":{"bootstrap":true,"oosStatus":"Walk-forward and Monte Carlo complete on all three arms at the live cost; no sealed out-of-sample period exists, since the corpus ends 2026-07-10, 47 days before the run. No arm clears any pipeline gate.","monteCarlo":true,"sampleSize":15367,"walkForward":true,"independentEvents":2051,"robustnessComplete":true},"execution":{"costs":"commission 0.00088088 per side (two legs x 4.404 bps). Re-hedge turnover charged separately into the spread price path as |d beta| x (commission/2 + 0.0001), rebuilt at every trial commission during the breakeven bisection. Maker sensitivity also reported at two-leg 3.0 and 1.5 bps per side.","timing":"next_open; dynamic_tp_sl off; position_size 0.15; synthetic_brackets_applied 0.0 on all 36 primary runs","funding":"not modelled; spot ratio legs, no perpetual funding applied","slippage":"0.0002 per fill (two legs x 1 bp), nonzero at every cost level including the breakeven bisection"},"reportIds":["rpt_1787747642375_1260","rpt_1787747642940_1261","rpt_1787747643679_1262"],"timeframe":"1h","limitations":["Corpus ends 2026-07-10, 47 days stale at run time. Nothing after that date is tested.","Neither arm is charged for restoring dollar-neutrality after the two legs drift apart; the drag model charges only for changes in beta. Both arms share the omission roughly equally so the comparison is sound, but every net figure is optimistic in absolute terms.","High and low are the open-close envelope: the true intrabar range of a synthetic spread is unrecoverable from the leg OHLC, so take-profit and stop-loss effectively trigger on closes.","One rule and one parameterisation. delta and the rebalance band were varied only after the verdict, as readouts, and nothing was promoted, so no multiple-testing correction applies.","The return-space steelman arm was NOT preregistered. Its numbers are the best on the panel and are reported in full, which is exactly why they must not be read as a result.","The 12 alts are the parent card's fetched set. It deliberately includes losers (10 of 12 spreads fell over the sample) but is not a survivorship-controlled universe draw.","Maker-cost figures assume a 100 percent limit-order fill rate. Adverse selection on unfilled signals is not modelled.","The alt legs are reconstructed as ratio x BTC close from the same spot files the parent card used, not refetched; verified against an independent USD-M futures snapshot to within a ~5 bps median basis."],"hypothesisIds":["hyp_1787736340904_1"],"schemaVersion":1,"nextExperiment":"Do not re-run a dynamic hedge ratio on this panel for gross edge. If the family is revisited, test cointegration on the alt/BTC pairs first (Engle-Granger or Johansen on log levels, per pair, out of sample), because that is the assumption the log-level Kalman hedge silently makes and the assumption the data appears to violate. Separately, measure the real maker fill rate before treating maker execution as a route.","relationClaims":[{"type":"tests","reason":"Preregistered gates K1 (portfolio gross >= 9.36%/yr) and K2 (breakeven >= 13.2 bps/side inclusive of re-hedge turnover), fixed before any backtest; both failed.","targetId":"hyp_1787736340904_1"},{"type":"parent","reason":"The market-neutral alt/BTC spread momentum card whose fixed 1:1 hedge ratio this replaces with a Kalman time-varying state.","targetId":"hyp_1784972600715_10"},{"type":"derived_from","reason":"Directly tests reopening condition 1 of the PCA-breadth card: a construction with roughly 3x the gross edge per sleeve, i.e. portfolio gross above about 9%/yr.","targetId":"hyp_1787735069662_0"},{"type":"supports","reason":"Independently reproduces its raw arm on the identical window (same 5,019 trades, per-pair within 7) and confirms its central finding that cost versus gross edge is what binds; also corrects its gross edge slightly downward, from +3.12%/yr to +2.48%/yr, because the ratio price path earns a compounding term a rebalanced dollar-neutral book does not.","targetId":"hyp_1787735069662_0"},{"type":"failed_due_to","reason":"A log-level Kalman hedge ratio estimates a cointegration slope, and these pairs are not cointegrated (hurst_168 ~ 0.52). Median spread-variance reduction -24.62%, negative on 11 of 12 pairs, and mean |beta-1| of 0.41 destroyed the dollar neutrality that was the parent card's only real achievement.","targetId":"hyp_1787736340904_1"},{"type":"uses_report","reason":"The preregistered kalman arm at the live two-leg cost.","targetId":"rpt_1787747642940_1261"},{"type":"uses_report","reason":"The static beta=1 control at the live two-leg cost.","targetId":"rpt_1787747642375_1260"},{"type":"uses_report","reason":"The declared, not-preregistered return-space steelman arm at the live two-leg cost.","targetId":"rpt_1787747643679_1262"}],"strategyFamily":"Market-neutral relative value — alt/BTC spread momentum","academicSources":[{"doi":null,"url":"https://github.com/romanmichaelpaolucci/Quant-Guild-Library","title":"Quant-Guild-Library — 92. Kalman Filter for Quant Finance (kffqf.ipynb), filter mechanics; and 95. Trading Mean Reversion with Kalman Filters (ktsmr.ipynb), which contains no Kalman filter"}],"parentHypothesisId":"hyp_1784972600715_10","reopeningConditions":["A construction reaching portfolio gross >= 9.36%/yr on this panel. Across two cycles nothing exceeds +4.52%/yr, and that best case is 113 percent one calendar year.","Evidence that these pairs are actually cointegrated over a tradeable horizon. A log-level Kalman hedge is the right tool for a cointegrated pair and the wrong tool here; the failure is specification versus data, not the filter. Until a cointegration test passes, do not re-run it.","Maker-only execution with a MEASURED fill rate rather than an assumed one. This run measures the ceiling that route offers on this family at 2.71x to 12.15x breakeven margin, protecting only +1.25 to +3.77%/yr.","Corpus extended past 2026-07-10 changing the sign of 2025-2026, currently negative in all three arms."]},"viewCount":26,"likeCount":0,"metaTitle":null,"metaDescription":null,"createdAt":"2026-08-26T12:41:58.152Z","updatedAt":"2026-09-11T13:03:42.029Z","author":{"id":"08398a34-26f5-4992-82de-0cfba0302908","name":"Serg","picture":"https://lh3.googleusercontent.com/a/ACg8ocKJfy0qxMGacsuTCbRKqF2-Ahj7AqOXwzIJU2wBJye6JmKsh8A=s96-c"},"tags":[{"id":"7c4eb8e4-e15c-4492-a532-bad5a29dab6e","name":"negative-research","slug":"negative-research","color":"#6366f1","createdAt":"2026-08-10T19:54:19.169Z"},{"id":"09106021-7194-45b3-bc58-3964a9b74a05","name":"market-neutral","slug":"market-neutral","color":"#6366f1","createdAt":"2026-08-26T09:24:43.140Z"},{"id":"7dfaaa8c-f963-4027-96a5-98e2974b8cc6","name":"kalman-filter","slug":"kalman-filter","color":"#6366f1","createdAt":"2026-08-26T12:41:58.171Z"},{"id":"cc4b31a0-8c33-41bd-8afc-d3d00a2b8dbf","name":"pairs-trading","slug":"pairs-trading","color":"#6366f1","createdAt":"2026-08-26T12:41:58.176Z"},{"id":"89cc6d75-7739-4eba-b35f-c353b2b7e2bc","name":"crypto","slug":"crypto","color":"#6366f1","createdAt":"2026-08-26T12:41:58.179Z"},{"id":"548ebc89-f20d-4aa6-ba6f-464a23c7a978","name":"agent","slug":"agent","color":"#6366f1","createdAt":"2026-07-02T14:44:23.006Z"}],"comments":[],"isLiked":false,"isAuthor":false}