mistakes/ · public postmortems

What I got wrong.

A research book that ships nine winners and hides the failure modes is a book primed for selection bias. Below are five real failures from the quant pipeline — what was wrong, which gate caught it, what I repaired, and what the discipline is for. NDA-safe. Public data.

A book is only as honest as its weakest postmortem. The minimum of wins and postmortems is the binding constraint.

  1. M01
    Project 09 — Look-ahead bias audit
    2026-06-18
    critical

    Shipped a backtest with a 1-bar forward shift. Looked like a 5.07 Sharpe.

    What was wrong

    While refactoring a momentum signal pipeline, I accidentally left a `.shift(-1)` on the signal column for two days. The "result" Sharpe was 5.07. The strategy was nonsense — every "trade" was using tomorrow's signal today.

    Which gate caught it

    G21–G25 (look-ahead discipline, point-in-time verification)

    Repair

    Wrote project 09 as the canonical one-line shift test. The leaked-Sharpe was 5.07; the real Sharpe after removing the shift was 0.55. The phantom edge was 88% of the apparent alpha. The test now runs as a pre-ship gate on every backtest.

    Lesson

    A 5.07 Sharpe is not a feature. A 5.07 Sharpe that survives a one-line shift test is not, in fact, surviving — it is lying. The shift test is now mandatory. There is no "we'll just be careful next time."

  2. M02
    Project 02 — Cross-sectional momentum (18 coins)
    2025-10-15
    high

    In-sample Sharpe 0.91 in cross-sectional momentum. Out-of-sample Sharpe −0.03.

    What was wrong

    18 BTC-correlated altcoins, ranked by 14-day return, long top decile, short bottom decile. IS Sharpe 0.91. The OOS Sharpe was −0.03. Bootstrap CI [−0.12, +0.18] straddles zero — cannot reject the null.

    Which gate caught it

    G11–G15 (locked OOS windows, pre-registration, frozen-spec evaluation)

    Repair

    Reported both numbers, side by side. The "honest decay" framing in the project writeup replaced what would have been a published-only-IS-Sharpe story. The bootstrap CI was reported with the bound, not as a one-sided significance test.

    Lesson

    Cross-sectional dispersion in a tightly-correlated universe (BTC-altcoin beta ≈ 1) is too small a signal to overcome rebalance friction at 14-day cadence. Project 05 (pairs via cointegration) is the *first* gate for stat-arb in this universe; cross-sectional momentum is downstream. The right order would have caught this earlier.

  3. M03
    Project 05 — Pairs via cointegration
    2026-02-18
    medium

    BTC/ETH spread: looked like a textbook stat-arb. ADF said no.

    What was wrong

    BTC and ETH are the most obvious pair in crypto. The textbook trade is to hedge, fade the spread, collect mean-reversion. The ADF test statistic was −2.11. Critical value at 5% is ≈ −2.86. Spread has a unit root; the trade is not stationary. Half-life 208 days. OOS Sharpe ≈ 0.

    Which gate caught it

    G1–G5 (mechanical validity), G6–G10 (statistical nulls)

    Repair

    Did not ship the trade. Shipped the rejection, with the ADF statistic and the half-life. The project is a published counter-example to the assumption "BTC and ETH are cointegrated."

    Lesson

    Stat-arb starts with the cointegration test, not with the trade. If the spread isn't stationary, no position-sizing rule will save it. Project 05 is the pre-trade filter for projects 02 and 06.

  4. M04
    Project 06 — Crypto funding carry
    2026-04-05
    medium

    Fade-funding trade IS Sharpe 1.11. OOS Sharpe −0.05. Alpha decayed post-2023.

    What was wrong

    The textbook perpetual-swap carry trade is to fade funding (short when funding > 0). IS Sharpe was 1.11. OOS Sharpe was −0.05. The carry was real (+11.9% annualized), but the trade that captured it was systematically arbitraged away as the participant mix shifted.

    Which gate caught it

    G11–G15 (locked OOS windows, 5-era stability)

    Repair

    The OOS window was locked before data was touched. The decay was visible in the rolling OOS-Sharpe trace — Sharpe 1.11 → 0.91 → 0.71 → 0.42 → 0.04 → −0.05 over the rolling window. The "carry is real, trade is dead" conclusion was honest.

    Lesson

    Carry signals are observable, regularly-paid, and visible to anyone with the data — which means they crowd fast. Pre-registering the OOS window before touching the data is what makes this a study and not a justification.

  5. M05
    Project 01 — Multiple testing / deflated Sharpe
    2025-09-20
    low

    First DSR pass on project 01: forgot γ₃·SR̂ term. Decoy result.

    What was wrong

    When implementing the Deflated Sharpe Ratio from the Bailey & López de Prado 2014 paper, I first wrote the simpler form: DSR = (SR̂ − E[max SR]) / σ_SR̂. The paper's full form has the higher-moment correction: (1 − γ₃·SR̂ + (γ₄·SR̂² − 1)/4) under the radical. Without it, returns with non-zero skew/kurtosis inflate the denominator and DSR is overstated.

    Which gate caught it

    G6–G10 (parameter-prior sensitivity, Monte-Carlo coverage)

    Repair

    Re-derived the formula from the paper's full expression. Added γ₃ and γ₄ to the calculator inputs as defaults (0, 3) with a comment that real-data estimates are recommended. The interactive DSR calculator on /methodology ships the full form.

    Lesson

    When the paper gives you a higher-moment correction, the higher-moment correction is the paper. The simplified form is for textbook examples. Always read the equation, never paraphrase it from a Stack Overflow answer.

What this page is not

Negative space as design.

This page is not self-flagellation, and it is not a humility performance. It is a record of the failure modes the gate stack is built to catch. If a gate didn't catch the failure, the gate gets updated; the failure gets logged. There is no "we'll be more careful next time" — there is a pre-ship test.

  • I am not above shipping a 5.07 phantom Sharpe — that is exactly the failure mode the gates exist to prevent.
  • I am not claiming the gate stack catches everything — there are 31 gates and they fail closed on the obvious ones; the subtle ones come later.
  • I am not hiding any failures that I am aware of — if a postmortem would change your hire/no-hire, it is on this page.
  • I am not interested in "fake failure" stories — these are real failures from the actual pipeline, with the actual numbers.

Want the failure log for a specific strategy?

If you have a written spec, send it. I'll send back which of G1–G31 already apply to your stack, which ones would catch your last failure, and which I'd build.