← all research
REJECTED

"Edge-Hunting Research Paper: Equities & Crypto"

2026-08-26

Date: 2026-08-25 Scope: Systematic search for tradeable anomalies across equity and crypto daily/intraday data, following the repository house protocol (fixed IS/OOS splits, Monte-Carlo gauntlet for winners, one ledger entry per idea adopted or rejected). Status: 1 validated edge (long-only momentum), ~15 rejected/retracted.


Abstract

We ran a multi-round research program testing ~20 trading-edge hypotheses across equities (S&P 500 constituents, sector ETFs, crypto) and intraday (SPY/QQQ 1-minute) data. Every originally "validated" edge was subsequently invalidated by methodological bugs — and in the final round we discovered the bugs were deeper than first thought:

After all three corrections, built on a new test base (validation/framework.py

The dominant lesson: any daily or intraday result with Sharpe > ~2 should be assumed buggy until proven otherwise — and even a "clean-looking" Sharpe ~1 deserves a returns-construction audit, not just a look-ahead check.


1. Methodology

1.1 Data

1.2 House protocol

  1. Fixed IS/OOS split chosen before testing (2025-01-01 crypto, 2016-01-01 equity, 2024-01-01 intraday).
  2. Monte-Carlo gauntlet for any winner (bootstrap p on OOS mean return).
  3. One ledger entry per idea, adopted or rejected, in docs/ROADMAP.md.
  4. Fee-free assumption for intraday (user-confirmed commission-free trading); cost-sensitive where relevant.

1.3 Statistics

1.4 Critical correction — timezone

All 1-minute bars are stored in UTC. Early intraday studies used pd.to_datetime(...).dt.tz_localize(None), which left timestamps as naive UTC. Filtering hour == 9 then captured 4:00 AM EST (pre-market), not the 9:30 AM ET open. This produced a fictitious "reversal" with p = 0.002. Fix: dt.tz_convert("America/New_York") before any session windowing. After correction, every intraday effect failed OOS. All intraday reports written before the fix are retracted.

1.5 Critical correction — look-ahead in daily cross-section studies

equity_mega_momentum.py and equity_sector_rotation.py originally defined the trend gate as close[t] > SMA200[t] & ROC60[t] > 0 and gated the open-to-close return close[t]/open[t] − 1 of the same day. Since the gate depends on close[t] (available only at the day's end), using it to select that day's open-to-close trade is look-ahead bias. The original OOS Sharpe (3.65 and 3.30) were artifacts of this. Fix: shift the signal by one day (gate = gate.shift(1)) and use close-to-close returns, matching the SPY benchmark. After correction both studies fail OOS (§2.2, §2.3). Any study reporting daily Sharpe > ~2 should be suspected of this bug.

1.6 Critical correction — overlapping forward returns & return clipping

The long-short momentum study (equity_momentum_monthly.py) survived §1.4 and §1.5 but was still wrong in two subtle ways that artificially created a "validated" edge:

  1. Overlapping forward returns. Its daily portfolio return was the H-day forward return close[t+H]/close[t] − 1 booked on day t. With a daily-rebalanced portfolio this means H overlapping positions are each credited with a full H-day return, inflating the series by ~H×. This alone turns a modest factor into a Sharpe-20 monster (confirmed when the corrected framework first produced Sharpe 24–45 on the same data).
  2. Return clipping masking the explosion. The portfolio return was clipped to [−0.1, 0.1] and forward returns to [−0.5, 0.5], which bounded the inflation enough to land at a "plausible" Sharpe 0.86–0.92 — hiding the bug rather than removing it.

Correct construction (validation/framework.py::cross_section_portfolio):

With this, long-short 6-month momentum is flat/negative post-2015 (OOS Sharpe 0.15–0.44, not significant) — matching the academic finding that US equity momentum weakened after 2009. The long-only "buy winners" version, however, is a strong, robust edge (§2.1).


2. Validated Edges (PASS)

2.1 Long-Only Cross-Sectional Momentum ★ the one genuine edge

Retraction note: the earlier "six-month momentum OOS Sharpe 0.86–0.92" (equity_momentum_monthly.py, §2.1 in prior drafts) was a measurement artifact of the §1.6 bugs, not a real edge. It is superseded by this long-only result.

(superseded) Six-Month Long-Short Momentum — RETRACTED (returns-construction)

2.2 Mega-Cap Trend Ranking ★ RETRACTED (look-ahead)

2.3 Sector Rotation ★ RETRACTED (look-ahead)

2.4 Cross-Asset Crypto Rotation ★ RETRACTED (look-ahead)

2.5 Cross-Asset Momentum ★ RETRACTED (look-ahead)


3. Rejected Hypotheses (REJECT)

3.1 Intraday Opening Range Breakout (ORB)

3.2 Equity Factor Zoo — Round 2 (orthogonal factors, beta-audited)

A second, more rigorous hunt (validation/edge_hunt2.py + validation/edge_audit.py) tested factors deliberately orthogonal to momentum on the audited framework (lag≥1, next-open, dead-stock-safe), IS/OOS 2016-01-01. The long-only versions posted tempting gross OOS Sharpe (ST-reversal 1.11–1.17, low-vol 0.99–1.14, liquidity-trend 1.35, all p≤0.003) — but a beta/residual audit exposed them as pure equity beta: every factor has market-neutral residual Sharpe ≈ 0 and Beta ≈ 1, and the long-short existence test is negative everywhere (ST-reversal LS −0.05, low-vol LS −1.07, liquidity-trend LS −0.09; Momentum LS 0.10). There is no new independent, deployable factor here — these are the same long-equity beta as momentum, just re-labeled. Earlier 1-day factor-zoo results (rev1m/w, high52, size) also REJECT; vol60/beta60 "PASS" only as risk premiums.

3.3 Low-Volatility Anomaly

3.4 Vol-Regime / Shock-Day / Pullback overlays

3.5 Overnight / Turn-of-Month (TOM) — Round 2

3.6 Intraday Reversal (RETRACTED)


4. Key Lessons

  1. Timezone is everything for intraday. UTC storage + naive local handling fabricated a "significant" edge. Always tz_convert("America/New_York").
  2. Look-ahead is the silent killer of daily studies. A gate/score that uses close[t] cannot select day t's open-to-close trade. All four cross-section daily studies contained this bug — mega-cap (3.65→1.06), sector (3.30→0.97), crypto rotation (1.99→0.54), cross-asset momentum (3.19→1.04) — and every one collapsed to ~1.0 / non-significant after the fix. Any daily Sharpe > ~2 deserves immediate suspicion.
  3. Horizon matters. Momentum is invisible at 1-day holding but strong at 21-day. Test the economically-motivated holding period, not the most convenient one.
  4. Asymmetry is informative. ORB up-breakouts work, down-breakouts fail — a bull-market signature, not a genuine breakout pattern.
  5. Fat tails kill significance. A strategy can show annualized Sharpe 0.97 yet have p = 0.20 because one outlier day dominates. Bootstrap p (not normal t-test) is the honest gate.
  6. Equities >> crypto for cross-section. Every multi-asset winner is equity-dominated; crypto adds volatility, not alpha.
  7. Risk premiums ≠ anomalies. vol60/beta60 "pass" but are compensation for risk, not exploitable inefficiencies.
  8. Three bugs invalidated every "high-Sharpe" result. Timezone, look-ahead, and overlapping-returns/clipping between them accounted for all results with Sharpe > 2 — including the "surviving" six-month long-short momentum, which collapsed once its returns were constructed correctly. The one edge that survived all three audits is modest (OOS Sharpe ~1.5) — exactly what a real, tradeable edge looks like.
  9. A clean look-ahead check is necessary but not sufficient. The long-short momentum study passed the §1.5 fix yet was still broken by overlapping forward returns. Audit the construction of the return series itself, not just the signal/trade alignment.
  10. Long-only can rescue a dead long-short factor. Momentum's short leg stopped working post-2009, but the long-only "buy winners" portfolio is robust (OOS Sharpe 1.4–1.7). Dropping an unprofitable, costly short leg is a legitimate edge-refinement, not data-snooping.
  11. A long-only Sharpe ~1 in 2016–2025 is usually just beta — audit it. Round 2 showed short-term-reversal, low-vol, and liquidity-trend all posted OOS Sharpe ~1.0–1.4, yet every one had market-neutral residual Sharpe ≈ 0 and Beta ≈ 1, and long-short existence tests were ~0 or negative. The lesson now enforced in the framework workflow: before claiming any long-only factor, regress its returns on an equal-weight market benchmark; require residual Sharpe > 0 AND low correlation to existing factors. A factor that is only beta is not a new edge and will not diversify a book.

5. Conclusion — What Actually Works

EdgeOOS SharpepStatus
Long-only momentum (buy winners)1.44–1.69< 0.001PASS (equity cross-section, tradeable)
Six-month long-short momentum0.86–0.92 → 0.15–0.440.007 → 0.12–0.34RETRACTED (returns-construction)
Long-only ORB0.80–0.97~0.20borderline (intraday)
Mega-cap trend3.65 → 1.060.000 → 0.161RETRACTED (look-ahead)
Sector rotation3.30 → 0.970.000 → 0.351RETRACTED (look-ahead)
Crypto rotation1.99 → 0.540.024 → 0.241RETRACTED (look-ahead)
Cross-asset momentum3.19 → 1.040.000 → 0.084RETRACTED (look-ahead)

The single adoptable edge is LONG-ONLY cross-sectional equity momentum — buy the top decile of trailing-return winners, equal-weight, monthly rebalance, no shorting (OOS Sharpe 1.44–1.69, bootstrap p < 0.001, robust across 3–12 month lookbacks and consistent in-sample 2007–2015). It is built on the audited validation/framework.py primitives. Retracted: the earlier six-month long-short momentum (a returns-construction artifact); mega-cap trend, sector rotation, crypto rotation, cross-asset momentum (look-ahead artifacts); the entire intraday family (timezone artifact); factor-zoo 1-day; low-vol; regime/shock/pullback overlays. Borderline: long-only intraday ORB (satellite only, not statistically robust).

Recommended next step: productionize the long-only momentum edge (with transaction-cost modeling for small-cap names, since the universe is delisting-inclusive and includes illiquid issues) as the single approved strategy. Do not build on any retracted signal — they were statistical ghosts created by the three bugs above.


6. References