If you run a market-making or grid bot, the single number that decides whether your backtest survives contact with a live account is the fee assumption baked into your config. I pulled the default fee settings out of three popular open-source frameworks and compared them against what the venues actually charge in mid-2026. All three are wrong — but they're wrong in different directions, and that matters.
The defaults, side by side
| Framework | Default maker | Default taker | What it assumes |
|---|---|---|---|
| Hummingbot | 0.10% | 0.10% | Flat symmetric fee, no tier logic |
| Freqtrade | 0.10% (single fee) |
0.10% | One value applied to both sides |
| OctoBot | 0.10% / 0.10% | reads from ccxt | Pulls venue defaults, ignores your tier |
The common failure is symmetry. Every one of these treats maker and taker as equal by default, but a post-only grid on a major venue in 2026 is paying maker rates that can be negative to +0.02%, while taker is closer to 0.04–0.05%. If your bot fills 80% maker, a flat 0.10% assumption overstates cost by roughly 3–5x on the side that dominates your fills.
Why each one bites you differently
- Hummingbot hardcodes the symmetric 0.10% in the connector config. It's honest that it's a placeholder, but most people never edit it. Your PnL curve looks conservative — which feels safe until the strategy that "worked" in sim was only profitable because the fake fee drag hid overtrading.
-
Freqtrade collapses both sides into one
feefield. There is no maker/taker split at all, so a maker-heavy strategy is systematically punished and a taker-heavy one flattered. Same number, opposite bias. - OctoBot does the smart thing and reads fees from ccxt — but ccxt returns the public default tier, not your account's actual schedule. If you're on a higher volume tier or a partner-linked account, the real number your account settles at can be materially lower than what the sim used.
A quick sanity check
Before trusting any of them, print the effective rate your bot is actually using per side:
mkt = exchange.market("BTC/USDT")
print("maker:", mkt["maker"], "taker:", mkt["taker"])
# then reconcile against a real settled fill:
# fee_paid / notional == effective_rate
If that ratio doesn't match your config, every equity curve you've drawn is fiction on the fee axis.
What I did about it
I keep a small dataset of the fee schedules I actually settle at per venue and per tier, so the number in the config is the number the account pays, not a framework placeholder. The raw tables are here: https://github.com/jack0752168/crypto-exchange-fee-data — and I wrote up how the maker/taker split and tier attribution actually flow through a bot's PnL here: https://www.jacktrader.xyz/en/blog/hummingbot-fee-rebate.html
The tools aren't wrong to ship a placeholder — they just can't know your tier. That's your job to fill in.
None of this is financial advice; verify current schedules against your own account before trading.
Top comments (0)