This article documents a quantitative research project whose outcome is: the hypothesis is false, don't trade this. I publish it for a precise reason: in trading education, the negative result doesn't exist — nobody sells a course titled "this doesn't work, I checked". Yet the ability to produce reliable "no"s, quickly and at near-zero cost, is more valuable than any single strategy: every "no" from three hours of compute is an account not burned and three months of development not wasted.
The hypothesis to test was the most popular on the planet: price action patterns (long-shadow rejections, extended-body breakouts) have tradable predictive power on 5-minute Bitcoin. Half of trading YouTube lives on this premise. Let's see what the data says when interrogated with method.
The experimental design
Data: BTCUSDT spot, 5-minute bars, two years: 210,240 bars, downloaded with the Binance API. Before any test, the integrity audit: zero duplicates, zero gaps, zero OHLC violations — and the normalization of 148,608 timestamps the feed delivered in microseconds instead of milliseconds. The kind of silent defect that, uncorrected, misaligns features and manufactures phantom edges. Rule: the data audit comes before the hypothesis.
Leak-free features: body/shadow ratios, close position in range, return, ATR and volatility/volume regime on rolling windows, taker buy ratio, breakout flags on shifted windows — every value computable only with the closed bar.
Patterns tested: rejection with lower shadow ≥60% of range (long); its upper mirror (short); momentum breakout with body ≥65% in both directions; plus the baseline — all bars, always long — as control group: any pattern must beat it, not zero.
Outcomes: forward returns over 1 to 48 bars, net of 6.5 bps round-trip cost; in parallel, triple barrier with stop/target in ATR multiples. Rigid split: in-sample development, verdict on the final 6 untouched months.
The results, without anesthesia
Test 1 — Directional edge
Across every pattern and horizon, the net edge is ≈ −6.5 bps: i.e., the gross edge is ≈ zero — the net coincides with the cost alone. The best gross value of the entire scan: 1.285 bps in-sample, flipping sign out-of-sample. No pattern beats the baseline. Signal-to-cost ratio: ~1:30.
Test 2 — Conditional edge (the "AI filter" test)
Standard objection: "the pattern alone no, but filtered by volatility/volume/session/order flow…". Tested systematically: buckets by volatility regime, volume regime, taker buy ratio, hour of day; both directions; three horizons. Zero buckets with gross edge above costs robust across IS and OOS.
Test 3 — Triple barrier
All 24 stop/target/time configurations in ATR: profit factor under 0.65, net loss per trade between −6 and −8 bps, IS and OOS concordant. With zero drift, barriers give PF≈1 gross, hence <1 after costs: dynamic management doesn't create an edge that isn't there — the same theorem that applies to your trailing stops.
Test 4 — Order flow as the primary signal
Analysis promoted from patterns to flow: per-bar OFI, cumulative delta, multi-bar net flow, flow/price divergences — eight signals, both directions, four horizons. Outcome: gross between −1.7 and +2.0 bps flipping sign between IS and OOS — the noise signature again. Diagnosis: aggregated taker flow on 5-minute bars is too coarse a proxy; real order-flow information lives at tick/book level and low latency — not coincidentally, the domain of the latency arbitrage bot.
How to read a "no"
Four independent tests, one converging conclusion, with declared caveats (overlapping returns inflate t-stats — but against the already-rejected hypothesis; the cost model excludes spread and slippage — so reality is even worse than the test). This is a quality "no": not "I found nothing", but "I searched with adequate statistical power, in the right places, and I can quantify how much the nothing is nothing" — the signal, if it exists, is under 1.3 bps gross against a 6.5 bps toll.
And a "no" like this produces directions: directional edge on fast bars at retail costs doesn't exist → move up in horizon or change the signal's nature; order flow pays only where it's native → invest in the structural engine; the carry hypotheses remain — perpetual funding and basis, which don't require predicting direction but collecting a premium.
A healthy research process is a funnel that kills quickly, at every floor, and lets rise only what has proven to deserve it. If your funnel promotes everything that enters it, it's not a funnel: it's a pipe.
The complete pipeline to replicate this kind of research on your own hypotheses: Python + Binance API, the guide.