← Research log

We found an edge, then noticed we had tested it on the data we tuned it on

This is a negative result, written up at the length a positive one would get. It took about four hours and went through two complete reversals, both of them mine.

It started as the opposite finding

Our live data said pre-market entries were the worst trades we took. The bot's cron fires every 15 minutes from 13:00 UTC, but the US cash session does not open until 13:30 — so two of its roughly 32 daily cycles run before the bell. We measured our market-data feed and found it carried a bar for only 27–33% of those two slots, against 100% for every slot from 13:30 to 19:45.

Then we checked what those slots had actually done. 36 of 335 entries — 11% — were taken pre-market, and they gave back 16.63 of the 42.14 points the other 298 made. Eleven percent of trades, in the window where the feed was thinnest, destroying 39% of gross return.

The obvious fix was to gate the hour. We were about an hour from doing it.

The backwards test said the opposite

Before changing anything we replayed the frozen rules over 4.7 years of consolidated data — the proper feed, not the one the bot sees. If pre-market is simply a bad time to trade this rule, it should look bad there too.

CohortnExpectancy per tradeTotal
Pre-market (13:00 / 13:15)273+0.797+217.7
Regular session2,253+0.052+116.9

The reverse of what we had seen. On clean data, 11% of the trades produced 65% of the total return — in exactly the window our own feed was blind. The fix we were about to ship would have deleted the best part of the strategy.

Then the control, which it passed

A cohort can look strong simply because being in the market at that hour pays. The test that separates exposure from signal is a control that draws entries at random in the same slots, with identical position limits, exits and cadence.

Over the full period our rule landed on the 97.5th percentile of 40 control runs, z = 2.21. Meanwhile the strategy as a whole sat on the 50th percentile — z = 0.02, exactly average. So: no edge anywhere, except apparently in this one window.

At this point we believed it.

And then the year-by-year cut

YearnExpectancyt
202287+0.3580.95
202350+0.9692.62
202440−0.078−0.11
202554+0.6371.55
202642+2.5436.89

2026 is not a fifth year of evidence. The entry rule's parameters were fixed in August 2026 using 2026 data — that is precisely why replaying 2022–2025 counts as out-of-sample. 2026 is in-sample, and it carries 106.8 of the cohort's 217.7 points from 15% of its trades, at an 83.3% win rate and a profit factor of 10.73. Numbers like that are not an edge; they are a description of the data the parameters were drawn from.

So we removed it and ran the control again on 2022–2025 alone.

WindownRuleControl meanPercentile
2022–2026 (all)273+0.797+0.13997.5th
2022–2025 (out-of-sample)231+0.480+0.03692.5th

92.5th percentile, z = 1.38. Below the threshold we had set before looking. The finding does not hold.

What survives

Directionally positive, not significant. The honest summary is that we do not have evidence for this.

The pattern underneath all three reversals

In one afternoon we were wrong about the same thing three times: the sampling cadence our own harness reported, whether a 96% feed-agreement rate was reassuring, and this. Every one had the identical shape — read an aggregate, fail to ask how it was distributed, act on the headline.

The distribution is where the answer lives. An agreement rate that clusters on volatile days is not the same as one spread evenly. A five-year expectancy carried by the year you fitted on is not a five-year expectancy. The aggregate will not tell you which one you have, and it will look identical either way.