NOTE 0014 / RESEARCH
The best of 1,000 coin flips beat my best trading rule
I spent a long stretch looking for a tradeable edge in foreign-exchange bar data. I did not find one. This is what I measured on the way to admitting that, because the measurements are more useful than the conclusion and almost nobody publishes them.
The last one is the reason for the title. I generated a thousand strategies that read no prices at all — they decide by coin flip — and ran them over the same 28 instruments and 3,113 daily bars as everything else.
tried best so far median so far
------------------------------------------
1 824.40 824.40
10 1067.65 93.35
50 2194.70 -319.20
100 2194.70 -132.20
500 2447.70 -405.70
1000 2862.55 -392.40
the best rule this crate actually found, on these bars
cross-sectional momentum, 20-day 944.30
it beats 901 of 1000 coins (90th percentile)
The median coin loses, which is what costs do. But the best coin made 2,862 by reading nothing, and the best rule I found by reading everything made 944. My real result sits at the 90th percentile of pure noise — good enough to look like something, and reachable by flipping a coin a thousand times and keeping the luckiest run.
Every configuration you try raises the score a result has to clear before it means anything, and it raises it faster than a weak edge grows.
How the harness was set up
Everything below runs walk-forward on a single carried account: the folds are sequential, the balance persists across them, and a risk gate refuses orders that would breach a daily or lifetime loss limit. That last part matters more than it sounds. A gate changes which trades happen at all, so a configuration can be profitable small and never reach its good trades large. Sizing is not a multiplier you apply at the end.
Costs are charged per fill from the instrument's contract terms rather than assumed. A round trip pays the spread once, and commission is per lot, per side.
1. Does the rule make money
Nine series, 1,764 trades, three cost models:
series trades no costs retail raw + comm -------------------------------------------------------------- EURUSD_M15 214 1000.00 874.75 573.92 GBPUSD_M15 281 3515.25 3155.50 2960.44 AUDUSD_M15 205 -1242.25 -1503.75 -1654.62 NZDUSD_M15 166 -384.25 -757.75 -716.89 USDCAD_M15 244 -2340.00 -2549.16 -2815.70 EURUSD_H1 200 750.00 595.50 351.42 GBPUSD_H1 211 1125.00 932.75 705.22 AUDUSD_H1 111 625.00 515.00 404.18 USDCAD_H1 132 720.00 642.24 466.64 -------------------------------------------------------------- total 3768.75 1905.08 274.62
Positive, barely, and concentrated in one instrument. GBPUSD on a fifteen-minute clock carries the entire result; remove it and the total is deeply negative. A t-statistic of 0.38 over those 1,764 trades is, in plain terms, indistinguishable from zero.
2. Is it the costs
The obvious next move is a cheaper account: raw spread plus commission instead of a retail markup. The bill:
the bill, retail: 1863.67 the bill, raw: 3494.12
The raw account is dearer. Its commission costs more than the spread it saves, at these trade sizes and frequencies. Cost was not the lever it looked like.
I want to be precise about this one, because I got it wrong first. The commission constant in my cost table was a hundred times too small — 70_000 where the comment beside it said 7_000_000. With the wrong constant the raw account looked cheaper and the conclusion reversed. The fix is one digit; the table above is the corrected run, and there is now a test pinning the unit so the digit cannot drift again.
3. Is it the clock
If the effect is real but small, a faster clock gives you more of it. Four clocks, same rules:
total -72015.24 -68845.50 -48774.23 -41090.31 trades 116959 121139 63936 2094 spread paid 73863.09 61259.14 27256.02 798.08 before costs 1847.84 -7586.35 -21518.20 -40292.23
Read the bottom row first. Before costs, the one-minute clock is the only one that reads the market correctly at all — and it is the worst account of the four, because reading the market on a one-minute clock means trading on one.
73863.09 of spread bought 1847.84 of edge the tariff is 40 times the signal
At the other end, the daily clock pays almost nothing — 798 of spread — and has nothing to pay it with: minus 40,292 before a single cost is charged. The effect is real and it is exactly where the quote stream said it would be. On bars it cannot be reached without paying many times its size.
4. Is it breadth
The Fundamental Law says information ratio scales with the square root of the number of independent bets. So: 28 instruments instead of one, and hold both sides of a ranking rather than each pair on its own.
rule net costs trades
--------------------------------------------------------------------
each pair on its own -3170.50 2047.85 8241
ranked, both sides held -1344.55 887.15 3480
gross of costs
each on its own -1122.65
paired -457.40
what holding both sides was worth: 1825.95
Pairing is worth 1,826 and that is a real, clean improvement. It is also beside the point: both rules lose before costs. The shape reads the market wrong to begin with, and breadth improved something that had nothing in it to improve.
Breadth raises the t-statistic of an edge you have. It does not manufacture one.
The three times the measurement caught me
These are the useful part.
I charged the spread twice. In an early tick-level estimate I billed a round trip two half-spreads on entry and two on exit. A round trip pays it once. The error made a viable-looking effect look about half its real size — in the wrong direction, which is the dangerous one: it would have made me discard something real.
My market-neutral construction was a no-op. I implemented neutrality by demeaning the cross-sectional scores before ranking them. Subtracting a constant from every score is a monotonic transform. It changes no ranking, and therefore changes no position. Neutrality comes from holding both sides simultaneously, which the harness was already doing; the demeaning was ceremony. The measurement did not change when I removed it, which is how I found out.
Trailing stops made it worse. Every position in the early runs had a fixed profit target, which caps the right tail while slippage leaves the left tail open — structurally fatal for anything momentum-shaped. I was confident this was hiding the edge. I added trailing exits and the result got worse at four of five lookbacks. The structural flaw was real and there was nothing behind it.
Each of those was a hypothesis I believed. What settled them was that each one had a number attached before I ran it, and the number came back and said no.
What actually closes it
Not one of the results above. A single negative measurement means you tried the wrong thing; that is always available as an explanation, and it is why searches like this do not end on their own.
What closes it is the coins. With 1,764 observations and a t of 0.38, trying a thousand more shapes does not find the edge sooner — it guarantees finding one that is not there, and it will look better than anything I found by reading the data. The threshold rises with roughly the square root of twice the log of the number of things you tried, and a weak effect does not grow at all.
So the honest statement is not "there is no edge in FX bars." It is narrower and it is testable: at this sampling frequency, with these cost assumptions, across this instrument set, nothing I tried separated itself from what a lucky coin produces. That is a bounded claim about a search, which is the only kind of claim this kind of work supports.
What I would tell someone starting
Build the null first. Before the first real strategy, generate a few hundred that read nothing and record the distribution of their results on your data, with your costs, through your harness. It costs an afternoon, and from then on every result you get arrives with a number next to it saying how often noise does that well. Mine said the 90th percentile, and there is no version of that sentence that ends in a funded account.
Charge costs from the contract, not from a constant you typed. Pin the units with a test. A hundred-fold error in a cost constant reversed one of my conclusions and nothing about the output looked wrong while it did.
And write down what would end the search before you start it. I did not, which is why it took eight measurements instead of two.