第 6 章 · 03 滑点与手续费 本节摘要:本节讲清回测里两个最容易被忽视、却会让结果严重失真的因素——滑点(slippage)和手续费(fee)。回测默认假设「订单按请求价全额成交、无滑点」,但实盘里限价单可能部分成交、市价单会穿越订单簿产生滑点;手续费方面,回测默认用交易所的市场费率(maker/taker),但你的实际费率可能因 VIP 等级、平台币抵扣而不同。本节先讲 freqtrade 的手续费建模机制(默认从交易所拉、可用 覆盖、每笔交易扣两次),再讲滑点的来源与回测/Dry-Run/实盘三种模式下的不同处理,最后给出「让回测更保守、更接近实盘」的实操建议——故意调高 fee、用 模拟 K 线内价格、对市价单策略格外谨慎。
本节摘要:本节讲清回测里两个最容易被忽视、却会让结果严重失真的因素——滑点(slippage)和手续费(fee)。回测默认假设「订单按请求价全额成交、无滑点」,但实盘里限价单可能部分成交、市价单会穿越订单簿产生滑点;手续费方面,回测默认用交易所的市场费率(maker/taker),但你的实际费率可能因 VIP 等级、平台币抵扣而不同。本节先讲 freqtrade 的手续费建模机制(默认从交易所拉、可用
--fee覆盖、每笔交易扣两次),再讲滑点的来源与回测/Dry-Run/实盘三种模式下的不同处理,最后给出「让回测更保守、更接近实盘」的实操建议——故意调高 fee、用--timeframe-detail模拟 K 线内价格、对市价单策略格外谨慎。
内容来源:原项目文档
docs/backtesting.md(fee / assumptions)、docs/configuration.md(fee / slippage 配置),汉化并套用体系化模板。
⚠️ 风险提示:回测默认的费率与成交假设偏乐观。直接用回测数字做实盘决策,等于「带滤镜看世界」。务必按本节建议把假设调保守。
阅读完本节,你应当能够:
回测的盈亏计算默认包含手续费,且 freqtrade 会自动从交易所的市场信息(market info)里拉取该交易对的默认费率(通常是 taker 费率,如 binance 现货 0.1%)。每笔交易扣两次手续费:一次进场、一次出场。
💡 为什么扣两次:一笔完整交易 = 进场(买)+ 出场(卖),每次都收手续费。所以一笔交易的「费用成本」约是
2 * 费率。比如 0.1% 费率,一笔交易成本约 0.2%。
如果你有特殊费率——比如账户达到某 VIP 等级、用了平台币抵扣、或者通过做市商拿到了更低的 maker 费——这些 ccxt 是看不到的。这时用 --fee 显式指定:
# 假设你的实际单边费率是 0.1%(写成 ratio 0.001) freqtrade backtesting --strategy MyStrategy --fee 0.001
--fee 的值是 ratio(比率),不是百分比。0.001 = 0.1%。它会同时应用于进场和出场。
不想每次敲 --fee,写进 config.json:
{ // ... "fee": 0.001 // ... }
⚠️ 官方建议:正常情况下不要配置
fee,让它回退到交易所默认值即可。只有在你确实有特殊费率、想实验不同费率时才设。配错了(比如把 0.001 写成 0.01)会让回测失真十倍。
滑点(slippage)指「请求价」与「实际成交价」之间的差。它的成因:
回测的核心假设之一是:所有订单只要价格在当根 K 线 high/low 范围内,就按请求价全额成交,无滑点。也就是说,回测基本不建模滑点。
这是回测「乐观假设」的最大来源之一。实盘里,你的限价单可能部分成交、市价单可能滑到很差的价——这些回测都看不到。
不同模式对滑点的处理不同:
| 模式 | 滑点处理 |
|---|---|
| 回测 | 基本无滑点(假设按请求价全额成交) |
| Dry-Run | 市价单按订单簿成交量模拟,最大滑点 5%;限价单价格触及即成交,跨价超 1% 转市价单 |
| 实盘 | 真实滑点,完全由市场决定 |
Dry-Run 的 5% 滑点上限是「保护性假设」——如果模拟成交价偏离请求价超过 5%,就当作没成交(避免模拟出离谱的价格)。但回测没有这个机制。
💡 核心结论:回测里「市价单策略」的成交价是最乐观的;Dry-Run 引入了有限的滑点模拟;实盘才是真实滑点。这就是为什么一个在回测里完美的市价单策略,Dry-Run 一跑就可能变差,实盘更差。
把手续费和滑点合起来看,回测的默认假设系统性偏乐观:
| 因素 | 回测默认 | 实盘实际 | 偏向 |
|---|---|---|---|
| 手续费 | 交易所默认(可能是 maker) | 你实际付的(常是 taker,更高) | 回测偏低 |
| 滑点 | 无 | 有,市价单尤其大 | 回测偏低 |
| 成交率 | 全额成交 | 可能部分成交、被拒 | 回测偏高 |
| K 线内价格 | 假设顺序(如 low 先 high 后) | 真实 tick 路径 | 不确定,但常偏乐观 |
这意味着:同一个策略,回测的收益率通常比实盘高 20%~50%(经验值,因策略而异)。短线、高频、市价单策略差异更大;长线、限价单、低频策略差异较小。
既然默认偏乐观,就主动把假设调保守:
把 fee 设得比真实值略高一点,留安全边际:
# 真实 0.1%,回测用 0.12% 甚至 0.15% freqtrade backtesting --strategy MyStrategy --fee 0.0012
这能抵消一部分滑点和「默认费率是 maker 而你实际付 taker」的偏差。
freqtrade backtesting --strategy MyStrategy --timeframe 1h --timeframe-detail 5m
更细周期模拟 K 线内价格走势,部分补偿「K 线内价格理想化」的乐观(见第 01 节)。注意它不模拟滑点,但能让成交时机更真实。
如果你的策略大量用市价单(order_types 里 entry/exit 是 market),回测会按 taker 费率算,但完全忽略滑点——这是最危险的组合。对这类策略:
--fee 用 taker 费率(通常比 maker 高一档)。--timeframe-detail 验证。第 02 节提到的「Wallet based Metrics」含浮亏,比 closed trades 口径保守。优先看这组。
把回测收益率打个 7~8 折作为实盘预期。如果打折后依然可接受,再考虑上线。
与费用相关的配置项集中这几条:
| 配置项 | 含义 | 默认 |
|---|---|---|
fee |
回测/Dry-Run 用的手续费 ratio;不设则用交易所默认 | 交易所默认 |
exchange.unknown_fee_rate |
当交易所费率币种不可交易时的回退值 | None |
futures_funding_rate |
合约历史资金费率不可得时的回退值;不熟就设 0 | None |
tradable_balance_ratio |
可用余额比例,留一部分给手续费;建议 0.99 | 0.99 |
⚠️ futures_funding_rate 慎设:合约策略的盈亏受资金费率影响。如果你在测某个币、又懂资金费率的影响,可以设;否则设 0,避免回测被错误的资金费率扭曲。
--fee 0.001 或配置 fee 覆盖。--fee、用 --timeframe-detail、市价单按 taker 费率、看 Wallet 口径、回测收益打 7~8 折作为实盘预期。fee(慎设)、exchange.unknown_fee_rate、futures_funding_rate(不熟设 0)、tradable_balance_ratio(0.99)。下一节,我们进入回测诊断里最关键的一关——未来函数检测(lookahead-analysis),揪出那些「作弊」式盈利的策略。