下载MetaTrader 5

基于 Bill Williams 所著《证券交易新空间》的 EA 交易程序

12 九月 2013, 07:02
Alexey Klenov
0
2 141

简介

在本文中,我将依据 B. Williams 所著的《证券交易新空间:如何从股票、债券和商品交易中的混沌获利》一书讨论针对MetaTrader 5平台,以 MQL5 语言进行的 EA 交易程序的开发。该策略本身已经广为人知,并且其使用在交易者之间仍然备受争议。

它吸引新来者的地方是其准备就绪的“几乎完全”不含主观因素的信号研究,举例而言,与 Elliott 波动理论的解释相比。但这仅仅是初看起来,在某些地方仍然不得不由交易者做出决定。本文将进一步讨论这一点。

本文的目的:
  • 使用面向对象编程开发一个 EA 类,该类依据 B. Williams 的策略实施交易。我们称之为C_TS_BW
  • 在 C_TS_BW 中,当可能时使用来自标准库中的现有代码。
  • 编写一个使用 C_TS_BW 类的 EA;
  • 在几个 Forex 和 CFD 工具中在策略测试程序内测试开发的EA;
  • 最后,在当前市场情形中确认或反驳此策略的适宜性。

1. 指标

在交易系统的资料库中有来自 4 个指标的信号:

  1. 鳄鱼指标
  2. 分形指标
  3. 动量振荡指标
  4. 加速/减速振荡指标

1.1. 鳄鱼指标

鳄鱼技术指标是运用分形几何学和非线性动态学的一组平衡线(移动平均线)。

  • 蓝线(鳄鱼的颚) - 是用于构建图表的时间框架内的平衡线(13 根价格线的平滑移动平均线,并将数值向未来方向移动 8 根价格线);
  • 红线(鳄鱼的牙齿) - 是低一级的有效时间框架内的平衡线(8 根价格线的平滑移动平均线,并将数值向未来方向移动 5 根价格线);
  • 绿线(鳄鱼的唇) - 是再低一级的有效时间框架内的平衡线(5 根价格线的平滑移动平均线,并将数值向未来方向移动 3 根价格线)。

鳄鱼指标的唇线、齿线和颚线显示出不同时间框架的相互作用。由于仅在 15-30% 的时间内才能确定市场趋势,因此我们必须跟随趋势,并且避免仅在某些价格范围内波动的市场。

当颚、齿和唇线闭合或缠绕在一起时,鳄鱼即将睡觉或已经在睡觉。当鳄鱼睡觉时,其饥饿程度会增大 - 因此,睡得越久,醒来时就越饥饿。当鳄鱼醒来时,它做的第一件事就是张开大嘴并开始打哈欠。然后它开始闻到食物的味道:牛肉或熊肉,然后开始猎食。当鳄鱼吃饱时,它开始对食物-价格失去兴趣(平衡线合在一起) - 这正是兑现利润的时候。

1.2. 分形指标

所有市场都有这样的事实:在大多数时间内,价格并不会大幅波动,并且只有很短时间 (15-30%) 的趋势变化能被看到。取得利润的最佳时期是市场价格依据某种趋势变化时。

分形(Fractals)- 是 Bill Williams 交易系统的 4 个指标之一,用于探测底部和顶部。上分形的技术定义是一系列的至少五根连续的价格线,其中最高的高价之前有两根较低的高价,而之后亦有两根较低的高价。相反的形态(一系列的五根价格线,其中在最低的低价之前有两根较高的低价,而之后亦有两根较高的低价)则为下分形。在图表中,分形有最高价和最低价,分别用向上或向下的箭头表示。

分形技术指标的信号需要使用鳄鱼技术指标来过滤。换言之,如果分形位于鳄鱼齿线的下方,我们不应买入;如果分形位于鳄鱼齿线的上方,我们不应卖出。分形信号一旦形成并且在鳄鱼颚线外的位置是有效的,则它一直会是信号,只至它被击穿为止,或者直至更新的分形信号出现为止。

1.3. AO(动量振荡指标)

Bill Williams 的动量振荡指标 (Awesome Oscillator, AO) - 是从 5 根价格线的中点(价格线的中点 (H + L)/2)的简单移动平均值减去 34 根价格线的中点(价格线的中点 (H + L)/2)的简单移动平均值。让我们知道目前在市场驱动力的作用下发生了什么。

1.4. AO(加速振荡指标)

价格是最后变化的因素。在价格变动之前,市场的驱动力会改变,而在驱动力改变其方向之前,驱动力的加速度应减小并到零。然后它开始加速,直至价格开始改变方向。

加速/减速振荡技术指标 (Accelerator/Decelerator Oscillator, AC) 衡量当前驱动力的加速和减速。此指标会在驱动力发生变化前改变方向,反之驱动力又会在价格发生变化前改变其方向。理解 AC 是一个早期警告信号让您具有明显的优势。


2. 信号

B. Williams 所著《证券交易新空间》一书所描述的交易系统使用来自五个交易维度的信号。

  • 第一维:越过鳄鱼颚线外的分形;
  • 第二维:来自 AO (Awesome Oscillator) 指标的信号;
  • 第三维:来自 AC (Accelerator Oscillator) 指标的信号;
  • 第四维:区间交易;
  • 第五维:平衡线交易。

有关来自各个维度的信号的更多信息。

2.1. 有关按第一维信号进行交易的描述

"A" 分形(买入信号)是虚假的,因为价格突破出现在鳄鱼颚线的下方。通过对 "B" 分形的执行,我们建了一个卖出持仓。随着 "C" 分形的出现,我们平卖出持仓,并且已经有一个净的买入持仓。

随着 "D" 分形的出现,我们再次将仓位从买切换到卖。越过表示买入的 "E" 分形,市场再次告诉我们仓位需要从卖出转为买入。通过对来自 "G""J" 分形的信号的执行,我们添加了更多买入持仓合约。

图 1. 第一维信号交易示例

图 1. 第一维信号交易示例

2.2. 有关按第二维信号进行交易的描述

实施了两类第二维信号。即 AO (Awesome Oscillator) 指标零线穿越和“碟形”信号。让我们接受柱状图分度,如我们在MetaTrader 5中的一样,即作为时间系列。信号检查将在零柱上进行。

对于“零线穿越”形态的形成,必须要有两个指标柱。

当第二个指标柱低于零线,而第一个指标柱高于零线时,买入信号即形成。第一个指标柱的最高价将是信号,如果超过,使用当前价的买入订单将被发送到服务器。以相反方向穿越时即形成卖出信号。

对于“碟形”形态的形成,必须要有三个连续的指标柱,并且第二个指标柱应是红色的,高于零线,同时第一个指标柱必须是绿色的并且高于第二个指标柱。信号价格将是第一个指标柱的最高价,该价格将一直有效,直到被当前价格超越或形成新的买入信号为止。“碟形”形态的卖出信号的形成是类似的,但是出现在指标的另一侧。

对于“碟形”形态的形成,必须要有三个连续的指标柱,并且第二个指标柱应是红色的,高于零线,同时第一个指标柱必须是绿色的并且高于第二个指标柱。信号价格将是第一个指标柱的最高价,该价格将一直有效,直到被当前价超越或形成新的买入信号为止。“碟形”形态的卖出信号的形成是类似的,但是出现在指标的另一侧。

“双峰”和“双底”信号不在本文的考虑范围之内,并且也不会在 EA 中设置,因为它们的形成几乎都在鳄鱼的另一侧出现:双底在颚线的下方,而双峰在该线的上方。依据此类信号进行交易会与系统矛盾,原因是为了不被鳄鱼吞食,我们不能在颚线下方买入,也不能在颚线上方卖出。

欲知这些信号的详细描述,我建议您参阅原文。

图 2. 第二维信号交易示例

图 2. 第二维信号交易示例


2.3. 有关按第三维信号进行交易的描述

在第三维中,有 AC (Accelerator Oscillator) 指标形成的“在零线上方买入”和“在零线下方卖出”信号。

我们首先看一看图 3 中的形态。针对零指标柱进行检查。如果第一个指标柱高于零线(情形 "A"),在柱状图中包含两条绿色柱和一条红色柱。与此同时,第二个指标柱和第三个指标柱相对于零线的位置并不重要。

如果第一个指标柱低于零线(情形 "B"),则我们需要三个绿色柱和一个红色柱才能形成一个买入信号。还不考虑余下的指标柱与零线的关系。第三维卖出信号相反类似的。

欲知更加详细的描述和例子,请参阅原文。

2.3. 第三维信号交易示例

图3. 第三维信号交易示例


2.4. 第四维信号交易(“区间交易”)

对于某些指标柱,当两个指标 (AO+AC) 都是绿色时,即形成绿色区间。

交易信号的形成需要两个连续的绿色区间,并且第一个指标柱的收盘价必须高于第二个指标柱的收盘价。

一旦新的指标柱开盘,就可以执行。在原文中,执行应是指标柱收盘时的订单。存在指标柱收盘的最后一个价格变动能够改变 AO 或 AC 指标柱颜色的情形,如果出现这种情形,则依据绿色区域信号买入是错误的。出于这些原因,我使用新指标柱的开盘进行买入。

在第四维中,也有一个信号用于跟踪买入持仓的止损单。

这需要五个连续的绿色区域。第一个区域的最低价用于设置止损。如果止损单在下一个指标柱上(在其收盘后)未触发,则在新指标柱开盘时我们将止损设置为上一个已收盘的指标柱的最低价(应高于止损单),而不考虑上一指标柱的区间颜色。

我们还通过连续绿色区间的数量来限制已建买入持仓的增加:B. Williams 建议使用 6 或 8 个区间。之后,我们应等待灰色(当AO 和 AC 的指标柱的颜色不相同时)或红色区间的出现,此时将再次允许填充仓位以从绿色区间买入。

卖出信号形成“红色区间”- 绿色区间的镜像。区间的颜色也反应出形成“平衡线交易”(第五维)信号的指标柱的数量。对于此线,B. Williams 选择鳄鱼的“牙齿”。

在此信号中,我想强调:零指标柱的 OHLC 价格参与信号的形成。

图 4. 第四维信号交易示例

图 4. 第四维信号交易示例


2.5. 有关按第五维信号进行交易的描述

“在平衡线上方买入”形态(如果是绿色区间)由两个指标柱形成。如果零指标柱的开盘价(也是此时指标柱的最高价)低于指标柱的上一最高价(可在前面的几个指标柱中找到),则找到的最高价将是在绿色区间中建立一个买入仓位的价格。

红色或灰色区间要求另一个最高价高于进入绿色区间的价格。一旦我们找到它(通常不超过前面 10 个指标柱,并且高于鳄鱼指标的齿线 [在作者原文中我没有找到对于此类形态必须要往前寻找多少个指标柱]),请作为进入红色或灰色区间的价格记住它,并且方向是买入。

要通过“在平衡线上方买入”信号建仓,我们检查当前价是否超过每个新的指标柱上的价格(对于绿色/红色/灰色区间)。

图 5. 第五维信号交易示例

图 5. 第五维信号交易示例


3. C_TS_BW 类

3.1. 类的目的:
  • 如有可能,使用标准库中的类;
  • 大量“类似的数据”应存储在结构中;
  • 自定义设置;
  • 从指标获得所需数量的计算得出的数据以供分析;
  • 新的指标柱时,检查来自五个交易维度的信号;
  • 当是新的价格变动时,检查建仓信号;
  • 计算固定手数或金字塔式手数(您将在该类的 CalcLot 方法中了解此算法);
  • 允许针对各种信号直接更改 EA 的手数。实施资金管理算法的自定义需要;
  • 跟踪已建仓位的止损单。如有必要,更改用户从 EA 计算出来的止损价;
  • 向交易服务器发送订单,并且在错误时进行二次请求;
  • 禁止交易信号的重复(每个信号仅进入一次);
  • 最大程度地减少公共类方法的数量;
3.2. C_TS_BW 类的实施
  • ...如有可能,使用标准库中的类和方法;

要执行此任务,您首先需要包含来自标准库的适当文件。

这通过以下代码来实施。

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh

在类的private部分,为交易请求的组织声明对象,获取有关交易品种和已建仓位的信息,以及访问订单的历史记录。

CTrade            exp_trade;    // 标准库中的交易方法
CSymbolInfo       s_info;       // 标准库中访问交易品种的方法
CPositionInfo     pos_info;     // 标准库中获得仓位信息的方法
CHistoryOrderInfo h_info;       // 访问订单历史的方法
  • ... 大量“类似的数据”存储在结构中。

该类使用四个结构,其中两个在private部分中声明。这两个结构如下:

struct l_signals            // 保存信号和柱出现时间的结构
struct l_trade              // 保存最后触发信号时间的结构

public部分中也有两个结构:

struct  s_input_parametrs   // 调整参数的结构
struct  s_actual_action     // 对应交易订单的结构

以下对象具有这些类型的结构:

l_signals         last_signals;     // 信号
l_trade           last_trade;       // 处理过的信号
s_input_parametrs inp_param;        // 接受的设置的内部结构
s_input_parametrs inp_param_tmp;    // 接受设置的结构 (通过类初始化中的链接得到)
s_actual_action   actual_action;    // 服务器上的订单

可以在附加的标题文件中找到有关结构代码的更多信息。

  • ... 自定义设置;

使用public部分中的Init方法实施此任务。用于从 EA 调用的参数:

string Symbol_for_trade             // 此类的交易品种
ENUM_TIMEFRAMES Period_for_trade     // 交易品种图表的周期,这时将会发生信号搜索及其处理
s_input_parametrs &inp_param_tmp   // 类设定的结构

在此方法中,也会发生所涉及指标的初始化以及对于从这些指标接收数据而言必不可少的缓存的整理。

  • ... 从指标获得所需数量的计算得出的数据以供分析;

可以使用private部分中的 CopyIndValue 方法进行。

int type       // 我们需要的类型  (0- 鳄鱼, 2 - АО, 3 - АС  )
int countValue // 数据量

视参数类型而定,针对计算出来的数据自动替换接收缓存,作为类初始化的时间系列组织。

  • ... 在新的指标柱的开盘期间 ...

在新指标柱开盘之后,仅执行一次信号搜索。为此,我们需要确定该时刻。NewBar 方法执行此功能,它没有输入参数,当收到的价格变动建立新的指标柱时,它返回 true,否则返回 false。

  • ... 检查来自五个交易维度的信号;

对于每个交易维度,我开始一个单独的方法。第一维信号由 FindSignal_1_dimension 来检查。

调用参数:

int type               // 分形搜索的方向 (0- 买入, 1 卖出)
double &price_out[]   // 在成功搜索后,这个数组包含分形价位 
datetime &time_out[]  // 在成功搜索后,这个数组包含分形被找到的柱的时间

第二维的分析将由FindSignal_2_dimension方法来进行。调用参数:

int type               // 搜索到的方向 (0-在买入方向, 1-在卖出方向)
int sub_type         // 搜索的子类型 (0- 零点线交叉信号, 1- 碟形信号)
double &price_out[]   // 在成功搜索后,这个数组包含信号对应的价位 
datetime &time_out[]  // 在成功搜索后,这个数组包含信号对应柱的时间

第三维的分析是通过含有输入/输出参数的FindSignal_3_dimension方法进行的:

int type              // 搜索的方向 (0-在买入方向, 1-在卖出方向)
int sub_type           // 搜索的子类型 (0-  2柱相同信号, 1- 3柱相同信号)
double &price_out[]    // 在成功搜索后,这个数组包含信号对应的价位
datetime &time_out[]   // 在成功搜索后,这个数组包含信号对应的柱的价位

第四维的处理是通过含有输入/输出参数的FindSignal_4_dimension方法进行的:

int type               // 搜索的方向 (0-在买入方向, 1-在卖出方向)
int sub_type          // 我们在找什么 (0- 区域信号, 1- 连续5区同色进行移动止损)
double &price_out[]   // 在成功搜索后,这个数组包含信号对应的价位
datetime &time_out[]  // 在成功搜索后,这个数组包含信号对应的柱的时间

第五维受 FindSignal_5_dimension 的监视。此方法的参数如下:

int type               // 搜索的方向(0-在买入方向, 1-在卖出方向)
int sub_type          // 搜索子类型(0-  2柱信号, 1- 3柱信号)
double &price_out[]   // 在成功搜索后,这个数组包含信号对应的价位
datetime &time_out[]  // 在成功搜索后,这个数组包含信号对应的柱的时间

整个检查通过 CheckSignal 方法统一在一起,该方法没有输入参数,并且包含:

  • 复制来自指标的数据;
  • 针对某些鳄鱼指标线检查平仓(如果使用的话);
  • 重置前一指标柱的信号;
  • 搜索两个方向上的活动分形;
  • 视仓位的可获得性而定,在建仓位方向搜索第二维至第五维的信号。

此方法在public部分声明,需要从 EA 调用。

  • 随着新的价格变动的到来,检查触发建仓信号的可能性;

在此类中实施 CheckForTradeSignal 方法,该方法搜索按当前价进入仓位的可能性。

调用参数:

int dimension        // 维度编号 (从1到5)
int type            // 交易的方向 (0- 买入, 1- 卖出)
int sub_type         // 交易维度子类型 (在信号搜索时已描述)
double &price_out[]  // 信号价位
datetime &time_out[] // 信号柱的时间

如果满足激活一个信号的所有要求,则我们返回 true,否则返回 false

对处理所有信号的能力的检查与 CheckActionOnTick 方法结合在一起,该方法在 public 部分中声明,需要从 EA 调用。调用不需要参数。每个成功的信号都存储在 actual_action 对象中,之后将在 TradeActualSignals 方法中处理这些信号。

  • …计算固定手数或金字塔式手数

CalcLot 方法public 部分中声明,并且可从 EA 调用。它用于计算手数以及进一步修改在类的 private 部分中声明的变量 Lot。调用参数:

bool external // 如果需要外部计算交易手数,需要把这个变量设为 true, 
              // 然后通过 ext_lot 值设置手数. 
              // 在类内部 (计算手数), 这个变量被设为 false.
double ext_lot // 外部手数大小
int type // 手数计算类型 
         //(0- 起始手数 (使用初始化类时传入的参数值), 
         //-1- 转换手数 (起始手数和当前仓位手数的和), 
         // 从 5 到 2 的数值用于渐进交易模式开启的时候 (即 "金字塔式").
         // 在这种方式下: 5 – 开始,  乘以5, 
         // 4 – 开始,  乘以 4,
         // 3 – 开始,  乘以 3, 
         // 2 – 开始,  乘以 2,
         // 1 -  执行手数等于开始手数

现在,我们已经考虑了固定手数,让我们更多地谈谈金字塔式手数。

让我们从等于 0.1 的手数开始。例如,通过从鳄鱼颚线外部的分形信号开始手数来建仓,总仓位将为 0.1 手。之后我们开始分析出现的第二维至第五维信号。一旦信号被触发,向未平仓位填入 0.5 手(开始,乘以 5),然后获得仓位的总量 0.6 手。在建仓方向的下一个信号期间,填入 0.4 手,总仓位将等于 1.0 手。

在建仓方向的下一个信号将使我们增加另外的 0.3 手,因此总量将为 1.3 手。第五次填入将增加 0.2 手,仓位的总量将变为 1.5 手。以下仓位方向上的填入仅变化 0.1 手。

这种资金管理 (ММ) 算法是由 B. Williams 在Trading Chaos(《混沌操作法》)一书中描述的。安装用户手数的可能性让我们能够切实可行地实施任何资本管理。

为了正确地确定一笔买卖中订单的顺序,我使用各种幻数。

幻数

订单描述

999

转向订单

1000

开始订单

1001

填入订单(开始 Х 1)

1002

填入订单(开始 Х 2)

1003

填入订单(开始 Х 3)

1004

填入订单(开始 Х 4)

1005

填入订单(开始 Х 5)

类计算需要的幻数(使用 CalcMagic 方法),之后在发送新的订单之前,将用该数确定在服务器上的交易操作。

  • …允许针对各种信号从 EA 更改手数。

如果需要,可以在 EA 中实施对 actual_action 结构的查询,交易信号以布尔变量的形式存储在该结构中。每个类型和方向都对应一个变量。如果我们得到 true 值,则对于此价格变动,类将尝试按指定的交易信号产生交易操作,之后可以更改此信号的手数。对于每一次价格变动,该类仅为未平仓位或平仓发送一个订单。

可以在调用 CheckActionOnTick 方法之后以及在调用 TradeActualSignals 之前在 EA 中设置手数。因为在当前价变动上可以有若干信号等待执行,只会选择其中一个信号。

信号执行的顺序如下:

  • 平仓;
  • 执行分形信号之一(建仓、重新平仓、转向);
  • “碟形”信号;
  • “零线穿越”信号;
  • AC“两根同色指标柱”
  • AC“三根同色指标柱”
  • 区间交易;
  • 平衡线(二指标柱信号);
  • 平衡线(三指标柱信号);

因此,在安排“用户”手数大小期间有必要考虑此顺序。

  • ... 跟踪已建仓位的止损单。如有必要,更改用户从 EA 计算出来的止损价。

在所描述的类中,有维护仓位止损价的功能,通过 Trailing Stop(跟踪止损)方法实施,意味着止损的拉升,仅限于增大此仓位利润的方向上,用于在此价格触发。有五种维护模式:

  • 按鳄鱼指标的唇线;
  • 按鳄鱼指标的齿线;
  • 按鳄鱼指标的颚线;
  • 按相同颜色的连续五个区间(绿色区间买入、红色区间卖出);
  • 止损价的外部设置。

安装止损的第五个选项通过 SetStopLoss 方法实施,该方法有一个参数 double & stoploss。必须从 EA 进行调用,并且必须在执行 TrailingStop 方法之前,该方法针对仓位的修改检查价格,并且向服务器发送请求。成功执行此过程之后,内部变量 StopLoss 的值被重置到 -1。

  • ...控制向服务器发送建仓订单,并且在发送不成功时进行二次请求。

对于发送用于建仓、平仓或仓位转向的交易订单,使用 boolSendOrder 方法。调用参数:

ENUM_ORDER_TYPE type   // 交易操作的方向
double &price_out[]   // 信号价位的指针, 成功执行操作后, 设为 -1;
datetime &time_out[]  // 信号时间的指针, 成功执行操作后, 设为 -1;
string comment         // 订单注释

所有交易信号的测试都结合使用 TradeActualSignals 方法。结构 actual_action 存储交易订单。成功将订单发送到服务器后(SendOrder 返回 true),重置结构 actual_action 中的交易信号。交易信号将一直有效,直到我们获得有关发送的正面响应。

在结构 actual_action 中还有一个没有参数的函数 init,用于重置所有当前信号。当建立新仓位或现有仓位出现转向时使用此过程。

  • ...禁止交易信号的重复(每个信号仅进入一次);

last_trade 结构存储每个类型和方向的最后一个交易信号的时间。在您将一个交易订单设置到 actual_action 结构之前,进行检查以确定此交易信号是否已经在 last_trade 结构中,如果是,则忽略该信息。因此,这对一种交易情形的“可放弃”执行的控制提供了实施方法。

  • 最大程度地减少公共类方法的数量。

以下是可通过从 EA 调用而获得的类方法的列表:

void C_TS_BW();                                      // 构造函数
bool Init(string Symbol_for_trade,
           ENUM_TIMEFRAMES Period_for_trade,
          s_input_parametrs  &inp_param_tmp);       // 类初始化
bool NewBar();                                           // 在当前交易品种/周期图表中检测新柱
void CheckSignal();                                 // 搜索信号
void CheckActionOnTick();                              // 收集当前订单的所需操作
void TrailingStop();                                // 移动止损
void TradeActualSignals();                             // 根据当前信号交易
void SetStopLoss(double  &stoploss);                  // 设置止损价位
void CalcLot(bool external,double ext_lot,int type); // 计算手数

以下结构也可供使用:

actual_action    // 当前准备执行的订单
inp_param_tmp;   // 设置的结构
                   // (在类初始化中根据链接得到数据)


4. 使用 C_TS_BW 类实施 EA

必须要做的第一件事是在 EA 交易程序中包含 h_TS_BW.mqh 文件。

#include <h_TS_BW.mqh>

之后,声明 C_TS_BW 类的对象。让此对象名为 EA_TS_BW。

您也会需要可调整参数的结构,例如 s_input_parametrs、input_parametrs。

以下描述植入到此结构的参数:

input_parametrs.alligator_jaw_period        // 鳄鱼指标: 颚线周期
input_parametrs.alligator_jaw_shift         // 鳄鱼指标: 颚线转换
input_parametrs.alligator_teeth_period      // 鳄鱼指标: 齿线周期
input_parametrs.alligator_teeth_shift       // 鳄鱼指标: 齿线转换
input_parametrs.alligator_lips_period       // 鳄鱼指标: 唇线周期
input_parametrs.alligator_lips_shift        // 鳄鱼指标: 唇线转换
input_parametrs.add_1_dimension              // 允许增加分形
input_parametrs.add_2_dimension_bludce     // 允许 根据 “碟形”信号 (АО) 增加维度
input_parametrs.add_2_dimension_cross_zero // 允许 根据 "零点线相交"信号 (АО)增加维度 
input_parametrs.add_3_dimension_use_2_bars // 允许 根据 "АС 2柱"信号 增加维度 
input_parametrs.add_3_dimension_use_3_bars // 允许 根据 "АС 3柱" 信号增加维度input_parametrs.add_4_dimension_zone       // 允许 根据红区绿区信号增加维度
input_parametrs.add_5_dimension             // 允许 根据平衡线增加维度
input_parametrs.max_4_dimension_zone       // 区域中连续相同颜色柱的最大值 
input_parametrs.trall_4_dimension           // 允许根据区域中5个相同颜色柱信号设置移动止损
input_parametrs.agress_trade_mm            // 激进型建仓
input_parametrs.support_position           // 仓位的移动止损类型
input_parametrs.lot                           // 交易手数

在 EA 的 OnInit() 部分,您需要:

  • 将数据填入 input_parametrs 结构的所有必需参数,这些数据之后会被传递到类。
  • 使用类的 Init 方法进行初始化。示例:
expert_TS_BW.Init(Symbol(),PERIOD_CURRENT,input_parametrs)

在此示例中,EA 交易程序将处理其安装所在的当前交易品种/周期。

EA 交易程序的 OnTick() 部分的示例:

//   double Sl[1];  
   if(expert_TS_BW.NewBar()) // 图表出现新柱
     {
      expert_TS_BW.CheckSignal();       // 搜索信号
     }
   expert_TS_BW.CheckActionOnTick();    // 检查当前订单需要的操作
//---******************* 开始交易量与止损的外部控制 
//--- 比如根据信号地区设置交易量

//   if(expert_TS_BW.actual_action.zone_buy || expert_TS_BW.actual_action.zone_sell)
//     {expert_TS_BW.CalcLot(true,0.11,0);}
//--- 根据抛物线设置止损

//   CopyBuffer(h_parabolic,0,0,1,Sl);
//   if (Sl[0]>0){expert_TS_BW.SetStopLoss(Sl[0]);}
//---*******************外部控制交易量和止损结束 

   expert_TS_BW.TrailingStop();           // 移动止损 (如有必要)  
   expert_TS_BW.TradeActualSignals();     // 当前信号的交易

在此示例中,止损价和交易手数的外部控制的例子,针对类的执行,被注释掉了。

5. 历史记录的某些测试

编写 EA 所依据的一书的作者声称此系统着重于股票和商品市场。

首先,让我们在 CFD 上检查 EA 交易程序。假定测试多边形是 IBM 历史记录的一部分。系统瞄准报价的趋势段。我采用第一个可用的段,肉眼就可以在该段上看到某种趋势。

图 6. 品牌IBM 图

图 6. 品牌IBM 图

在此段上运行写好的 EA 交易程序,以下是我们作为订单得到的结果。

图 7. Bill Williams 的交易信号 (IBM)

图 7. Bill Williams 的交易信号 (IBM)

第一眼看上去,有很多按趋势进行的交易,这很好。这里有一张由策略测试程序创建的图。

交易是按 0.1 手进行的,没有鳄鱼指标线的闭合,没有使用五个连续单色区间的跟踪止损,也没有进取性交易(金字塔式)。

图 8. 测试结果

图 8. 测试结果

整体而言,我们获利了。

让我们分析一个不是很陡的延长趋势。

图 9. IBM 图(片段 2)

图 9. IBM 图(片段 2)

让这里有相同的交易品种和 13 个月的周期(从 2008 年 12 月至 2010 年 1 月)

以下是来自策略测试程序的图表:

图 10. 依据历史记录测试系统的结果(片段 2)

图 10. 依据历史记录测试系统的结果(片段 2)

我们姑且说它“不满意”或“没有达到我们的预期”。

接下来,我要检查对货币交易的效果。

让我们采用著名的 EURUSD(欧元美元)交易对和图表的 H1 周期。历史记录的深度为 2010 年。

图 11. 依据历史记录测试系统的结果,EURUSD,H1,2010 年

图 11. 依据历史记录测试系统的结果,EURUSD,H1,2010 年

让我们在同一年(2010 年)EURUSD 的每日指标柱上试一试。

测试程序的报告看起来如下:

图 12. 依据历史记录测试系统的结果,EURUSD,D1,2010 年

图 12. 依据历史记录测试系统的结果,EURUSD,D1,2010 年


总结

本文旨在检查 Bill Williams 提出的著名交易策略之一的性能,不仅仅是在股票市场和商品交易中,也在外汇市场中。系统对去年的 EURUSD 日线图“或多或少”有作用,但是在没有尝试优化的情况下在更短的时间框架内并没有带来盈利。

系统的入场信号非常准确(如果我们看日线图的话),但是退出信号却明显延迟了,因为超过一半的利润没有兑现。此领域面向给定系统的改进,针对更短的时间框架进行优化。

可以在附加文件中找到类的完整代码。


本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/139

附加的文件 |
h_ts_bw.mqh (104.25 KB)
交易系统的评估 - 有关进入、退出与交易效率的概述 交易系统的评估 - 有关进入、退出与交易效率的概述

有很多指标可用于确定一个交易系统的效率和盈利能力。但是,交易者始终会将任何系统推向一个新的崩溃测试。本文讲述基于效率指标的统计如何用于 MetaTrader 5 平台。它包含一个类,该类用于将成交统计解释转变成与 S.V. Bulashev 所著《Statistika dlya traderov(面向交易者的统计)》一书不冲突的一种解释。它还包括一个用于优化的自定义函数示例。

MQL5 简介:如何编写简单的EA 交易和自定义指标 MQL5 简介:如何编写简单的EA 交易和自定义指标

相比 MQL4,MetaTrader 5 客户端的 MetaQuotes 编程语言 5 (MQL5) 具有许多新的发展潜力和更高的性能。本文将帮助您熟悉这一新的编程语言。文中给出了编写EA 交易和自定义指标的简单示例。我们还会涉及到 MQL5 语言的一些细节,这些细节对于理解示例是必要的。

自适应交易系统以及它们在 MetaTrader 5 客户端中的运用 自适应交易系统以及它们在 MetaTrader 5 客户端中的运用

本文推荐一种由很多策略组成的自适应系统,每种策略执行其自己的虚拟交易操作。实际交易依据当时最赚钱策略的信号进行。归功于使用面向对象的方法、标准库中用于处理数据的类和交易类,系统的架构看起来很简单并且可扩展;现在,您可以轻松地创建和分析包含数以百计的交易策略的自适应系统。

在 MQL5 中使用对象指针 在 MQL5 中使用对象指针

默认情况下,MQL5 中的所有对象都通过引用传递,但还有使用对象指针的可能性。然而,由于对象可能没有初始化,我们必须执行指针检查。在这种情况下,MQL5程序可能会因为关键性错误而终止并卸载。自动创建的对象不会引起此类错误,因此就此意义而言它们十分安全。通过本文,我们将理解对象引用和对象指针之间的差异,并思考如何编写使用指针的安全代码。