MetaTrader 5终端策略测试器中的订单生成算法

MetaQuotes | 30 八月, 2013


创建EA交易程序 - MQL5中的自动交易系统

MetaTrader终端中包含了一个开发完全自动策略(交易机器人)的集成开发环境,这些完全自动的策略可以在无人参与的情况下进行交易。这些交易机器人的另外一个名字是EA交易程序,在MetaTrader 5中,EA交易程序和技术指标是使用MQL5语言编写的,这种语言包含了现代编程语言中所有先进的方面。

MQL5的除错能力使您能够编写安全级别最高的代码,这当然非常必要,但是开发一个能赚钱的交易系统还需要其他条件。能够在很大历史时间跨度上展示出正面结果的交易系统,可以称为稳健,这个词从英文的"robust"中得来,是容纳错误的意思。


测试交易策略

在把您的资本委托给EA交易程序之前,您必须确定它开启和关闭仓位的规则,还有资金管理,以及允许利润预期等,测试这些方面的最简单的方法是用历史数据来模拟EA交易程序的工作。

MetaTrader 5客户终端中有一个特别的集成组件,就是策略测试器,可以获得EA测试程序在历史数据下工作的结果。使用EA交易程序在一个时间段下运行一次的过程称为EA交易程序的测试,这样的一次测试可以提供给我们大量有用的信息,对我们判断EA交易程序的稳健性很有必要。

但是为了能够信任这些结果,测试的过程在建模的过程中必须和EA交易程序运行的真实现实环境尽可能地接近。MetaTrader 5测试器使用的是各个订单形式模拟价格,使用的是各种资产在操作时差价的历史数值。


策略测试器的一些历史


MetaTrader 3

第一个策略测试器最早出现在MetaTrader 3终端中。和当今现代标准相比它是相对简单的,它进行测试是基于在柱上价格生成的三种模型:

价格建模总是基于测试时周期的柱的,更小周期的信息没有使用。MetaTrader 3终端中的测试器有很多缺点,包括测试速度很慢,精度低,也没有EA交易程序输入参数的优化功能。

MetaTrader 4

MetaTrader 4终端替代了第三代终端,包含了一种新的编译语言 - MQL4 (之前的 MQL-II 是解释型的), 它也在测试方面迈进了绝对崭新的一步。现在测试可以有三种模式进行:

MetaTrader 4中一个很重要的和第三代终端中测试策略的差别是它使用最小级别的周期做交易的模拟,这样,根据分钟历史上的表现,在测试周期内,结果和在线结果达到最大程度的接近。如果较低级的周期历史缺失了,测试器中柱内价格变化的模拟就和MetaTrader 3测试终端一样。

另外,我们得到了直接枚举输入参数以及使用遗传算法进行优化的机会. 这给了我们极大加快优化过程的机会,特别是策略中包含大量的输入参数。现在可以在可视化控制下进行真实的测试了. 这是交易者们喜爱的一大步。

第五代MetaTrader新终端是基于前任终端的设计经验的,这些经验被应用到了策略测试器中。现在有机会进行多币种策略的测试了,比如在多个设备上同时交易的策略测试。

策略的优化现在不仅可以在处理器内核中进行,也可以运行于位于局域网或者因特网上其他计算机的远程代理上面,这使您可以建立强大的测试器进行云计算,这在MQL5语言之前是不可能的。

但是为了对MetaTrader 5终端测试过程有个基本了解,理解策略测试器中的价格模型是很关键的。


订单生成算法

MetaTrader 5中的策略测试器只使用一种模式来进行测试价格模拟 - 订单是根据所用货币对已有历史数据中的分钟周期所生成的。在MetaTrader 4中其他的模拟模式被去掉了,因为虽然它们的速度很快,但是它们不能提供高度精确的测试。

使用测试器的M1周期可以非常精确地模拟价格的移动,和其他基于更高级别时间周期的订单模拟相比,它的错误是最少的,这样,MetaTrader策略测试器对价格建模的错误是非常少的,模拟价格和真实价格的差异只会在分钟柱级别才会出现。

在本地和远端代理都能够进行优化的能力,可以抵消测试时间的增长,订单是基于缓存的分钟级数据,以整数格式生成的,这样,订单的生成非常快。

测试器中所有所需时间周期的价格柱都是根据历史数据的,这和通常方式(就像在客户终端中)接收到订单的生成是一样的。如果分钟柱只有一个订单,它不会生成订单 - 它会被标注为收盘


如果分钟柱有两个订单,也不会生成订单 - 第一个订单值记录为开盘, 另外一个订单被记录为收盘

          



分钟柱有三个订单,会根据规则生成订单,三个订单的分钟柱有四种柱生成的模式:
  1. 向一个方向发展然后达到开盘的级别;




  2. 向一个方向发展,再返回,然后到达开盘级别;




  3. 向一个方向发展,再返回,但是没有到达开盘的级别;




  4. 几个点在同一个方向上




支撑点

如果一个柱有超过三个订单,首先产生支撑点,支撑点的数量不能超过订单的数量,开盘价不包括在支撑点击数中,因为它是起点,支撑点最多有11个,

支撑点分布在开盘影线,蜡烛范围和收盘影线中, 


根据订单数量在支撑点之间的分布(开盘影线 - 蜡烛范围 - 收盘影线):

3 - 5 - 3
2 - 6 - 2
2 - 5 - 2
2 - 4 - 2
2 - 3 - 2
1 - 4 - 1
1 - 3 - 1
1 - 2 - 1
1 - 1 - 1
如果蜡烛没有某根影线,在这些影线上支撑点的分布就转到蜡烛上。



蜡烛的范围是由奇数个支撑点产生的,如果范围内有偶数个支撑点,那么“额外”的点会放到已经有两个支撑点的影线中,否则,额外的点就算消失了。

支撑点的数值反映了支撑点的价格和蜡烛开盘价的差异,一个牛市(白色)蜡烛上支撑点的理想的分布(3-5-3)是:





一个熊市(黑色)蜡烛生成支撑点的3-5-3模式是一样的:




如果蜡烛是十字星, 就是说开盘价==收盘价, 那么就分析前一个蜡烛,如果前一个蜡烛是价格上升的,十字星就被认为是个价格下跌的蜡烛;



如果影线由三个支撑点生成,而且影线大小的4/3整数值与影线大小的1/2是相等的(这种情况发生的情况是:开盘价最低价或者开盘价最高价相差不超过两个点), 影线的生成则改成以下方法:

 

如果影线有两个支撑点生成,控制点会如下安排:




收盘影线的生成方式是同样的。


支撑点的基础生成是从低价到高价生成

蜡烛的范围是由脉冲波生成的,波的数量计算如下:

波的数量 = (范围内支撑点数量 + 1) / 2.

举个例子,如果蜡烛范围内支撑点数量等于5,那么会生成3个波 = (5 +1) / 2.

每个脉冲波都有一定点数的步长, 由以下公式计算:

步长=(最高价点数-最低价点数-1)/(波的数量)+1

再举个例子,蜡烛的范围 (最高价 - 最低价) = (1.3113 - 1.3100) = 0.0013 等于13点数, 波的步长 = (13-1) / 3 +1 = 5个点。

在脉冲的一步过后,点数会回滚1点。进一步看,支撑点的价格是这样计算的 (针对牛市蜡烛):


前一价格=最低价
循环
  n1=前一价格+步长
  n2=前一价格+步长-1
  前一价格=n2

其中:

让我们把这种算法应用到3-5-3模式下,波数等于3,步长等于5点,一个点等于0.0001:

  1. 第一步. 变量 前一价格 = 最低价 = 1.3100, 进入循环,
  2. 计算第一波数据
    • 我们计算第一波n1点的价格 n1 = 前一价格 + 步长 = 1.3100 + 5 * 0.0001 = 1.3105.
    • 我们计算n2点的价格 n2 = 前一价格 + 步长 -1 = 1.3100 + 5 * 0.0001-1 * 0.0001 = 1.3104;
    • 给前一价格赋值为n2: prev = 1.3104;
  3. 计算第二波数据
    • 计算n1点的价格 n1 = 前一价格 + 步长 = 1.3104 + 5 * 0.0001 = 1.3109.
    • 计算n2点的价格 n2 = 前一价格 + 步长 -1 + 5 = 1.3104 * 0.0001-1 * 0.0001 = 1.3108;
    • 把前一价格赋值为n2:前一价格=1.3108;
  4. 计算第三波数据
    • 计算n1点价格 = 前一价格 + 步长 = 1.3108 + 5 * 0.0001 = 1.3113.
    • 退出循环, 前一价格 = n2 = 1.3112

上面的所有演示在图片中看的更清楚:


计算熊市蜡烛支撑点的方式是一样的:


前一价格=最高价
循环
  n1=前一价格-步长
  n2=前一价格-步长+1
  前一价格=n2


订单的生成是基于支撑点的

支撑点中间的订单时根据如下规则生成的:


检测订单顺序

综上所述, 让我们比较MetaQuotes-Demo服务器在2010年5月13日13:00到13:30的订单历史和MetaTrader 5客户终端测试器生成的订单,一个EA交易程序用来在代理日志中记录下订单:

//+------------------------------------------------------------------+
//|                                                  Write_Ticks.mq5 |
//|              Copyright Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+

input datetime start=D'2010.05.13 13:00:00';
input datetime end=D'2010.05.13 14:00:00';

//+------------------------------------------------------------------+
//| 交易程序订单函数                                                   |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick tick;
   datetime time=TimeCurrent();
//---
   SymbolInfoTick(Symbol(),tick);
   Print(time,tick.bid);
//---
   if(time>end) ExpertRemove();
//---
  }

订单历史是在线采集的,使用的是在文章建立订单号指标中描述的指标来做的。

两种订单顺序 - 一种来自测试器另外一种来自储存的文件 - 都显示在图表中,测试中生成的订单用绿色表示,MetaQuotes-Demo交易服务器中的由文件记录的订单用蓝色表示,


你可以用鼠标指向图表中的任意点,在弹出窗口中阅读每个订单号信息:

图表清晰地显示出MetaTrader 5客户终端测试器中模拟订单的质量允许自历史数据上充分测试EA交易。