Episode 2 of 3: Why Most DeFi Trading Bots Fail in the Real World
The easiest way to make a DeFi trading bot look smart is to stop the story before the trade has to survive the market.

on this page
The easiest way to make a DeFi trading bot look smart is to stop the story before the trade has to survive the market.
That usually means three things get hidden:
- the quoted price is treated like a real fill
- the fill is treated like a certainty
- the backtest is treated like the market itself
The Boros project only became useful once it stopped doing that.
Series navigation: Episode 1 | Episode 2 | Episode 3
What most DeFi bot backtests leave out
The easiest way to make a DeFi trading bot look smart is to stop the story before the trade has to survive the market.
If you have ever seen a crypto bot thread with a smooth chart and a lot of confidence, there is a good chance the hard parts were removed before the chart was drawn.
In practice, the hard parts are usually:
- waiting after the signal
- paying the spread
- getting less size than expected
- missing a fill completely
- paying to get out, not just to get in
- learning that the best-looking trades are often the least repeatable ones
That is why so many bot ideas look great in research and mediocre in reality.
The model is not trading.
The notebook is not trading.
The market is trading.
The Boros test system
The real value of the Boros repo was not the strategy itself. It was the system around it.
Instead of treating one promising setup like a winner, the repo forced every strategy through the same path:
market data
+
reference data
+
historical snapshots
|
v
signal engine -> backtest -> execution realism -> capacity checks
|
v
forward paper trader -> persistent logs -> dashboard
That structure did two useful things:
- it made every assumption visible
- it made bad strategies fail in the same place every time
That is what you want from a research stack.
The assumptions that changed the answer
Once the Boros strategy moved into the strict framework, every run had to survive the same execution profiles.
| Profile | Delay | Spread multiplier | Extra slippage | Cost floor |
|---|---|---|---|---|
| Optimistic | 0s | 1.00x | 0.25 bps | 0.25 bps |
| Base realistic | 300s | 1.10x | 0.75 bps | 0.75 bps |
| Conservative | 900s | 1.25x | 1.50 bps | 1.50 bps |
| Adversarial | 1800s | 1.50x | 3.00 bps | 3.00 bps |
That table is where the mood changed.
A strategy that only works with perfect timing, clean fills, and gentle costs is not robust. It is just lucky.
The Boros-native carry signal did not survive that transition.
What happened to the Boros signal
The original story was simple:
- find a Boros market where fixed looked rich or cheap
- enter when the gap looked wide enough
- exit when the gap compressed
That sounds reasonable until you ask the more useful version:
after delay, spread, slippage, exit friction, and a short history window, is there still enough left to matter?
For the lead strategy, carry_mean_reversion_v2, the final answer was no.
Under the strict realism pass it finished with:
4base-realistic trades-22.2679 bpsnet under the base-realistic profile-10.9869 bpsout of sample-5.5670 bpsaverage base-realistic return per trade
The important point is not that performance got worse.
The important point is that it crossed through zero and stayed there.
That is not a tuning problem. That is a strategy-quality problem.
Why paper trading staying flat was a good sign
One of the most honest outputs in the Boros project was also the least exciting one.
The paper trader stayed flat.
On the March 27, 2026 forward snapshot:
- all three strategy workers were running
- each had fake capital of
10,000.0 - each had
0open positions - each had
0.0open PnL - each had
0.0closed PnL - each still had recent signals being logged
That means the system was alive.
It just was not pretending.
The main rejection reasons were exactly what you would want from a strict paper stack:
signal_below_thresholdcalibrated_edge_non_positive
That is the opposite of fantasy paper trading.
The system saw the market, scored the setup, and decided the trade did not deserve to exist.
Research & Code
The technical details belong here, not at the center of the reader story.
If you want the deeper mechanics, the key repo pieces are:
docs/boros/PROTOCOL_DEEP_DIVE.mdreports/boros/REALITY_CHECK.mdreports/boros/EXECUTION_REALISM.mdreports/boros/FORWARD_VALIDATION.mdreports/boros/STRATEGY_LANDSCAPE.mdresearch/boros/reviews/SKEPTIC_REVIEW.mdsrc/ai_homelab_ops/boros/
The simplified trade lifecycle looked like this:
for snapshot in market_history:
signal = strategy.compute(snapshot, refs, config)
if not signal.accepted:
record_rejection(signal)
continue
entry = execution_model.enter(signal, book=snapshot.book)
if not entry.filled:
record_missed_trade(signal, entry)
continue
position = open_position(entry)
position = manage_until_exit(position)
close_position(position)
That code is not there to look clever.
It is there so the hidden assumptions have nowhere to hide.
Next up
The final article is the blunt one.
I will put the Boros-native carry idea, the external-reference strategy, and the benchmark funding strategy side by side, then answer the only question that matters:
did any Boros edge survive realistic costs?
Continue with Episode 3: Boros Trading Bot Verdict.