6.6 回测与参数优化
先选建模方式
- Every tick:每个 Tick 都模拟,最接近实盘,也最慢。适合最终验证和短周期策略。
- Control points:用控制点生成价格路径,速度快,适合中期参数扫描。
- Open prices only:只按开盘价成交,适合日线、H4 等长周期,不适合日内。
建模质量(Modeling quality)低于 90% 时,回测结果只能当参考。点差、滑点、佣金、隔夜利息都要设置;默认点差往往偏乐观。先把成本调成真实水平,再看收益曲线。
看哪些指标
- 净利润:绝对收益,受手数和复利影响,不能单独比较策略优劣。
- 盈亏比(Profit Factor):总盈利 / 总亏损。1.0 是打平,1.3 以上才有讨论价值。
- 最大回撤:从峰值到谷底的最大跌幅。决定你能不能拿得住。
- 交易次数:太少(<30)时统计意义弱;太多可能被成本吃掉。
- 期望收益:平均每笔盈亏,乘以交易次数才是长期结果。
不要只看净利润。一个策略净利润很高但最大回撤 60%,实盘很难执行;另一个净利润一般但回撤 8%、交易 200 次,反而更可信。
参数优化:网格与过拟合
策略测试器的“优化”会对输入参数做网格扫描,输出每组参数的收益。常见的错误是直接选样本内最高分。参数越细、组合越多,越容易找到“刚好拟合历史噪声”的一组。表现就是:样本内盈亏比 2.1,样本外只剩 1.1。
更稳的做法是看“参数邻域”:最优参数附近一圈是否也表现良好?如果 8/40 是 2.1,但 8/30 只有 1.0、8/50 只有 1.1,说明这是孤峰,换一段数据就崩。如果 8/30、8/40、8/50 都在 1.6 以上,说明这个区域比较稳健。
样本外与前推滚动
把历史数据切成两段:前 70% 做样本内优化,后 30% 做样本外验证。样本外不参与选参,只用来检验。更严格的是前推滚动(walk-forward):每次用过去 N 年优化,预测下一年,然后窗口向前滚动,最后看多次样本外的综合表现。
前推滚动不能保证未来盈利,但能有效暴露“参数对时间段过度敏感”的问题。至少做一次样本外,再决定要不要上线。
完整示例:可优化的均线 EA
下面的 EA 把快线、慢线、手数、止损、止盈、最大点差都做成 input,方便测试器扫描。信号使用 shift=1 和 shift=2 的已收盘均线,避免当前 Bar 重绘。CanTrade 在测试器里跳过点差检查,在实盘里限制最大点差。
注意:信号用 `fast1/slow1` 与 `fast2/slow2` 比较,而不是 `fast0/slow0`。shift=0 的均线会随当前价格跳动,用它做交叉判断,回测里会出现“看到未来”的假信号。
成本压力测试
把点差调大 50%、滑点调大 1 点、佣金翻倍,再跑一遍。如果策略立刻从盈利变成亏损,说明它的边际很薄,实盘很难复制。好的策略应该在最差成本假设下仍然可控,而不是只在理想成本下漂亮。
常见错误
- 用 shift=0 的指标做信号:当前 Bar 未收盘,回测会重绘,结果虚高。
- 只做样本内优化:16 组参数选最高分,过拟合概率极高。
- 忽略点差和滑点:默认成本偏低,实盘收益被吃掉。
- 交易次数太少就下结论:10 笔交易的高盈亏比没有统计意义。
- 参数孤峰:最优参数附近表现很差,说明是拟合噪声,不是稳健区域。
小结
回测的可信度来自实验设计,不是收益曲线的好看程度。先固定成本假设,再看回撤与交易次数,再做样本外和前推滚动。优化时选“邻域稳定”的参数,不选“单点最高”的参数。这样得到的结论,才有资格拿到实盘去验证。
测试器设置清单
- 品种与周期:与实盘一致。用 H1 优化的参数拿到 M5 上跑,结果没有可比性。
- 数据区间:至少覆盖一轮完整趋势和一轮震荡,避开只有单边行情的样本。
- 建模方式:最终验证用 Every tick;参数扫描可用 Control points,但要接受误差。
- 初始资金与杠杆:与实盘账户一致,否则手数和回撤比例会失真。
- 点差/滑点/佣金:按经纪商的真实水平设置,不要用 0 点差。
- 执行延迟:部分版本支持随机延迟,能模拟网络抖动。
优化结果怎么读
测试器的优化报告是一张表:每行一组参数,每列一个指标。不要只按净利润排序。先看交易次数,少于 30 的结果统计意义弱;再看最大回撤,超过可承受范围直接淘汰;然后看盈亏比和期望收益;最后才看净利润。把“参数—指标”画成散点或热力图,比单看最高分更容易发现稳定区域。
如果最优参数是 8/40,但 8/39、8/41 的表现断崖式下跌,说明这是孤峰。稳健区域通常是一整片颜色相近的格子,而不是一个亮点。实盘更愿意要“2.0 的平原”,而不是“2.5 的针尖”。
前推滚动的步骤
- 把数据按时间切成多个窗口,例如 2018–2020 优化、2021 验证,然后窗口向前滚动。
- 每次只用窗口内的数据选参数,绝不能用验证段的数据。
- 记录每次验证段的收益、回撤、交易次数,最后看平均值和最差值。
- 如果多次验证中有一半以上亏损,说明参数不稳定,不要上线。
前推滚动不能消除过拟合,但能让你看到“参数在不同时间段的表现分布”。分布比单点更有说服力。
上线后的监控
实盘和回测的差异主要来自成本、滑点、执行延迟和行情结构变化。上线后至少记录:实际成交价与请求价的偏差、每日交易次数、实际最大回撤、错误码分布。连续两周偏离回测区间,就应该暂停策略复查,而不是加仓摊平。
把回测的“预期值”写成一张小卡片:盈亏比、最大回撤、月交易次数。实盘每周对照一次。偏离在 20% 以内可以观察,超过 50% 要停手。这个简单的对照表,比任何复杂监控都更能防止“策略已经失效但还在跑”。
数据质量与缺口
回测结果首先取决于数据。选择“历史数据”时优先用经纪商提供的 M1 数据,不要用来源不明的 CSV。数据缺口会表现为某段 K 线突然跳空、点差为 0、成交量缺失;这种数据上跑出的高收益没有意义。测试前用“图表—历史数据”检查缺口,或写一个脚本统计连续缺失的分钟数。
不同经纪商的数据不完全一致,同一策略在 A 经纪商回测盈利、B 经纪商回测亏损,可能不是策略问题,而是点差、隔夜利息、数据源不同。上线前用目标经纪商的模拟账户再跑一遍,不要直接套用别家的回测结论。
参数敏感性与稳健性
稳健的参数区域有三个特征:邻域表现接近、跨时间段表现接近、跨品种表现接近。只满足第一个还不够:8/40 在 EURUSD 上很好,换到 GBPUSD 就亏损,说明它拟合的是品种特性,不是市场规律。至少用两个品种、两段时间做交叉验证,再决定是否上线。
参数越少越好。每增加一个参数,就多一个过拟合的维度。能用固定逻辑解决的问题,不要做成参数;必须做成参数的,给出合理范围和步长,不要用 0.01 这种细粒度扫描,除非你有足够的数据支撑。
交互演示:参数优化为什么会过拟合
4×4 参数网格逐个回测,样本内冠军是 8/40,盈亏比 2.10;换到样本外只剩 1.15。单步走完,理解“最高分”为什么不能直接上线。
提示:动画默认暂停。点「播放」连续演示,点「单步」自己控制节奏;桌面端也可以用空格播放、方向键单步、R 重置。
练习题
-
6.6 回测与参数优化 选择题1.参数优化时,样本内最高分直接上线的主要风险是? (2分) [选择]A. 回测速度太慢B. 过拟合,样本外表现可能大幅下降C. 手续费太低D. 图表颜色不对2.下列哪个指标最能反映策略的“回撤风险”? (2分) [选择]A. 净利润B. 最大回撤C. 交易次数D. 点差3.使用 shift=0 的均线做交叉信号,回测结果通常比 shift=1 更可信。 (2分) [判断]
-
6.6 回测与参数优化 编程实战(AI 批改)1.【实战】写一个可优化的均线 EA 骨架 (10分) [MQL4自动批改]写一个 EA:用 input 定义 FastMA、SlowMA、Lots、StopLoss、TakeProfit、MagicNumber、MaxSpread;CanTrade 中判断 IsTradeAllowed,实盘时限制 MODE_SPREAD;OnTick 中用 Time[0] 与 lastBar 保证每根 K 线只执行一次;用 iMA 取 shift=1 和 shift=2 的快慢线,金叉 OrderSend 买入、死叉卖出,SL/TP 用 NormalizeDouble。必须出现 input、iMA、OrderSend、NormalizeDouble。
《MQL4 教程与 MT4 EA 编程》课程目录
系统讲解 MQL4 编程:从变量、循环、函数到 OrderSend 下单、iMA 指标调用与 EA 回测。36 节中文教程,覆盖 MT4 编程入门、外汇 EA 编写与外汇量化策略三类实战,每节配可运行代码和 AI 自动批改练习
- 第1章 基本语法
- 1.1 第一个EA
- 1.2 如何学习
- 1.3 变量
- 1.4 语句
- 1.5 运算符
- 1.6 常量与枚举
- 第2章 条件
- 2.1 if语句
- 2.2 关系运算符
- 2.3 逻辑运算符
- 2.4 复合条件
- 2.5 switch语句
- 第3章 循环
- 3.1 for循环
- 3.2 while循环
- 3.3 break和continue
- 3.4 嵌套循环
- 第4章 函数
- 4.1 函数的定义
- 4.2 参数和返回值
- 4.3 变量的作用域
- 4.4 常用内置函数
- 4.5 日期和时间函数
- 4.6 交易函数
- 4.7 账户和市场信息函数
- 4.8 图表和对象函数
- 4.9 文件操作函数
- 4.10 数组函数
- 4.11 技术指标函数
- 第5章 如何写EA
- 5.1 EA的基本结构
- 5.2 常用内置变量
- 5.3 下单函数
- 5.4 技术指标
- 5.5 实战:均线交叉EA
- 第6章 进阶实战:从能跑走向可靠
- 6.1 OnTimer 定时器与事件处理
- 6.2 订单池遍历与 OrderSelect
- 6.3 错误处理与 GetLastError
- 6.4 自定义指标与指标缓冲区
- 6.5 图表对象与交易面板
- 6.6 回测与参数优化