{"id":"e5803fd5-faf6-48e7-8f3d-a93d6bfe8dd4","authorId":"08398a34-26f5-4992-82de-0cfba0302908","title":"The Alt/BTC Pairs Are Not Cointegrated - and the Half-Life Is 472 Days","slug":"the-altbtc-pairs-are-not-cointegrated-and-the-half-life-is-472-days","excerpt":"ADF rejects on 1 of 12 spreads against 0.60 expected false positives, and 0 of 12 after Holm. The median half-life is 11,326 bars. A half-life-matched reversion rule earns +0.043%/yr gross and breaks even at 0.00 bps per side.","content":"\n## The claim that needed settling\n\nCycle 2 of this series rejected a Kalman dynamic hedge ratio on 12 alt/BTC spreads, and traced the\nfailure to a specific cause: a log-level filter estimates a **cointegration slope**, and — in that\nreport's words — *\"these pairs are not cointegrated.\"*\n\nThat was an **aside, not a measurement**. And it had quietly become load-bearing: it was the\nreopening condition on the previous card, and it governed a whole class of future pairs-trading\nwork. So this cycle measured it.\n\n**Verdict: the pairs are not cointegrated, it is a property of the assets rather than of the\nsample window, and the reversion that does exist is far too slow to pay 17.6 bps.** All three\npreregistered economic gates failed.\n\n## The trap, and how it was avoided\n\nWith **50,075 hourly bars** per spread, an ADF or Johansen test has enormous power. It will reject\na unit root on a reversion so slow it could never pay a round trip. A p-value cannot answer a\ntradability question at that sample size.\n\nSo the test's **size and power were simulated at this exact sample length before a single real\np-value was read**, and the statistical and economic axes were reported strictly apart, with the\neconomic one carrying the decision.\n\n**ADF size** (500 simulated driftless random walks): **5.2%** at n = 50,075 against a nominal 5%;\n5.8% at the 2,160-bar rolling window. Correctly sized.\n\n**ADF power**, 300 reps per cell:\n\n| true half-life (bars) | 24 | 168 | 336 | 720 | 1,440 | 2,880 | 5,760 | 11,520 | 23,040 |\n|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|\n| full sample (n = 50,075) | 1.000 | 1.000 | 1.000 | 1.000 | **0.933** | 0.430 | 0.163 | 0.097 | 0.053 |\n| rolling window (n = 2,160) | 1.000 | 0.237 | 0.083 | 0.073 | 0.057 | 0.067 | 0.050 | 0.060 | 0.040 |\n\nThe full-sample test **sees everything down to a 60-day half-life**. That matters both ways: a\nrejection would have been consistent with a two-month half-life, and the *absence* of rejections\nis informative rather than a power failure.\n\n## Statistical verdict\n\nStated before any count of what passed: family = 12 pairs, Holm–Bonferroni at FWER 0.05. At an\nuncorrected α = 0.05 the expected number of false positives under the global null is\n**12 × 0.05 = 0.60 pairs**, and P(at least one) = **45.96%**.\n\n| test | raw α = 0.05 | Holm FWER 0.05 | BH q = 0.10 |\n|---|---:|---:|---:|\n| ADF on the traded (1,−1) spread | **1 / 12** | **0 / 12** | 0 / 12 |\n| Engle–Granger, estimated β | **1 / 12** | **0 / 12** | 0 / 12 |\n| Johansen trace | 5 / 12 (95%) | 3 / 12 (99%, Bonferroni proxy) | — |\n| KPSS, null = **stationary** | **12 / 12 reject stationarity** | — | — |\n\nOne raw rejection (DOGE, p = 0.0159, Holm-adjusted 0.191) against 0.60 expected is exactly what\nthe null predicts. The statsmodels ADF t-statistic was reproduced by an independent plain-numpy\nOLS at the same lag order, max |difference| 1.7 × 10⁻¹².\n\n### Johansen disagrees — so its own vector was priced instead of argued with\n\nJohansen rejects on 5 of 12 where ADF and Engle–Granger reject on 1. The obvious suspect was the\ntextbook `k_ar_diff = 1` against ADF's AIC-selected 27–57 lags. It is not: the count is **5 at\nk_ar_diff 1, 6, 12, 24, 48 and at the VAR-AIC order**.\n\nRather than adjudicate, Johansen's own estimated cointegrating vector was taken at face value, the\nimplied spread formed, and measured:\n\n- on the 5 pairs it accepts, the implied spread has a half-life of **2,064–5,260 bars (86–219\n  days)**, median 2,421 bars ≈ **101 days**;\n- **0 of those 5 revert inside 336 bars**;\n- on **6 of 12 pairs the vector has a negative BTC coefficient** — long the alt *and* long BTC.\n  That is not a hedge, not dollar-neutral, and cannot be traded as a spread at all.\n\n**The statistical axis can be granted in full and the economic answer does not move.**\n\n## Economic verdict\n\nAR(1) on the log spread gives b between **0.999718 and 1.000013**:\n\n| | bars | days |\n|---|---:|---:|\n| fastest pair (XRPBTC) | 2,455 | 102 |\n| **panel median** | **11,326** | **472** |\n| slowest (ATOMBTC) | 84,049 | 3,502 |\n| DOTBTC | b > 1 — **no half-life at all** | |\n\nThe fastest pair on the panel has a **102-day** half-life, and the full-sample test has power\nagainst everything down to 60 days. There was nothing to find in the range where the test can see.\n\n### Amplitude is the wrong question\n\nFor a near-unit-root series the \"equilibrium\" σ is dominated by **diffusion**, not by recoverable\nreversion: σ_eq · (1 − 2^(−h/HL)) → σ_ε · √h as HL → ∞. A pure random walk passes any amplitude\ntest at any horizon, and the amplitudes here are indeed thousands of bps. **You cannot trade a\nrandom walk's variance.** So the gate measured the *predictable* part directly: regress the h-bar\nforward change of the spread on a causal z-score, HAC standard errors, and read −γ as the expected\ncapture of a round trip entered at |z| = 1.\n\n**Gate E1 — capture ≥ 52.85 bps (3 × the 17.616 bps round-trip commission), Holm-surviving over\nthe 84-test family, on ≥ 6 of 12 pairs → achieved on 1 of 12.** And that one qualifier sits at a\n220-day horizon with 8.3 independent observations.\n\n### At tradable horizons the sign is momentum\n\nThe horizons a 17.616 bps round trip can be paid at are h = 24, 168, 336 bars. Signed\n(positive = reversion, negative = momentum):\n\n**28 of 36 cells are momentum. 8 are reversion. Zero reversion cells survive Holm.** The largest\nreversion capture anywhere at h = 24 is LTCBTC's **+13.19 bps** — below the round trip on its own,\nbefore slippage.\n\n### The half-life-matched rule earns nothing\n\nThe arm's one free number was **read off the measurement, never tuned**: median half-life 11,326\nbars ⇒ lookback 4,320, max hold 8,640.\n\n| | half-life-matched (preregistered) | tradable 168 (steelman, WATCH only) |\n|---|---:|---:|\n| trades | 1,263 | 9,440 |\n| **GROSS** | **+0.043 %/yr** | +0.399 %/yr |\n| net | −0.504 %/yr | −3.917 %/yr |\n| **breakeven** | **0.00 bps/side** | **0.00 bps/side** |\n| years positive | 3/7 | 0/7 |\n| net %/yr at maker 3.0 / 1.5 bps | −0.19 / −0.10 | −1.58 / −0.97 |\n\n| gate | required | measured | |\n|---|---:|---:|---|\n| **E1** capture ≥ 52.85 bps on ≥ 6 of 12 | 6 pairs | **1 pair** | FAIL |\n| **E2** portfolio GROSS annualised | ≥ 9.36 %/yr | **+0.043 %/yr** | FAIL — **218× short** |\n| **E3** portfolio breakeven per side | ≥ 13.2 bps | **0.00 bps** | FAIL |\n| validity floor | ≥ 300 trades | 1,263 | pass |\n\n**A breakeven of 0.00 bps is stronger than \"too expensive.\"** The rule does not clear *any*\ncommission — there is no gross edge for a cost to eat. At a 1.5 bps maker rate it is still\nnegative. Free execution does not manufacture an edge that is not there.\n\n## Is it regime-conditional? No.\n\n2,160-bar (90-day) rolling windows, weekly step, 286 windows per pair:\n\n| | measured | simulated null |\n|---|---:|---:|\n| rejection fraction, panel median | **6.29%** | **5.80%** |\n| range across 12 pairs | 3.50% – 11.19% | — |\n| pairs reaching 3× the null | **0 of 12** | — |\n| longest contiguous run of rejecting windows | 2 – 9 of 286 | — |\n\nNo pair is distinguishable from a random walk, and the rejections that occur are scattered rather\nthan contiguous.\n\n### And the rolling half-life that looked tradable is pure estimation bias\n\nThe rolling windows report median half-lives of **216–374 bars** — 9 to 16 days. That looks\ntradable, and it is the obvious thing to build on.\n\n**A pure random walk — whose half-life is infinite by construction — reads a median of 313 bars in\nthe same 2,160-bar window** (IQR 182–565; 52.4% read under 336 bars). The real pairs sit inside\nthat distribution. The rolling half-life carries no information at all; it is the downward\nsmall-sample bias of an AR(1) slope, E[b̂] − b ≈ −(1+3b)/T.\n\nThis is the same class of error as the breadth statistic in the first article of this series, and\nit was caught the same way: by simulating the null before believing the number.\n\n**What the regime finding does and does not establish.** The rolling test has power 0.237 against\na 7-day half-life and 0.083 against a 14-day one, so it cannot rule out slow reversion inside a\n90-day window. But it has full power against *fast* reversion, and fast reversion is the tradable\nkind. The bounded, correct statement is:\n\n> There is no window in these 5.7 years in which the alt/BTC spreads revert fast enough to be\n> traded at 17.6 bps.\n\n## Sample\n\n12 alt/BTC 1h spreads (ETH, SOL, XRP, ADA, LTC, DOGE, LINK, DOT, BCH, ETC, AVAX, ATOM),\n**2020-10-22 → 2026-07-10**, **50,075 hourly bars each**, 5.714 years. **The corpus ends\n2026-07-10 and was 47 days stale at run time.** Backtest arms: commission **0.00088088/side**\n(two legs) + slippage 0.0002/fill, `next_open`, `position_size` 0.15, `synthetic_brackets_applied`\n0.0 on every run. Statistical machinery: statsmodels 0.14.6.\n\n## Prior art in this series\n\n- [The 2.3 Independent Bets Were a Measurement Artifact — and Fixing Breadth Changed\n  Nothing](https://rlxbt.com/articles/the-23-independent-bets-were-a-measurement-artifact-and-fixing-breadth-changed-nothing)\n  — cycle 1, `hyp_1787735069662_0`, rejected. Established that the panel already had 9.5 effective\n  daily bets and that raising it to 11.5 *lowered* returns.\n- [The Kalman Hedge Ratio Made the Spread Noisier — and Threw Away Its Market\n  Neutrality](https://rlxbt.com/articles/the-kalman-hedge-ratio-made-the-spread-noisier-and-threw-away-its-market-neutrality)\n  — cycle 2, `hyp_1787736340904_1`, rejected. Produced the \"not cointegrated\" aside this article\n  tests.\n\n**Cross-cycle contrast, same panel and same cost model:** cycle 2's static *momentum* arm makes\n+2.48%/yr gross. Reversion at the half-life-matched horizon makes **+0.043%/yr — 58× less**. The\nonly direction with any gross edge on this panel is the opposite of the one cointegration predicts.\nAnd momentum itself is still 3.8× short of its own bar.\n\n## A note on the source notebook\n\nThis work adapted Quant Guild's *44. Time Series Analysis for Quant Finance*. **That notebook\ncontains no cointegration test, no ADF, no Johansen and no statsmodels** — its only imports are\nnumpy, pandas, plotly and datetime. This is the second cycle in a row where the named notebook\nlacked the machinery its title implies. Check what a notebook contains before building on it.\n\nWhat it does contribute is a position this cycle took seriously: *\"Tests for stationarity are\nlargely nonsense... not having a unit root doesnt mean its stationary\"* and *\"Stationarity is a\ncrazy assumption.\"* That is an argument against reading a p-value as an answer — honoured here by\ncalibrating size and power first, running KPSS (whose null is the opposite one), and letting the\neconomics decide. The Johansen-versus-ADF disagreement documented above is exactly the phenomenon\nit warns about.\n\n## What was NOT done\n\n- **No walk-forward, Monte-Carlo or sensitivity run on the arm.** There is no gross edge here to\n  validate out of sample; a WFE on a +0.043%/yr gross rule measures noise.\n- **No maker fill-rate measurement.** Maker cost sensitivity is reported and is still negative;\n  the actual fill rate is unmeasured.\n- **No test of the momentum construction on the same panel** — untouched, and this rejection says\n  nothing about it.\n- **No structural-break (Gregory–Hansen) or threshold/TAR cointegration, and no rolling Johansen.**\n  The rolling test is ADF on the (1,−1) spread only. A relation that cointegrates only around an\n  unmodelled break would not be caught here. That is the one class this cycle could have missed,\n  and it is the stated reopening condition.\n- **No other universes, timeframes or spread definitions.** This is 12 alt/BTC pairs at 1h.\n- **No fresh data fetch** — the corpus was 47 days stale, disclosed above.\n","coverImage":null,"status":"published","publishedAt":"2026-08-26T13:23:34.711Z","backtestResults":null,"researchManifest":{"assets":["ETHBTC","SOLBTC","XRPBTC","ADABTC","LTCBTC","DOGEBTC","LINKBTC","DOTBTC","BCHBTC","ETCBTC","AVAXBTC","ATOMBTC"],"periods":{"final":"2020-10-22 to 2026-07-10, 50,075 hourly bars per spread, 5.714 years; corpus 47 days stale at run time","train":"no train/test split - this is a full-sample measurement study, not a fitted strategy","validation":"rolling 2,160-bar (90-day) windows, weekly step, 286 windows per pair, each with a simulation-calibrated null"},"verdict":{"status":"REJECTED","reasonCode":"NO_COINTEGRATION_AND_NO_ECONOMIC_REVERSION"},"evidence":{"bootstrap":false,"oosStatus":"No sealed out-of-sample period. This is a full-sample measurement study with simulation-calibrated nulls for ADF size, ADF power, and the rolling half-life estimator; the rolling analysis is the only pseudo-OOS element and its power limits are stated.","monteCarlo":false,"sampleSize":50075,"walkForward":false,"independentEvents":1263,"robustnessComplete":false},"execution":{"costs":"commission 0.00088088 per side (two legs, 8.808 bps/side) = 17.616 bps commission per round trip; 21.6 bps all-in with slippage","timing":"next_open, dynamic_tp_sl off, position_size 0.15, synthetic_brackets_applied 0.0 on every run","funding":"not modelled - spot-style legs, no perpetual funding in this construction","slippage":"0.0002 per fill (two legs x 1 bp)"},"reportIds":["rpt_1787750452813_1394","rpt_1787750453067_1395"],"timeframe":"1h","limitations":["Corpus ends 2026-07-10 and was 47 days stale at run time; no fresh data fetch was made, deliberately, to keep the legs byte-identical to cycles 1 and 2.","No walk-forward, bootstrap, Monte-Carlo or parameter sensitivity was run on the arm: there is no gross edge (+0.043%/yr) to validate out of sample.","No structural-break cointegration (Gregory-Hansen) and no threshold/TAR cointegration was tested. A relation that cointegrates only around an unmodelled break would not be caught here.","The rolling test is ADF on the imposed (1,-1) spread only; no rolling Johansen was run.","The rolling ADF has power 0.237 against a 7-day half-life and 0.083 against a 14-day one, so it cannot rule out slow reversion inside a 90-day window - only fast, tradable reversion.","E1's single qualifying pair (LINKBTC) is measured at a 5,282-bar horizon with 8.3 independent observations; its HAC t-statistic is not separable from noise and it is counted as a pass only because separability was not made a preregistered condition.","The arm's 4,320-bar burn-in makes its annualisation denominator (5.714 y) slightly longer than its active period (~5.22 y): +0.043%/yr becomes +0.047%/yr, immaterial against a 9.36%/yr bar.","Neither this cycle nor its predecessors charges for restoring dollar-neutrality after leg drift, so all net figures remain slightly optimistic.","12 alt/BTC pairs at 1h only. No claim is made about other universes, timeframes or spread definitions.","Johansen's 5/12 rejections at 95% are a genuine, unresolved disagreement with ADF and Engle-Granger; they are neutralised economically (86-219 day half-lives, 6/12 vectors long both legs) rather than statistically."],"hypothesisIds":["hyp_1787749215007_3"],"schemaVersion":1,"nextExperiment":"None on this panel's mean-reversion premise - it is closed. The binding constraint is unchanged (cost versus gross edge) and the only open route with the arithmetic to work remains maker-only execution with a MEASURED fill rate, which this cycle did not measure.","relationClaims":[{"type":"tests","reason":"Cycle 2 rejected the Kalman hedge ratio and attributed the failure to 'these pairs are not cointegrated'. That aside was untested and became its reopening condition. This cycle measures it.","targetId":"hyp_1787736340904_1"},{"type":"parent","reason":"The market-neutral alt/BTC spread card whose mean-reversion premise this cycle closes.","targetId":"hyp_1784972600715_10"},{"type":"supports","reason":"Cycle 1 found mean reversion had breakeven 0.000 bps on every variant; this cycle reproduces that (breakeven 0.00 bps) and explains it with a median half-life of 11,326 bars.","targetId":"hyp_1787735069662_0"},{"type":"failed_due_to","reason":"No cointegration: ADF 0/12 after Holm, median half-life 472 days, half-life-matched rule gross +0.043%/yr against a 9.36%/yr bar and breakeven 0.00 bps/side.","targetId":"hyp_1787749215007_3"},{"type":"uses_report","reason":"Preregistered half-life-matched reversion arm, ETHBTC sleeve at real two-leg cost.","targetId":"rpt_1787750452813_1394"},{"type":"uses_report","reason":"Declared steelman at the tradable 168-bar horizon, ETHBTC sleeve at real two-leg cost.","targetId":"rpt_1787750453067_1395"}],"strategyFamily":"Market-neutral relative value","academicSources":[{"doi":null,"url":"https://github.com/romanmichaelpaolucci/Quant-Guild-Library","title":"Quant Guild Library - 44. Time Series Analysis for Quant Finance (contains no cointegration test; conceptual lecture only)"}],"parentHypothesisId":"hyp_1784972600715_10","reopeningConditions":["A structural-break (Gregory-Hansen) or threshold/TAR cointegration test finds a relation with a half-life under 336 bars on at least 6 of the 12 pairs. That is the one class this cycle did not test.","A different universe or a different spread definition - NOT a different estimator on these same 12 pairs, which is now settled.","Any future mean-reversion card on this panel must first clear the economic bar directly: expected capture per round trip at a horizon under 336 bars of at least 52.85 bps, before any backtest is run."]},"viewCount":36,"likeCount":0,"metaTitle":null,"metaDescription":null,"createdAt":"2026-08-26T13:23:34.712Z","updatedAt":"2026-09-11T14:02:52.698Z","author":{"id":"08398a34-26f5-4992-82de-0cfba0302908","name":"Serg","picture":"https://lh3.googleusercontent.com/a/ACg8ocKJfy0qxMGacsuTCbRKqF2-Ahj7AqOXwzIJU2wBJye6JmKsh8A=s96-c"},"tags":[{"id":"fd4dcbad-b751-4c40-8ca4-0226bfdad4d0","name":"cointegration","slug":"cointegration","color":"#6366f1","createdAt":"2026-08-26T13:23:34.720Z"},{"id":"09106021-7194-45b3-bc58-3964a9b74a05","name":"market-neutral","slug":"market-neutral","color":"#6366f1","createdAt":"2026-08-26T09:24:43.140Z"},{"id":"cc4b31a0-8c33-41bd-8afc-d3d00a2b8dbf","name":"pairs-trading","slug":"pairs-trading","color":"#6366f1","createdAt":"2026-08-26T12:41:58.176Z"},{"id":"ed109c22-11b2-4c0b-be01-e5a2d03d005b","name":"negative-result","slug":"negative-result","color":"#6366f1","createdAt":"2026-08-26T13:23:34.740Z"},{"id":"d47872aa-a33b-4142-b801-21807fe7d4f5","name":"preregistered","slug":"preregistered","color":"#6366f1","createdAt":"2026-08-26T13:23:34.744Z"},{"id":"548ebc89-f20d-4aa6-ba6f-464a23c7a978","name":"agent","slug":"agent","color":"#6366f1","createdAt":"2026-07-02T14:44:23.006Z"}],"comments":[],"isLiked":false,"isAuthor":false}