终端 MetaTrader 4 中的测试程序:应该了解

MetaQuotes | 29 二月, 2016

简介

在金融市场工作不能没有交易系统。交易者们花费了大量时间和精力制定建仓和平仓的规则,并从经验出发选择通过追踪止损修改仓位的方法。这会用到来自各个科学领域的知识。在创建策略之后,第一件事是测试机械交易系统 (MTS) 的历史数据。这意味着,测试程序将成为任何程序的最重要的部分。


两种建模类型:

并非所有进行技术分析 (TA) 的程序都有测试选项,因此并不包括每个终端!即使程序声明拥有测试程序和测试选项,也可能有错误或结构限制和禁止。这就是为什么,在终端 MetaTrader 4 的测试程序开发过程中预先包括体系结构解决方案非常重要,因为根据对未来的了解,它会阻止整个类别的策略的出现。程序测试任何策略的方式有两种:

三角形“当前时间”表示测试程序在当前时间点所处的位置。在第一个例子中,我们看到测试程序已处理数据的过去时间(“过去”)以及测试程序将进行操作的将来时间(“将来”)。过去和将来都已计算(指标、收盘价、开盘价、最高价和最低价),测试程序只是遵循此序列。如果有能够预测未来(真实或错误)的可能性,测试的结果需要进行彻底的验证。关闭已知的可能性并不确保没有其他可能性。最终,这对于测试程序开发人员或测试程序用户而言一直是个问题。

在第二个例子中,我们只有过去时间(“过去”),本质上没有未来(黑色方格)。在这种方法中,我们始终只有关于过去的信息,没有关于将来的信息,就像在真实交易中一样。随着我们当前移动的测试程序中每次出现新的价格变动(价格改变),当前时间三角形将移至新的已知时间的右侧并收到新的价格。每次新的价格变动都会创建“当前”,增加关于“过去”的信息,其前面仍有黑暗的未知“将来”。在这种情况下,无论交易者在编写策略时是否犯错,测试程序在本质上是无法预测未来的。

这就是这两种方法之间的差异。第一种创建测试程序的方法提供了简单而快捷的测试假象,第二种方法保证,在相等的价格变动下,所有编写的策略的运行方式将与实时交易中的运行方式相同。这就是为什么为测试程序建模的序列保存为文件(fxt 文件)的原因,其中包含柱体状态的快照,此文件可像普通的图表一样使用菜单“文件” - >> “脱机打开”打开。


测试程序文件由带字母 G (已生成)的图标标记,提供有关建模类型、已建模价格变动范围、柱体数和时间范围的信息:

例如,如果我们打开文件 EURUSD M15,我们将看到为测试程序构建 15 分钟柱体模型的方式:



上图显示了柱体在 15 分钟时间范围内的进度。在测试 Expert Advisor 时,测试程序看到了完全按照这种序列的 15 分钟烛台 (2006.04.21 10:00)。分钟柱体上的价格变动次数等于测试期间的烛台变动次数。因此,在每个时间点上,测试程序将看到正确的开盘价(固定不变,等于 Open[0])、正确的最高价和最低价(在柱体进度期间可能会变化)(分别等于当前的 High [0] 和 Low[0])以及最新了解的买入价(等于当前 Close[0] 价,在柱体结束之前会发生变化)。同时还对交易量进行了尽可能准确地建模,这在不断增大的绿色交易量直方图中显而易见,就像在一个简单的图上。红色虚线表示周期 1 的移动平均数(简单移动平均线)指标。此移动平均数显示了在测试期间的每个时刻的平仓头寸。

注意!MetaTrader 4 中的测试程序处理每次价格变动根本无法预测未来


针对测试交易品种的不同时间范围建模

MetaTrader 4 中的测试程序不仅允许查看测试的时间范围,还允许查看其他 - 更高和更低的 - 时间范围。因此,如果我们在时间范围 EURUSD M15 上测试 Expert Advisor,我们可以看到 EURUSD H1 或 EURUSD M5 的指标的值。我们还可以在任何可用的时间范围 EURUSD 上看到当前零柱体的最高价和最低价。如果我们需要获得当日的最高价,我们只需查看值 iHigh(NULL,PERIOD_D1,0)。这类似于网上交易。测试 Expert Advisor 时所在的时间段与 Expert Advisor 在实时模式下所连接到的图表的时间范围并无区别。

因此,测试程序的任务是不仅正确为当前时间范围建模,还为所有其他必要的时间范围建模。在测试程序中将按照以下方式解决此任务:不仅对当前零柱体的柱体进度建模,还按照相同的方式对所有其他时间范围建模。每次收到新的价格变动都将更改有关每个时间范围上的零柱体条件的信息,所有操作同步执行。下面是一张图片:



在这里,蓝色表示完成的柱体,绿色——当前零柱体,正在不断的变化。图中的 +1 表示收到新的价格变动。所有必要的已建模时间范围将即时收到每次价格变动。要确认这一点,你可以启动对简单 Expert Advisor CheckModelling.mq4 的测试,将显示测试程序在每个时间点可用的价格。

将对所有请求的时间范围(不仅是价格,还有交易量)正确建模。测试程序将看到每个时间范围上的同步价格进度,就像实际情况一样:


很明显,15 分钟时间范围的最低价与更高的时间范围的最低价不同。而最高价的情形也是如此。然而,在收到新的价格变动时,所有时间范围上的买入价相同。

重要事项: 已测试交易品种的所有时间范围也已准确建模 - 开盘价、最高价、最低价和收盘价已 100% 准确地建模。更高时间范围的交易量也已 100% 准确地建模。


针对其他交易品种的价格建模

要准确地测试历史记录,有时需要大量的建模数据,还可能需要更多的内存和处理器资源。MetaTrader 4 中的测试程序不允许执行组合测试,但计算机技术发展非常迅速,也许不久我们就能够准确地测试用于针对各种交易品种建仓的复杂策略。不过,MetaTrader 4 中的测试程序允许接收有关不同于已测试交易品种的其他交易品种的价格信息。但在这种情况下,不会执行建模,且数据按原样提取。在进程初期引入时,零柱体被简化为以下形式:High[0]=Low[0]=Close[0]=Open[0], Volume[0]=1,能够在柱体开始时了解价格,但在结束时不了解价格。要确认这一点,只需在“每次价格变动”模式下在 EURUSD 上测试简单 Expert Advisor。

//+------------------------------------------------------------------+
//|                                               CheckModelling.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/|
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/"
 
//---- input parameters
extern int       DayS=21;
extern int       MonthS=4;
extern int       YearS=2006;
extern int       HourS=10;
extern int       MinuteS=00;
extern int       CounterS=20;
int counter;
int start()
  {
//----
   if (counter>CounterS) return;
   if (Year()<2006) return;
   if (Month()<MonthS) return;
   if (Day()<DayS) return;
   if (Hour()<HourS) return;
   if (Minute()<MinuteS) return;
   Print("My time frame   "," Open=",Open[0],"  High=",High[0],"   Low=",Low[0],
      "  Close=",Close[0],"  Volume=",Volume[0],"  Bid=",Bid);
   Print("30 minute frame "," Open=",iOpen(NULL,PERIOD_M30,0),"  High=",iHigh(NULL,PERIOD_M30,0),
      "   Low=",iLow(NULL,PERIOD_M30,0),"  Close=",iClose(NULL,PERIOD_M30,0),
      "  Volume=",iVolume(NULL,PERIOD_M30,0),"  Bid=",Bid);
   Print("1 hour frame    "," Open=",iOpen(NULL,PERIOD_H1,0),"  High=",iHigh(NULL,PERIOD_H1,0),
      "   Low=",iLow(NULL,PERIOD_H1,0),"  Close=",iClose(NULL,PERIOD_H1,0),
      "  Volume=",iVolume(NULL,PERIOD_H1,0),"  Bid=",Bid);
   Print("4 hour frame    "," Open=",iOpen(NULL,PERIOD_H4,0),"  High=",iHigh(NULL,PERIOD_H4,0),
      "   Low=",iLow(NULL,PERIOD_H4,0),"  Close=",iClose(NULL,PERIOD_H4,0),
      "  Volume=",iVolume(NULL,PERIOD_H4,0),"  Bid=",Bid);
 
   counter++;  
//----
   return(0);
  }
//+------------------------------------------------------------------+

建模期间的指标计算

十年前,由于家庭计算机和工作站的性能不强,软件开发人员受到了限制。有限的运行内存、处理器频率低于 100 MHz——所有这些因素导致针对交易策略只能使用空间效率最高的计算和测试类型。根本不存在 intrabar 测试,所有需要的指标都是事先计算好的,然后以现成、不变的形式进行测试。那时它是单一解决方案,这给测试带来了限制。使用这种方法,我们只能收到柱体结束时刻的正确指标值,在零柱体上使用此数据实际意味着预测未来。

MetaTrader 4 中的测试程序不接收任何计算的数据,它只获取已建模价格的进度,同时根据新输入的价格,在测试的过程中计算所有必要的指标。也就是说,所有指标的计算方式与在网上操作的方式相同。这是测试程序的充分优势,但如果指标的算法不是最优的,EA 的测试速度会大幅降低。测试程序中的指标计算速度与终端中的速度一样快,并且看不到未经优化的算法。但在 MetaTrader 4 的测试程序中,在对数百万个柱体(EURUSD 从 1999 年起的分钟历史记录包含将近三百万个柱体) 进行计算期间,任何非最优状态都将变得显而易见。不要忘记,分钟柱体的每次价格变动建模并非只提供一次价格变动,而是多次,之后测试程序将计算每次价格变动。

现在,处理器拥有数千兆字节的运行内存和数千兆赫兹的频率,32 位体系结构被 62 位体系结构取代,甚至出现了多重处理。但是,仍有很多人正在使用上个世纪的各种机器,将上一代 TA 程序和开发人员的所有缺点都归因于 MetaTrader 4 测试程序。这些人害怕 intrabar 建模,他们认为这是一个不正确的测试程序操作。MetaTrader 4 中的测试程序不仅提供在任何时间范围上对价格正确建模的可能性,还提供在基于历史的策略测试中执行此方法的必要性。

你可以观看视频,估算测试程序中的价格进度和指标计算:


重要事项:测试程序执行需要特定资源的真实测试模型。


由于对测试程序的正确价格建模认识不足而提出的常见问题

MetaTrader 4 于 2005 年 7 月 1 日正式发布,从那以后,各个论坛上经常出现相同的问题,这些问题涉及测试程序的错误操作。下面是由于对以往的测试程序认识不足而提出的最多的问题。


总结

MetaTrader 4 中的测试程序是根据 2000 年以来长期累积的编写几代交易终端的丰富经验编写而成的。所做的一切都是为给交易者提供一个尽可能准确地测试策略的机会。从而,不需要在实时模式下花费数个月时间来测试交易想法。但是,了解测试程序的所有选项有助于节约时间以及更好地认识到正确指标和 EA 开发的重要意义。