我把交易機械人減至每年四次交易:回測收益增至三倍,仍然失敗
I Slowed My Trading Bot Down to Four Trades a Year. It Tripled a Backtest, and It Still Failed.
作者將加密貨幣策略限制為每年最多 4 次往返交易,四種策略在回測中均錄得正回報,但全部未能通過 Gate 1。2022 年 1 月至 2026 年 9 月,趨勢策略回報為 +200%,但在隨機時點對照測試中只勝過 84% 的結果,低於 95% 門檻。作者認為,現有測試未能認證這類低頻策略,而回測結果也不足以證明策略有優勢。
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.
來源:DEV Community · dev.to