算法交易不仅包括交易机器人的规划和开发, 而且 (在更大程度上) 测试和验证其中实现的想法和算法的生存性。MetaTrader 5 提供了内置的测试器, 用来优化基于历史数据的智能交易系统。这个工具在日常活动中往往是不可或缺的。然而, 其主要难处是寻找执行区间优化之后依然能保持稳定盈利的参数。可能的解决方案之一是前瞻测试。测试器拥有相应的 内置模式。但是, EA 优化一次之后, 并在随后的一段时间里验证成功就能足以确保其可靠性吗?
EA 的运行周期意味着优化和交易阶段以选定的频率不断重复, 交易者期望长期获得正面 (或至少无损失) 的结果。为了确保系统的效率, 必须重复多次启动测试器按照固定偏移从过去到虚拟未来进行优化和前瞻测试。
这可称为 前瞻优化, 被许多交易者广泛使用。不幸的是, 内置的 MetaTrader 测试器不允许在触压按钮时启动它。代之, 我们必须使用外部工具自动启动测试器, 一并生成前瞻测试报告。因此, 仅需通过 MetaTrader 和 MQL 就可用较简单的方式执行前瞻分析, 无需重复性操作。
事实证明, 我们能够开发一个 MQL 函数库, 如果需要, 可以轻松地连接到任何 EA。您需要一些编程技能, 因为我们要调整 EA 源代码。
计划
在描述函数库之前, 我们来介绍几个概念。
优化区间通常称为样本内数据。后续测试区间通常称为样本外数据。出于便利, 我们还将使用术语 "优化窗口" (或简称 "窗口") 和 "测试步长" (或简称 "步长", "测试")。
前瞻优化的想法很简单。在测试器中, 选择整个优化周期 D, 此值远大于通常的优化窗口从开始日期到过去 (点B) 的区间。仅允许 EA 在预定大小的当前窗口 W 和随后的测试步长 S 内进行交易。确保 D > W >> S。例如, D 应包括一个 W 窗口和十几个 S 步长。
首先, 窗口从初始 B 点开始, 之后应以步长按顺序向右移动多次, 直到窗口的右边界到达整个优化范围 D 的最终日期。
优化参数仅依据 W 窗口内的交易进行计算。计算并保存 S 区段内的交易结果供后续分析。所以, 可以确定每个特定窗口的最佳参数, 并掌握通过数量, 得到相应测试结果的链接。
这完全重复了典型的前瞻测试, 除了一个明显的细微差别: S 段的交易不是以初始存款开始, 而是 EA 在 W 时段内赚取的金额。此功能限制函数库仅适用于固定手数的策略。不过, 您可能会同意, 当分析任意 EA 时, 如果您打算在后续阶段启用资金管理, 使用固定手数进行验证也是强制性过程。
我们为了进行上述的 "零星" 交易, 可以通过添加专门输入来设置窗口 W 的大小, 步长 S, 以及定义整体 D 区间内的窗口平移的步进索引号作为步进量。例如, 当平移为 0 时, 窗口从 B 起点开始。当等于 1 时, 窗口从 S 开始, 并在 S+W 结束。如果移位为 2, 窗口从 2*S 开始, 以 2*S+W 结束, 等等。根据相应参数进行优化, 我们可以委派测试器搜索各样平移。所以, 我们能够沿着虚拟时间轴移动它们, 对包括样本内和样本外数据的区段分派多个测试器验算。
现在, 我们只需要适应这种连续前瞻优化机制。为了实现这一点, 请确保仅在每个窗口 W 中执行交易结果优化, 同时忽略所有后续测试周期 S。在测试器设置中选择 自定义优化条件, 并在函数库中基于当前窗口 W 内的交易计算, 然后使用 OnTester 事件处理程序从测试器中返回它。此外, 函数应在每个后续测试区间 S 里计算并保存交易结果。.优化完成后, 随着步进 i 的移动, 我们会得到每个窗口 W 的多组参数。它们当中最好的一组将被定义。验算索引号可令我们在下一个测试段 S 立即获得交易结果。通过将它们结合在一起, 我们能获得 D 内多个周期前瞻测试的完整报告。
图例. 1. 形成前瞻测试
W 和 S 大小可依交易者自行厘定。例如, 您可以选择 3 个月的优化窗口和 1 个月的前瞻步进。如果总验证期 D 为12个月, 则在测试器中含平移的步进 S 从 0 到 9 (含)。9 是运用简单计算得到的:
N = (D - W) / S = (12 - 3) / 1 = 9 (1)
前瞻步进测试位于窗口 W 的右侧, 除了最后一个之外的所有迭代。然而, 当平移为 9 时, 窗口 W 接近结束日期, 并且前瞻测试变得不可能。如果前瞻优化正常成功, 则最后一步的最优参数组推荐用于在线交易。
前瞻优化的效率可通过下面将要研究的不同标准进行评估。我们已直观地理解了由熟悉的参数所定义的前瞻测试形成的余额曲线, 如利润因子, 夏普比率, 利润的数学期望, 等等。
但是, 我们再谈谈另外一个问题: 什么是合适的 W 窗口和 S 步进大小?让测试器搜索最佳值是合理的。类似于使用函数库提供的专用输入前瞻测试步进遍历, 我们还可以将指定窗口和步长的参数包含到优化列表中。
前瞻优化优化与选择最佳窗口和步进大小一并执行被称为集群前瞻分析。
使用函数库和所有三个参数的优化结果, 我们将能够形成一个包含窗口和步进大小的各种组合的前瞻测试盈利能力表格报告, 以及包含所有表格单元的相应 W 和 S 值组合的精简报告。
除了所描述的操作模式 (集群分析和连续前瞻测试, 也称为滚动前瞻), 函数库支持锚定前瞻优化。与前瞻滚动不同, 因为窗口 W 的开始日期不会改变, 但在每次步进时窗口大小的增量包括前一次迭代的测试周期。举例, 我们继续使用我们的示例, 初始窗口大小为 3 个月, 且假设总时段 D 从 1 月份开始。在第一步, 优化在 1 月份至 3 月份间进行, 而测试在 4 月份完成。第二步是在 1 月份至 4 月份进行优化, 并在 5 月份测试, 而第三步则是在 1 月份至 5 月份进行优化, 6 月份进行测试。
现在, 我们要做的就是实现这个想法。程序员和 EA 开发者能够为自己创建一个这样的工具, 因为任务相当透明, 尽管相当广泛。如果您想要获得现成的产品, 那么还有 MetaTrader 4/5 的 WalkForwardOptimizer (WFO) 函数库。它们的些微区别在于 MetaTrader 5 的版本更具吸引力。尤其是在第五版:
- 函数库作为单个模块实现, 收集优化数据并据其生成报告。在 MetaTrader 4 版本中, 文件将在 tester/Files 中生成, 并应手工重定位到 MQL4/Files。然后应启动单独的脚本来生成报告 (所有链接都列在下面);
- 大多数重复性手工操作被消除, 包括开始新优化之前删除中间文件;
- 名称和数值被自动分配到 EA 工作参数 (在 MetaTrader 4 中, 此数据应通过调用相应的函数显式传递);
- 支持多线程优化, 包括网络代理和 MQL 云计算。
一般来说, MetaTrader 5 版本更加高效, 易于使用。这个可能性出于测试器的 MQL5 API 提供更广泛的有用工具。
实现
因此, 函数库程序界面应提供输入, 令我们能够配置测试器, 以便进行前瞻优化。在头文件中有关它们的描述:
input WFO_TIME_PERIOD wfo_windowSize = year; input int wfo_customWindowSizeDays = 0; input WFO_TIME_PERIOD wfo_stepSize = quarter; input int wfo_customStepSizePercent = 0; input int wfo_stepOffset = 0; input string wfo_outputFile = ""; input WFO_ESTIMATION_METHOD wfo_estimation = wfo_built_in_loose; input string wfo_formula = "";
wfo_windowSize 和 wfo_stepSize 参数允许设置窗口大小和优化步进。WFO_TIME_PERIOD 枚举用来以标准单位设置它们:
#define DAYS_PER_WEEK 7 #define DAYS_PER_MONTH 30 #define DAYS_PER_QUARTER (DAYS_PER_MONTH*3) #define DAYS_PER_HALF (DAYS_PER_MONTH*6) #define DAYS_PER_YEAR (DAYS_PER_MONTH*12) #define SEC_PER_DAY (60*60*24) #define SEC_PER_WEEK (SEC_PER_DAY*DAYS_PER_WEEK) #define SEC_PER_MONTH (SEC_PER_DAY*DAYS_PER_MONTH) #define SEC_PER_QUARTER (SEC_PER_MONTH*3) #define SEC_PER_HALF (SEC_PER_MONTH*6) #define SEC_PER_YEAR (SEC_PER_MONTH*12) #define CUSTOM_DAYS -1 enum WFO_TIME_PERIOD { none = 0, year = DAYS_PER_YEAR, halfyear = DAYS_PER_HALF, quarter = DAYS_PER_QUARTER, month = DAYS_PER_MONTH, week = DAYS_PER_WEEK, day = 1, custom = CUSTOM_DAYS };
基本测量单位是一天。不支持更小的步进。测试器本身设置日期时只能允许一天内精度。一根柱线精度内的替代工作品, 用于实施日内前瞻优化。
请记住, 一周, 一月, 一季度和一年被定义为常数 (固定天数)。不会发生时段的日历边界对齐。这样可以提高计算效率, 统一移动任意大小的窗口, 而不需要绑定数周或数月的边界。如果选择月份 (30 天), 并从任意月份开始计数, 则后续每个日历月份的变更可能会在 "月" 步进之前或之后发生 (因为有些月的天数不同)。如果计数从月中开始, 那么这个步进将在随后数月的中旬进行, 日期则会顺移。
wfo_windowSize 或 wfo_stepSize 中的 'custom' 值允许在随后的参数中设置任意窗口和步长 — wfo_customWindowSizeDays 和 wfo_customStepSizePercent。我们从参数名称可以看出, 窗口是以天为单位定义的, 而步进 — 窗口的百分比 %。
这些参数允许我们在集群优化期间分配尺寸搜索。我们应该选择这些尺寸, 以便最小 (初始) 百分比及其给定增量的变化在应用于最小窗口后之我们能够得到整数天。例如, 如果窗口以 10 为步进从 10 变为 50, 则将步进降低到 10% 以下是没有意义的, 因为这是从最小窗口开始的 1 天。此外, 前瞻步进的增量不应小于 10%。例如, 如果是 5%, 则窗口大小为 30, 第二次迭代意味着测试间隔为 30 的 15% (初始 10% 加一步 5%), 得出 4.5。这样的配置当然不会导致致命的错误, 且函数库会继续正常工作, 不过前瞻测试步进也许不一定完全相符, 这将影响计算的准确性。
不幸地是, 在这种情况下, 函数库未能提供便利的工具来简化配置并验证其正确性。用户应自行检查参数 (意即它们至少应该有一些基本的编程知识)。可能的解决方案之一是实现另一种函数库的分配方法 — 尤其是在一根柱线的精度内工作。我们将在下面介绍一下。
如果 wfo_windowSize 和 wfo_stepSize 等于 "none", 则函数库被禁用。
wfo_stepOffset 参数 (包含在优化参数中) 允许前瞻测试步进排序。其增量应始终为 1。使用方程 (1) 来计算所涉最大窗口尺寸 W 和最小步进 S 的最大值。
wfo_outputFile 参数设置保存优化运行财务结果的 csv 文件名。文件会在 MQL5/Files (МТ5) 或 tester/Files (МТ4) 中创建。
wfo_estimation 参数定义要传递给测试器进行优化的结果。此值是 WFO_ESTIMATION_METHOD 枚举值之一:
enum WFO_ESTIMATION_METHOD
{
wfo_built_in_loose,
wfo_built_in_strict,
wfo_profit,
wfo_sharpe,
wfo_pf,
wfo_drawdown,
wfo_profit_by_drawdown,
wfo_profit_trades_by_drawdown,
wfo_average,
wfo_expression
};
- wfo_built_in_loose (省缺) 和 wfo_built_in_strict — 复合指标由夏普比率, 盈利因子, 盈利大小和交易数量组成;
- wfo_profit — 盈利;
- wfo_sharpe — 夏普比率;
- wfo_pf — 盈利因子;
- wfo_drawdown — 依据余额曲线计算逆相对回撤 (100 - DD)
- wfo_profit_by_drawdown — 盈利除以相对回撤;
- wfo_profit_trades_by_drawdown — 盈利乘以交易数量除以相对回撤;
- wfo_average — 交易平均盈利;
- wfo_expression — 自定义结果方程。
最后, 如果 wfo_estimation 等于 wfo_expression, 则 wfo_formula 参数同样是用于计算结果的自定义方程。您可以在 函数库用户指南 (俄语) 中找到有关有效方程和其它设置的更多信息。
所有参数都具有 wfo_ 前缀, 因此可以轻松地将其与 EA 的工作参数区分开来。
请记住, 您在 EA 中包含头文件之后, 所描述的输入参数会在其中创建。我们也许将它们称为元参数, 因为它们管理优化过程。
另外请注意, 头文件仅声明必需的类型和元参数。为了令数据访问函数库, 我们需要一组开放函数 — 函数库的编程接口。它们也在头文件中描述并由 import 指令导入 (从现在开始考虑 MetaTrader 5 的版本):
#import "WalkForwardOptimizer.ex5" void wfo_setEstimationMethod(WFO_ESTIMATION_METHOD estimation, string formula); void wfo_setPFmax(double max); void wfo_setCloseTradesOnSeparationLine(bool b); void wfo_OnTesterPass(); int wfo_OnInit(WFO_TIME_PERIOD optimizeWindow, WFO_TIME_PERIOD optimizeStep, int optimizeStepOffset, int optimizeCustomW, int optimizeCustomS); int wfo_OnTick(); double wfo_OnTester(); void wfo_OnTesterInit(string optimizeLog); void wfo_OnTesterDeinit(); #import
含有 wfo_set 前缀的函数是可选的。它们允许设置操作模式, 但如果不调用它们, 将使用省缺值。含有 wfo_On 前缀的函数处理相应的事件。它们应该添加到 EA 的源代码中。
以下是一则内置函数库 EA 的源代码示例。所有函数参数都直接从输入元参数中获取。#include <WalkForwardOptimizer.mqh> ... int OnInit(void) { // 您的工作代码在此 ... // 可选, 省缺为 wfo_built_in_loose wfo_setEstimationMethod(wfo_estimation, wfo_formula); // 可选, 省缺为 DBL_MAX wfo_setPFmax(100); // 可选, 省缺为 false // wfo_setCloseTradesOnSeparationLine(true); // 必修, 来自头文件的所有参数 int r = wfo_OnInit(wfo_windowSize, wfo_stepSize, wfo_stepOffset, wfo_customWindowSizeDays, wfo_customStepSizePercent); return(r); } void OnTesterInit() { wfo_OnTesterInit(wfo_outputFile); // 必修 } void OnTesterDeinit() { wfo_OnTesterDeinit(); // 必修 } void OnTesterPass() { wfo_OnTesterPass(); // 必修 } double OnTester() { return wfo_OnTester(); // 必修 } void OnTick(void) { int wfo = wfo_OnTick(); if(wfo == -1) { // 等到窗户开始 // 不会交易 return; } else if(wfo == +1) { // 等待测试窗口前瞻测试结束后 // 不会交易 return; } // 您的工作代码在此 ... }
wfo_OnInit 将所有必需的数据传递到函数库: 窗口大小, 步进, 步进量, 以天为单位的自定义窗口大小, 以窗口百分比为单位的自定义步进。在 成功的情况下返回 0, 若设置了不正确的参数, 则返回错误码 (例如, INIT_PARAMETERS_INCORRECT)。
wfo_OnTick 在优化和前瞻测试优化窗口内管理 EA。如果当前即时报价 (柱线) 落在 EA 可交易的移动帧内, 则返回 0, 如果即时报价在窗口之外, 则为 -1/+1, 且应暂时禁止交易 (-1 表示窗口未到达, 而 +1 表示窗口已经错过)。
wfo_OnTester 计算并返回给定效率参数到测试器。
wfo_setCloseTradesOnSeparationLine 设置所有市场订单的平仓模式, 并在跨越优化窗口和前瞻测试之间的边界时删除所有挂单。
实践
当内置函数库的 EA 编译完毕, 就是配置测试器的时候了。
我们在间隔字段组中选择一个特定的日期范围。这与上述的一般期间 D 相同。通常, 结束日期是当前日或接近某天。
在 前瞻 字段, 选择 无 (内置的前瞻测试不适合我们)。
设置 执行模式 为 正常, 使用柱线或控制点。请记住, 我们在前瞻优化中还包括涉及的元参数 (除了 EA 的操作参数), 从而增加了计算负担。
在 优化 模式, 您可以选择慢速 (完整排序) 或者快速模式 (使用遗传), 而 优化条件 应一直为 自定义。
允许使用遗传优化算法, 但必须牢记一些细微差别。遗传算法跳过许多输入参数的组合, 包括指定窗口大小的元参数组合, 前瞻步进的大小和步进量。这就是为什么有些前瞻测试可能不存在。如果搜索空间非常大 (如果 EA 有许多工作参数或其增量), 则这个问题比较令人瞩目, 否则可以忽略。遗漏在生成的报告中被标记, 令我们能够决定是否尝试减少优化空间。
此问题通常发生在群集优化期间。顺序或锚定前瞻优化不太容易受到影响。
遗传算法可以根据其盈利能力,在优化窗口之间不均匀地 "优先排列" 不同的平移。例如, 如果交易的第一个月比第二个交易月更困难, 则测试器可能会更加注意 wfo_stepOffset 参数, 其值为 1 而不是 0。换句话说, 基于日期范围 D 内的多窗遗传优化不会与基于特定窗口 W (函数库关闭) 的遗传优化产生相同的最佳结果。唯一的解决方案是对所有参数和元参数进行慢速全面搜索。
另一方面, 前瞻检查算法对样本外数据的稳定性, 还可以选择最佳优化历史深度和重优化的步进 (寻找新设置的频率)。这些函数通常在不搜索最佳参数的情况下执行。
配置 EA 工作参数需要以通常方式优化。元参数的配置取决于您打算启用的前瞻优化模式。
在预定时段内进行顺序前瞻优化
- 使用 wfo_WindowSize 从列表中选择优化窗口
- 从 wfo_stepSize 中的列表中选择前瞻步进
- 启用 wfo_stepOffset 的优化, 范围从 0 到与可用历史记录相适的步数, 步长为 1。
任意时段的顺序前瞻优化
- 从 wfo_WindowSize 参数列表里选择 'custom'
- 在 wfo_customWindowSizeDays 里输入天数
- 为 wfo_stepSize 参数选择 "自定义" 大小
- 为 wfo_customStepSizePercent 输入尺寸, 单位是窗口大小的百分比%
- 启用 wfo_stepOffset 的优化, 范围从 0 到与可用历史记录相适的步数, 步长为 1。
群集前瞻优化
- 在 wfo_WindowSize 中选择优化窗口大小为 "custom"。
- 启用 wfo_customWindowSizeDays 优化, 适用于任何适合的范围, 且增量以天为单位。
- 在 wfo_stepSize 中选择前瞻步进为 "custom"。
- 为任何合适的范围启用 wfo_customStepSizePercent 优化, 且增量为窗口大小的百分比 % (推荐值范围为 5-30%, 步进为5-10%)。
- 启用 wfo_stepOffset 的优化, 范围从 0 到与可用历史记录相适的步数, 步长为 1。
如果您有首选的优化窗口大小, 则只能针对不同的步进运行集群分析, 如果已经选择了步进, 则只能更改窗口大小。
锚定前瞻优化
- 在 wfo_WindowSize 中选择优化窗口大小为 "custom"。
- 在所需范围内启用 wfo_customWindowSizeDays 优化。作为增量, 选择天数等于下一步中要设置的预定时段长度 (例如, 如果要使用 "月" 步进, 增量请输入 30 天)。
- 从预定义常量的 wfo_stepSize 列表中选择步进。常数应等于窗口大小之上指定的增量。
- 禁用 wfo_stepOffset 优化, 并将其值设置为 0。
当所有设置完毕后, 运行优化并等待完成。与标准优化不同, 我们无法暂停并在处理函数库时继续该过程。这是由于测试器的暂停和延续在 MQL5 API 中没有相应的程序事件。所以, 函数库的数据高速缓存不能与测试器缓存同步。换言之, 每次按下 "开始" 按钮都会导致函数库的完整初始化, 且不管测试器的内部状态如何, 函数库将从头开始收集数据。如果恢复之前暂停的优化, 则在暂停之前由函数库收集的所有数据都将丢失。我建议在开始前瞻优化之前清除测试器/缓存文件夹。
在优化期间, WFO 创建特殊的全局变量 (保存在 GVF 扩展名的 "归档" 文件中), 并在 MQL5/Files 文件夹中创建含有数据的 CSV 文件。之后, 基于它们自动形成解码结果的 HTML 页面。GVF 和 HTML 文件名称与函数库中通过 wfo_outputFile 参数设置的 CSV 文件名相符。
我们取一个简单的 EA, 看看使用不同模式的函数库我们可以获得哪些报告。EA 是由 MQL5 向导生成, 并基于两个交易策略 — 包络线和 WPR。它在市场中作为 免费商品。
注意!此 EA 不是一个圣杯。这是一个平均样本, 唯一的目的是作为函数库的实验老鼠。
我们将在 EURUSD D1 图表上进行实验。首先, 我们尝试一个简单的滚动前瞻报告。设置整体周期 2015.01.01-2017.06.01。
图例. 2. 测试器设置
EA 具有 EnableWFO 参数, 省缺值为 "false"。在这种情况下, 函数库被禁用, EA 交易正常。若要启用函数库, 请将标志设置为 "true"。
保留 wfo_windowSize (year) 和 wfo_stepSize (quarter) 的省缺值。它们指定 1 年期的移动优化窗口, 平移为 1 个季度, 单次前瞻测试为季度。这可为我们提供 (2.5 年 - 1 年) / 3 个月 = (30 - 12) / 3 = 6 个前瞻测试步进。
在 wfo_outputFile 里设置 demo.csv 文件名。
在 EA 的工作参数需要要优化的包括止损和止盈价位, 周期和包络线偏差, 以及 WPR 周期。参数集 (wfo-demo-rolling.set) 在文章末尾附上。
图例. 3. EA 设置
优化之后, 我们得到的 demo.html 报告如下。
图例. 4. 滚动前瞻报告
正如我们所见, EA 在前瞻区间表现非常糟糕。不过, 负面结果也是有用的。
现在我们尝试得到一个集群报告, 并选择优化窗口和步进大小, 其中盈利是稳定的。要实现这一点, 将 wfo_windowSize 和 wfo_stepSize 设置为 'custom', 并将 wfo_customWindowSizeDays 从 90 到 180 天配置为 30, 且 wfo_customStepSizePercent 从 10 到 30%, 步进为 10。在 wfo_stepOffset 中接收的最大步数作为比率从 (2.5 年 - 90 天) / (90 天 * 10%) = 810 / 9 = 90 。参数集 (wfo-demo-cluster.set) 附在文章末尾。
样本报告显示如下 (参见下一节中的更多细节 — 分析)。
图例. 5. 集群前瞻报告
许多表格单元格展现出令人满意的结果。我们澄清一下120 天和 30% 步进的窗口配置意味着什么 。为此, 单击相应的单元格, 并查看前瞻测试的详细信息。
图例. 6. 澄清滚动前瞻报告
尽管取得了积极的成果, 余额曲线并不令人印象深刻。查看其它版本, 我们可以得出结论, 当前选定优化参数的 EA 不够稳定。它要么需要调整交易策略组, 亦或优化我们尚未使用的其它参数。
获得合适的结果总是需要很长时间, 使用前瞻解决方案可以简化任务, 我们只需整理出许多选项, 这将需要更多的努力来检查传统的方法。寻求改善 EA 特性的方法仍然是直观的。前瞻在这里没有提供任何帮助。它更适合这种情况, 当我们已经拥有或多或少的盈利 EA, 且需要确定其结果是否因参数匹配而实现, 以及它们能否通过彻底检查。
分析
生成的报告所包含的各种数据取决于所选的函数库模式。在集群分析中, 报告伊始的若干表格包含一组连续前瞻测试的最终参数。在每个表格中, 列对应于窗口 W 的天数大小, 行对应于步进 S (以 % 为单位)。表格中的每个单元格都是一个超链接, 指向连续前瞻测试的相应报告。因此, 可以澄清如何计算最终参数。
以下参数显示在集群分析表中:
- 年度盈利/亏损是 EA 按照优化和测试周期重新计算盈利比例时的假设年利。
- 效率是在测试和优化区间运行同一过程的年利润比率。
- 一致性是所有前瞻组合测试测算中盈利测算的百分比。
- 完整性是窗口大小和前瞻步进特定组合的前瞻执行步数。也许由于缺少一些参数值, 在遗传优化期间可能会少于请求的数量。跳过的步进数量在圆括号中表示。
- 以步进为单位的 Daus 是每个窗口大小和步进组合的天数, 将步进从 % 转换为天。
年化利润, 效率和一致性是评估前瞻测试成功的主要标准。显而易见, 它们越高越好。建议一致性在 50% 以上。集群分析表格中最好的选项以绿色高亮显示。
此外, 注意回撤, 数学期望和利润的标准背离是有意义的 — 它们可在精炼的标准报告中获得。
标准 (连续) 测试报告不仅用于集群分析版本的精炼测试, 而且还作为简单滚动前瞻优化的结果。
在标准 (连续) 或锚定前瞻测试的情况中, 报告表格包含生成此前瞻组合的所有测试器运行结果。每行包含交易参数 — 盈利, 利润因子, 交易总数和盈利交易, 回撤, 夏普比率 — 优化和测试区间分别显示。优化参数以蓝色高亮显示, 而测试区间为黄色。如果最后一步捕获到 "当前" 时间 (测试的结束日期), 则以绿色高亮表示这些是已知的最近参数, 因此它们适用于 "当前" 交易。当然, 只有当优化的结束日期设定为今天时, "当前" 时间才是最新的时间。
前瞻报告的前三列显示测试器测算索引号, 优化窗口的开始日期 (样本内) 以及测试区间 (样本外) 的开始和结束日期。报表的最后一列显示了窗口内优化结果的参数值。可通过将鼠标悬浮在列标题上来获取含有参数名称的工具提示。
在遗传优化方法的情况下, 内置报告中的测算索引号不是以数字形式显示, 而是以 "世代数量, 实例数量" 显示。这意味着您只能通过参数将内置报表的行与 WFO 函数库报表的行进行匹配。使用慢速优化方法时, 我们可以避免这个难题, 因为这两种报表中的测算索引号都是相同的。这是 MetaTrader 5 平台的功能, 而非函数库。
通过双击内置测试器报告的相应行, 我们可以在特定的前瞻优化窗口和随后的前瞻测试步进中重现 EA 交易。请注意, 在这个范围之外没有交易。如果您想看看 EA 如何在窗口外利用这个集合进行交易, 那么您应该禁用该函数库, 或者将 wfo_windowSize 设置为 "none"。
余额曲线的原理图显示在表格之后。
我们来总结一下中间结果。我们已设法直接在 MetaTrader 测试器中以简化的形式分派了前瞻优化。它可以工作并得出有趣的结果。但是, 函数库参数的设置已经变得棘手。对于某些用户, 选择正确的元参数会导致困扰。另一个问题与性能有关。由于函数库操作基于参与优化的附加元参数, 所以搜索空间显著增加, 需要更多的计算资源。是否可能以某种方式简化这种状况?是的, 有。但为了达成这一目标, 我们必须通过修改函数库的运行原则, 实际上是实现不同的函数库来重塑轮廓。
懒散和忙碌的前瞻
新的函数库也内置在 EA 中, 但它不会公开参数, 这意味无需配置。启动 EA 在通用 (递增) 区间 D 上进行优化。与通常的优化不同之处在于这一区间仅在用户所选择的窗口 W 上进行一般的优化。在 D 的优化期间, 新的函数库收集有关 EA 执行的所有交易信息 (对于不同的参数集)。换言之, 对于测试器的每次测算, 形成一个文件, 其中在每根柱线上记录当前余额, 以及浮动利润和持仓数量。事实证明, 优化完成后, 您可以根据这些数据构建各种前瞻报告。报告类似于上述讨论。在 MetaTrader 4 的情况下, 可以通过一个单独的脚本来实现, 而在 MetaTrader 5 的情况下可以通过函数库本身完成。
此函数库还有用于 MetaTrader 4 和 MetaTrader 5 的版本。我们在这里研究 针对 MetaTrader 4 的修改实现。完整的 略有不同的文档版本 (俄语) 已发表在博客上。
我们来解释一下简化函数库的操作原理。
当使用它时, 测试器其实并不实际执行优化, 而是通过输入参数的各种组合进行排序。在报告生成期间选择每个窗口的最佳优化集合。脚本从整体 D 区间分配所需的样本内 W 窗口, 计算所有测试器测算的性能参数 (每次测算是一组单独的参数), 并找到最佳选项。然后在同一次测算上, 计算随后的样本外步进 S 的交易效率参数。
该算法以非标准方式实现前瞻。这使得它易于使用, 但具有副作用。特别是地, 当使用遗传优化方法时, 由于所测试的参数集在全局意义上 (对于整个区间 D 而非当前窗口 W) 而言, 引入了一些误差。可将其视为对未来的一瞥。不过, 另一方面, 最好的全局参数比 W 窗口上的局部优化能够发现的参数产生更小的利润。
无论情况如何, 在对参数进行慢速搜索的情况下, 不存在此问题。
还应指出的是, EA 在整个 D 区间交易, 由此产生两个后果。。
首先, 在特定窗口 W 伊始, 余额可以是任意的。与 WFO 类似, 这意味着新的函数库仅适用于具有固定手数的策略。
其次, 有些仓位可能会在其持仓期跨越初始或最终窗口边界, 即, 持仓可能已存在, 并且在窗口开始处具有浮动利润, 或者可在窗口内开仓并在前瞻测试 阶段平仓。这种不准确是简化过程的必要付出。随着交易数量的增加, 其负面影响降至可忽略的数值。例如, 如果您使用净持帐户, 在窗口开始时最多可能会扭曲一笔仓位的数字, 在结束时可能最多会有一笔仓位。如果在 W 窗口中有 100 笔双向入场/离场交易, 计算中的平均误差不超过平均交易大小的 2%。
wfL.mqh 头文件中的函数库接口非常简单。
#import "wfL.ex4" int wfl_OnInit(const int cleanUpTimeout); void wfl_OnTick(); #import
嵌入 EA 的代码也大大简化了。
#include <wfL.mqh> int OnInit() { // ... 工作代码 wfl_OnInit(60); } void OnTick() { // ... 工作代码 wfl_OnTick(); }
使用与上述 WFO 函数库相同的程序进行优化。
优化区间应至少包含 200 个柱线, 但建议使用 1000 根以上。这是由于实际上一般区间划分窗口和前瞻测试步进是按照柱线完成的, 且在函数库代码中预定义了一组窗口大小和偏移量: 窗口的大小从 10% 到 50%, 增量为 10% (注意, 窗口大小设置为总测试范围 D 的百分比), 步进 S 从 5% 增加到 30%, 增量为 5%。
优化完成后, 将在 Tester/Files 文件夹中创建以下窗体的目录:
<EA name>-<Symbol>-<Timeframe>-<Date>-<Time>
它包含 csv 文件, 含有测试器每次测算期间由函数库收集的元数据。文件中的每一条都包含一根柱线的信息: 日期和时间, 余额, 浮动利润和开仓交易的数量。利用这些数据, 您可以计算区间内任何窗口的损益。有关独立交易的信息不会存储或分析。
将含有所有文件的指定的文件夹从 Tester/Files 移动到 MQL4/Files, 您可以运行报告生成脚本 — 在输入参数中指定文件夹名称。还要指定要在特定窗口中选择最佳参数集的优化条件。可用条件与完整版本的 WFO 函数库中的相同。结果就是, 我们通过精炼连续的前瞻测试 (其示例显示如上) 获得了一个集群报告。
上述所有的小缺点都可以通过卓越的生产率和易用性轻松降低。由于这里没有元参数, 因此, 与基于选定工作参数的 EA 常规优化相比, 前瞻优化不会引入任何间接成本。
结束语
我们已研究了在内置测试器当前构建并实现前瞻优化技术的可能性原理。上述的现成函数库令您以最小的工作量测试该方法。函数库的一些简化和限制提供了传统的易用性, 且无需任何外部应用即可区分前瞻结果。直到 MetaTrader 拥有内置的前瞻优化能力, 此函数库提供了一个有效的替代方案。产品汇总表
产品 | MetaTrader 4 | MetaTrader 5 |
---|---|---|
WFO: WalkForwardOptimizer & WalkForwardReporter |
||
WalkForwardOptimizer 函数库 |
||
WalkForwardReporter 脚本 |
(无需, MT5 WFO 函数库自动生成报告) |
|
WalkForwardDemo EA |
(无) | |
WFL: WalkForwardLight & WalkForwardBuilder |
||
WalkForwardLight 函数库 |
||
WalkForwardBuilder 脚本 |
(选项) |
单击图标将引导至相应产品的页面。
演示 EA 前瞻分析的连续 (滚动) 参数— wfo-demo-rolling.set
演示 EA 前瞻分析的集群参数 — wfo-demo-cluster.set