Guarded Trader, Part 2: fees stopped mattering. The other problems didn't go away.
In Part 1 the problem was fees. A $100 Kraken account is stuck on the lowest fee tier: 0.80 % per taker fill. Add 0.10 % slippage and every round trip costs about 1.8 %. Every strategy I tested traded often enough that fees ate everything.
So round 2 asked the obvious next question. What if it barely trades at all?
The rule for this round: more than 4 round trips in any calendar year is an automatic fail. At that pace, even 1.8 % a round trip is a rounding error.
The short version: the economics worked, and the test still said no. I think the test was right.
The four candidates
Everything was written down and frozen before a line of strategy code existed. That means the parameters, the costs, the pass/fail rules and my predictions. It was hashed into an append-only trial registry. Nothing could be tuned after I saw a result.
| Rule | Checked | |
|---|---|---|
| Trend filter | Hold BTC while it's 5 % above its 200-day average; sell when it's 5 % below | weekly |
| Dual momentum | Hold BTC or ETH, whichever went up more over 12 months, if it went up at all | monthly |
| Vol target | Hold BTC at a size that targets 50 % annual volatility; rebalance only on a 20 % drift | monthly |
| Trend × vol | The trend filter's on/off, the vol target's sizing | weekly |
None of these is new. That was the point. If the textbook slow strategies can't clear the bar, nothing clever I invent is likely to.
Costs were the real Kraken Tier-1 numbers: 0.80 % taker + 0.10 % slippage per fill. I also ran 0.40 % maker, 0.30 % slippage and double fees. The data was Kraken's own candle archive. The start balance was the CA$35 that is actually sitting in the account.
The money looked good
On the scored range, January 2022 to September 2026, which includes the 2022 crash and the 2025–26 slide:
| Net return | Max drawdown | Sharpe | |
|---|---|---|---|
| Trend filter | +200 % | 27 % | 0.85 |
| Trend × vol | +199 % | 27 % | 0.88 |
| Dual momentum | +167 % | 38 % | 0.73 |
| Vol target | +124 % | 60 % | 0.60 |
| Just holding BTC | +78 % | 67 % | 0.48 |
The trend filter sat out most of 2022, got back in early 2023, and stepped aside in November 2025. It closed four trades in nearly five years. Fees were about 7 % of its gross winnings. Doubling the fees to 1.80 % a fill still left it at +174 %.
So the thing that killed round 1 is gone. At four trades a year, a $35 account on the worst fee tier is not the problem.
⚠️ "+200 %" is on about US$25 (the CA$35). That's about $50 of profit, on a backtest, over almost five years.
And then the gate said no
The project's first gate (Gate 1) is deliberately unfriendly. All four failed it, and not narrowly.
1. It needs at least 100 closed trades. I knew before running anything that this was impossible. Four trades a year over 4.75 years is 19 at most. The conflict came up before anything ran. I chose not to change the gate, and ran it anyway. A gate you rewrite for the candidate in front of you isn't a gate.
2. It needs an in-sample Sharpe of at least 1.0. The best was 0.85.
3. Walk-forward testing saw something different. The test chops history into 3-month windows, each starting flat, and ignores any position still open when a window ends. A strategy whose trades last 7 months almost never closes a trade inside one window. What's left are the few quick losers. Pooled out-of-sample Sharpe was −1.25. That's a blind spot of the test for this kind of strategy, not a verdict on it, and I wrote it down as one.
4. No single trade may be more than 30 % of the profit. With four trades, one of them always is. Dual momentum's single best trade was 115 % of its net profit. The other three lost money.
Points 1, 3 and 4 are really one finding: Gate 1 can't certify a strategy this slow. That's a real limitation and a fair thing to revisit, in writing, in a separate decision. It is not a reason to quietly lower the bar this round.
The test that actually matters: was it luck?
This is the part I'd keep if I could keep only one.
I built a second control I called the matched null. For each strategy, it keeps:
- the same number of times in and out of the market,
- the same total time in the market,
- the same position sizing.
It just puts the switches at random dates. Then it does that 200 times. If the trend filter's timing is skill, it should beat almost all of those random versions.
It beat 84 % of them. The rule was 95 %.
Random timing with the same exposure did as well as my "skill" about one time in six. The other three were at the 72nd–94th percentile. Nothing cleared 95 %.
That's the honest summary of a 200-day trend filter on one asset, over one five-year stretch: it looks great, and nine in-out decisions are not enough evidence to tell a rule from a lucky calendar. The Deflated Sharpe Ratio says the same thing. It corrects for the 26 strategies this project has now tried, and it comes out at 0.26–0.35.
Over the longer run, holding BTC won on return
Going back to 2015 (supplementary, not the gate), every candidate made less money than simply holding BTC. The exception was dual momentum, on its shorter 2016 start. Holding BTC turned $25 into about $6,500 in the backtest. The trend filter turned it into about $4,900.
What every candidate did do was cut the worst drawdown: buy-and-hold fell 84 % at its worst, the trend × vol strategy 53 %.
That matches what I predicted before running anything: "its edge over buy-and-hold, if any, is drawdown, not return." Lower drawdown is worth something. It isn't the same as an edge.
Two small things that would have bitten in real life
$35 is too small for the strategies that rebalance. Kraken's minimum BTC order is about $4.66. The vol-target strategies wanted to trade slices as small as $3.61. Only the two all-in or all-out strategies are even tradeable at this size.
I found a bug in my own control. The random-entry null draws a random number per candle, keyed by the candle's timestamp. The code divided timestamps by 10⁹, assuming nanoseconds. The pinned Docker image's pandas loads Kraken's candles at second resolution, so every candle got the same random number. Round 1's Freqtrade data was in milliseconds, so it got one number per ~12 days.
The fix is three lines and a regression test. I rebuilt the reports with a mode that refuses to write unless every recorded result is reproduced bit for bit, and they were. Only the null changed.
The bug did not change any verdict, in either round. I re-scored round 1's null the same read-only way. Its percentiles moved (one EMA-cross candidate dropped from the 86th to the 70th), but every candidate also failed on other checks.
Still, a control that silently doesn't randomise is exactly the kind of thing that makes a backtest lie. It's now in the results doc, in public, next to the numbers it affected.
So what happens now
Nothing, on purpose.
- The project stays paused. The rule for unpausing is "a strategy passes Gate 1 at real costs", and none did.
- No API key exists, no server is running, and the CA$35 stays parked.
- An LLM wrote and ran this round's backtests: in a sandbox with no network, no keys, and the results registry counting every attempt. It can't place an order, and it didn't get to pick the rules it was scored against. Those were frozen first.
What I'd do differently next, and will decide in writing before running anything:
- A gate built for slow strategies. Fewer trades, but more history, more assets, and the matched null as the main test instead of a trade count. That's a decision record, not a tweak.
- More independent decisions. The same rule across several assets gives the null more than nine switches to judge.
If you take one thing from this round: slowing down fixes fees. It doesn't fix the question of whether the signal is real. The tests that ask that question are the ones worth keeping, even when they cost you a nice-looking +200 %.
Everything here, including the frozen pre-registration, the results and the bug, is in the repo: github.com/aplicy-com/guarded-trader, under docs/research/07-round2-preregistration.md and 08-round2-results.md. This is a research project, not financial advice. It has no proven edge, and its own results say so.
Top comments (1)
Slowing trade frequency solves the microstructure problem by turning it into a degrees of freedom problem. Four trades over five years is effectively four macro samples, so the standard error around your Sharpe ratio is wider than the strategy return itself.
The three-month walk-forward window also penalizes the trend filter on path dependency. When average holding duration stretches past half a year, resetting to flat cash every ninety days books the entry whipsaw while truncating the payoff tail. Freezing the gate was the disciplined call, but testing a multi-month trend system across quarterly slices measures the boundary conditions of your evaluation script more than the edge.