English Русский Español Deutsch 日本語 Português 한국어 Français Italiano Türkçe
学习如何基于 ADX 设计交易系统

学习如何基于 ADX 设计交易系统

MetaTrader 5交易 | 26 七月 2022, 08:59
1 874 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

概述

本文将介绍一种新的技术交易工具,这是最有用和有意义的工具之一,可以帮助我们更好地交易和了解行情走势。 因为技术指标最有用的特征之一就是它们可以表达价格无法示意的内容,而这将基于每个指标的计算方式,其中一个有用的指标是平均方向指数(ADX)指标。 我们将详尽地学习这个指标,从而能够更好地理解它,并学习如何在简单策略里运用它,因为当我们深入学习一些东西时,我们将能够获得更多的认知,并可更好地运用它。

我们的学习将贯穿以下主题:

  1. ADX 定义
  2. ADX 策略
  3. ADX 策略蓝图
  4. ADX 交易系统
  5. 结束语

贯穿 ADX 定义主题,我们将详细讨论什么是平均方向指数(ADX)指标,及其测量值,以及如何手工计算它,从而加深对其理解,并能够用它获利。 然后,在充分理解该指标及其工作原理后,我们将探讨一个可以在交易中使用的简单策略,这部分会放在 ADX 策略的主题之后。 然后在 ADX 策略蓝图的主题中,我们将学习如何设计蓝图,来帮助我们编写其代码,从而为该策略设计实现交易系统。 然后我们将学习如何运用此策略编写交易系统,这部分会在 ADX 交易系统的主题来实现。

我们将使用 MetaTrader 5 交易平台和 MetaQuotes 语言编辑器,该编辑器内置于 MetaTrader 5 当中,您可以通过以下链接下载它:https://www.metatrader5.com/zh/download

下载并安装 MetaTrader 5 之后,您会发现它与交易平台的下图相同:

MT5 

我建议您自己应用本文中的所有内容,因为这能快速拓展您的技能,并令您对这个主题有深刻的理解。 实践是任何发展的关键。 因此,最好尝试应用每个概念,并亲自测试,因为我们将学习如何运用技术工具来设计交易系统,我们将通过 MQL5 编写一些代码来创建智能交易系统或程序,从而帮助我们更好地进行交易。 基本需求还要有一个演示帐户来进行测试和应用,如果您不知道做,可以通过 MetaTrader 5 本身开立演示帐户,方法是在 MetaTrader 5 终端按“文件”选项卡-->开户-->您可以输入经纪商的名称,通过他们开立一个演示帐户,或者选择 “MetaQuotes-->下一步-->选择开立无风险资金演示帐户进行虚拟交易”-->下一步-->输入您的数据并确定帐户要求,然后勾选“我同意-->下一步-->然后找到您的演示帐户凭据-->完成。

您现在就可以使用此帐户进行虚拟交易了,方法是单击“文件”选项卡-->登录到交易帐户-->输入您的演示帐户凭证,然后按“确定”。

免责声明:所有信息“按原样”提供仅用于教学目的,并非出于交易目的或建议。 所有信息不能保证任何结果。 如果您选择在您的任何交易账户上使用这些材料,您将自行承担风险,您是唯一的责任人。

现在,我们开始学习一种新的工具,它可以令我们的交易结果变得更好。


ADX 定义

在这一部分中,我们将详细探讨技术交易世界中最流行的指标之一,来了解它是什么,它衡量什么,以及我们如何计算它,如此即能够更好地理解它,然后我们就可以在策略里实现它,甚至通过围绕它的新思路来更好地加以运用它。 该指标是平均方向指数(ADX),由威尔斯·怀尔德(Welles Wilder)开发,用于测量并确认是否存在趋势,因为根据其计算,它取一个时期的交易范围,并与此前一个时期的交易范围进行比较。

从比较的结果当中,我们可以发现:

  • 提升或衰退(正向走势或负向走势)。
  • 无提升或衰退。
  • 提升或衰退。

如果有正向走势,则意味着一个周期的高点超过了前一个周期的高点,其符号为(+DM)。

下图向我们展示了它的价格动作在图表上是如何进行的:

+DM

且反之亦然,如果存在负方向走势,则表示一个周期的低点超过前一个周期的低点,其符号为(-DM)。

下图向我们展示了它的价格动作在图表上是如何进行的:

-DM

如果我们没有得到正向走势,也没有负向走势。 这意味着高点没有超过之前的高点,低点没有超过之前的低点。

下图向我们展示了它的价格动作在图表上是如何进行的:

无 +DM-DM

如果我们正向走势、负向走势两者兼而有之。 这意味着高点超过了先前的高点,低点超过了先前的低点。

下图向我们展示了它的价格动作在图表上是如何进行的: 

 +DM-DM

我们来了解如何计算它,因为它将为我们提供更多的认知。 因此,以下是计算(ADX)的步骤,需要注意的是,所有数值都必须是绝对值:

1- 计算 +DM 和 -DM:

在这一步中,我们需要判定与前一步相比,当前走势是向上还是向下。 因此,我们将计算两件事:

  • 如果有向上走势,则 (+DM) 指正向走势。 
它将通过(+DM = 当前高点 - 前一高点)来计算
  • 如果有向下走势,则 (-DM) 指负向走势。 
它将通过(-DM = 当前地点 - 前一地点)来计算

因此,我们将检查每个计算周期,并检查它是否为 +DM,-DM,或任何其它值。

  • 如果我们得到 +DM,那么:
+DM=n
-DM = 0
  • 如果我们得到 -DM,那么:

-DM = n

+DM = 0

在某些情况下,我们可以找到其它场景,此刻(+DM 和 DM)没有数值;或者我们发现找到(+DM 和 DM)均有数值;下面是我们如何处理这样情况的:

  • 如果我们没有 (+DM 和-DM),那么:

+DM = 0

-DM = 0

无 DM

  • 如果我们有 (+DM 和-DM) 两者的数值,那么我们将在 +DM 和 -DM 之间进行比较,并考虑最大值,如果数值彼此相等,则忽略这些值:
+DM>-DM = 只会考虑 +DM,

 +DM 更大

+DM<-DM = 只会考虑 -DM

-DM 更大

+DM=-DM = 两者均被忽略

+DM 等于 -DM

2- 计算真实范围(True Range -TR):

在这一步中,计算 DM 之后,我们将计算(TR),它是以下公式中的最大值:

  • 当前最高价和最低价之间的差值。
  • 当前最高价高与前一个收盘价之间的差值。
  • 当前最低价和前一个收盘价之间的差值。
3- 求已计算出的 14 个周期的总和(+DM、-DM 和 TR)

已计算的前 14 个周期(+DM、-DM 和 TR)求和之后,我们将使用以下公式计算 14 后期后的以下值:

+DM 15 = (前一 +DM - (前一 +DM/14)) + 当前 +DM

-DM 15 = (前一 -DM - (前一 -DM/14)) + 当前 -DM

TR 15 = (前一 TR - (前一 TR/14)) + 当前 TR

4- 计算 14 周期的 +DI 和 -DI
+DI 14 = 100*(+DM14/TR14)
-DI 14 = 100*(-DM14/TR14)

5- 计算 +DI 和 -DI 之间的差值

DI 14 差值 = (+DI 14) - (-DI 14)

6- 计算 +DI 和 -DI 的合计

DI 14 合计 = (+DI 14) + (-DI 14)

7- 计算 DX

DX = 100*((+DI 和 -DI 之间差值)/+DI 和 -DI 的合计))
8- 计算 ADX
ADX = DX 的 14 周期均值

经由前面的步骤,我们能计算 ADX,现在我们来看一个应用这些步骤的示例,假设我们有以下数据:

天数 最高价 最低价 收盘价
1 110 90 100
2 140 120 130
3 160 120 140
4 150 110 130
5 140 100 130
6 150 130 140
7 170 150 160
8 180 160 170
9 170 150 155
10 170 130 140
11 180 155 160
12 190 175 180
13 220 190 190
14 230 200 200
15 215 205 210
16 200 190 200
17 195 180 190
18 195 180 185
19 210 185 195
20 220 190 200
21 233 195 208
22 246 200 216
23 258 205 223
24 271 210 231
25 283 215 238
26 296 220 246
27 308 225 253
28 321 230 261
29 333 235 268
30 346 240 276

我们计算之前数据的 ADX:

1- 计算 +DM 和 -DM:

+DM = 当前最高价 - 前一最高价

-DM = 当前最低价 - 前一最低价

示例 - DM

2- 计算 TR:

它将是以下各项中的最大值:

  • 当前最高价和最低价之间的差值。
  • 当前最高价高与前一个收盘价之间的差值。
  • 当前最低价和前一个收盘价之间的差值。

下图是计算后得到的 TR:

示例 - TR

3- 已计算出的 14 周期的 +DM、-DM 和 TR 求合:

+DM 14 = 合计 +DM 1(天数 2: 天数 15)

-DM 14 = 合计 -DM 1(天数 2: 天数 15)

TR 14 = 合计 TR (天数 2: 天数 15)

示例 - 14 DM-TR

4- 计算 14 周期的 +DI 和 DI,第一次计算将从第 15 天开始,因为我们需要 14 DM 来计算 14 DI:

+DI14 = 100*(+DM14/TR14)

-DI14 = 100*(-DM14/TR14)


5- 计算 +DI 和 -DI 之间的差值

DI 14 差值 = (+DI 14) - (-DI 14)

6- 计算 +DI 和 -DI 的合计

DI 14 合计 = (+DI 14) + (-DI 14)

DI14 - 差值和合计

7- 计算 DX:

DX = 100*((+DI 和 -DI 之间差值)/+DI 和 -DI 的合计))


DX

8- 计算 ADX,第一次计算将是 28 天,因为我们需要更多的 14 天来计算 ADX:

ADX = 14 周期的 DX 均值 --> DI (天数 15: 天数 28) 均值


ADX

现在,我们手工计算 ADX 指标,但我们不需要这样做,因为它内置于 MetaTrader 5 当中,我们只需学会如何计算它即可,如此加深我们对 ADX 指标及其工作原理的理解。 如果我们需要将其插入到图表中,我们需要做的就是从交易终端的可用指标中选择它,通过(插入-->指标-->趋势-->平均方向移动指数),从下面您可了解我们如何做到这一点:

ADX 插入

选择“平均方向移动指数”后,将出现以下窗口:

ADX 窗口

该窗口用于 ADX 指标的参数,它们与以下相同:
  1. 确定所需周期。
  2. 确定 ADX 线的颜色。
  3. 确定 ADX 线的类型。
  4. 确定ADX线的宽度。
  5. 确定 +DI 线的颜色。
  6. 确定 -DI 线的颜色。
  7. 确定 +DI 线的宽度。
  8. 确定 -DI 线的宽度。
  9. 确定 +DI 线的类型。
  10. 确定 -DI 线的类型。

确定 ADX 所有参数并按“确定”后,它将被加载到图表上,下图就是一个示例:

ADX 加载

ADX 策略

在这一部分中,我们将看到可以采用 ADX 指标的简单策略,我想在这里提到的是,我们只提供了一些基于 ADX 指标的简单策略,您必须知道,ADX 可以在许多策略里运用,从简单到复杂,但在本文里,我们只提到一些简单的策略,这是为了理解指标背后的概念,并学习如何根据指标背后的概念来设计交易系统。

基于 ADX 指标计算背后的概念,它显示出是否存在趋势,无论这种趋势是什么(上行还是下行),如果 ADX 曲线向上移动,这意味着存在趋势,反之亦然,如果 ADX 曲线向下移动,这意味着没有趋势。 但首先我们需要定义趋势,它将与以下内容相同:

趋势定义:

为您提供的信息,价格动作非常重要,它向我们显示了趋势类型,正如我们所知道的那样,我们有三种趋势(上行趋势、下行趋势和横盘)。

上行趋势:它是行情方向或趋势,我们能够看到价格创造了更高的低点和更高的高点,价格上涨,在该行情走势中由买家控场。

下图是该行情方向或趋势的形式:

上行趋势形式

下图是行情上行趋势的一个示例:

上行趋势示例

下行趋势:它是行情方向或趋势,我们能够看到价格创造了更低的高点和更低的低点,价格下跌,在该行情走势中由卖家控场。

下图是该行情方向或趋势的形式:

下行趋势形式

下图是行情下行趋势的一个示例:

下行趋势示例

横盘:它是除了上行或下行趋势以外的任何行情方向,没有明确的方向,并在买家和卖家之间维持平衡。

以下是该行情方向的一些形式:

横盘形式 1

横盘形式 2

横盘形式 3

横盘形式 4

下图是一个行情横盘的示例:

横盘实例

在趋势识别之后,我们将看到能够运用 ADX 概念的一些简单策略。

  • 策略一: 简单 ADX 系统 - ADX 走势:

该策略基于 ADX 曲线的移动,

当前 ADX 值 > 前一个 ADX 值 = ADX 正在上升,

当前 ADX 值 < 前一个 ADX 值 = ADX 正在下降。

  • 策略二: 简单 ADX 系统 - 上行趋势:

根据这一策略,处于上行趋势期间,

ADX 值 > 25 且当前 ADX 值 > 前一个 ADX 值 --> 当 +DI 值 > -DI 值 = 做多

  • 策略三: 简单 ADX 系统 - 下行趋势:

根据这一策略,处于下行趋势期间,

ADX 值 > 25 且当前 ADX 值 > 前一个 ADX 值 --> 当 +DI 值 < -DI 值 = 做空


ADX 策略蓝图

在这一部分中,我们将为每个策略设计一个蓝图,来帮助我们创建交易系统,该蓝图将辅助我们逐步组织和设置我们所需的程序或系统。

  • 策略一: 简单 ADX 系统 - ADX 走势:

根据该策略,我们需要程序在每次即时报价来临时检查当前 ADX 值和前一个 ADX 值,然后判定当前 ADX 值是否大于前一个 ADX 值,如果当前值大于前一个的值,则我们需要系统在图表上显示一条注释,在新的一行中显示 “ADX 正在上升”,“ADX 值为 (n)”,在另一行中,“ADX 最后值为 (n)”。 如果当前 ADX 值小于前一个 ADX 值,则我们需要系统在图表上显示一条注释 “ADX 正在下降”。如果当前 ADX 等于前一个 ADX,则我们的系统什么也不需要做。

下图是这一策略的蓝图:

ADX 走势蓝图

  • 策略二: 简单 ADX 系统 - 上行趋势:

根据该策略,我们需要系统检查每次即时报价来临时的当前 ADX 值、前一个 ADX 值、+DI 值和 -DI 值,然后我们需要由它们来判定当前 ADX 值是否大于 25 和前一个 ADX 值。 如果它不比两者更大,我们的系统什么都不需要做;如果它大于两者,那么我们需要系统检查 +DI 和 -DI,如果 +DI 大于 -DI,或不大于 -DI,如果 +DI 大于 -DI,我们需要系统在注释里标明做多信号,ADX 值是(n),ADX 最后值是(n),+DI 值是(n),并且 -DI 值是(n);或者如果 +DI 不大于 -DI,我们的系统什么都不需要做。

下图是该策略的蓝图:

ADX - 做多信号蓝图

  • 策略三: 简单 ADX 系统 - 下行趋势:

根据该策略,我们需要系统检查每次即时报价来临时的当前 ADX 值、前一个 ADX 值、+DI 值和 -DI 值,然后我们需要由它们来判定当前 ADX 值是否小于 25 和前一个 ADX 值。 如果它不比两者更小,我们的系统什么都不需要做;如果它小于两者,那么我们需要系统检查 +DI 和 -DI,如果 +DI 小于 -DI,或不小于 -DI,如果 +DI 小于 -DI,我们需要系统在注释里标明做空信号,ADX 值是(n),ADX 最后值是(n),+DI 值是(n),并且 -DI 值是(n);或者如果 +DI 不小于 -DI,我们的系统什么都不需要做。

下图是该策略的蓝图:

ADX - 做空信号蓝图

ADX 交易系统

在这最有趣的部分中,我们将了解如何为上述简单策略创建一个交易系统,以便在 MetaTrader 5 交易终端中使用它们,我们将使用内置的 MetaQuotes 语言编辑器(MQL5)编写此交易系统的代码;在打开 MetaTrader 5 交易终端时,您可按下 F4 键打开此 MetaQuotes 语言编辑器,或单击 MetaTrader 5 --> “工具”选项卡,然后选择 “MetaQuotes 语言编辑器”。

下图展示了如何做到这一点:

Metaeditor 打开 1

或者您可以按下 IDE 按钮:

Metaeditor 打开 2

之后,将打开以下 MetaQuotes 语言编辑器窗口:

Metaeditor 窗口

然后,我们将打开一个新文件,通过单击“新建”来创建我们的交易系统:

Metaeditor 窗口 2

然后以下窗口将被打开:

Metaeditor - 新建文件

以下是新文件类型的选项:

  1. Expert Advisor: EA 是终端中的一个程序,可根据预定条件自动化交易过程。
  2. Custom Indicator: 这种类型的程序代码可帮助我们读取图表,来改进交易决策。
  3. Script: 在执行后仅能执行一次任务的程序。

现在,我们选择创建一个智能交易系统(EA)文件来创建我们的交易系统。

首先,我们将创建一个程序,该程序可在图表上用当前 ADX 值显示注释,以下是实现该操作的步骤:

  • 创建一个价格数组,我们将使用 “double” 函数,该函数用分数部分表示数值:
double PriceArray[];
  • 为所创建的价格数组里的当前数据设定排列顺序,我们将使用 “ArraySetAsSeries” 函数,它在成功时返回 true,在失败时返回 false(bool — 布尔值)。 其所需参数为:
数组[] 是按引用,和标志

ArraySetAsSeries(PriceArray,true);

  • 识别 ADX 指标,我们将使用 “iADX” 函数,它返回 ADX 技术指标的句柄,其参数为:
symbol 作为字符串、period 是时间帧和 ADX 周期,它们将与以下内容相同:
  • _Symbol: 当前品种
  • _Period: 当前时间帧
  • 14: 计算周期
int ADXDef = iADX(_Symbol,_Period,14);
  • 依据创建的 ADX 指标填充数据,我们将使用 “CopyBuffer” 函数,该函数返回已复制的数据数量,或在出现错误时返回 -1。 其参数为:
indicator 句柄,buffer_num 指标缓存区编号,start_time (数据和时间的起始时间),stop_time (数据和时间的终止时间),和 buffer[] (目标数组)。
CopyBuffer(ADXDef,0,0,3,PriceArray);
  • 获取 ADX 的值,以 “double” 类型创建 “ADXValue” 变量后,我们将使用函数 “NormalizeDouble”,它返回具有预设精度的双类型值,其参数为: 
value 是双精度类型值 (规格化数字),和整数型小数位 (小数点后面的位数)
double ADXValue=NormalizeDouble(PriceArray[0],2);
  • 显示含有当前 ADX 值的注释,我们将使用 “Comment” 函数,其参数为:
任何值,我们在它们之间用逗号分隔,当我们需要在新的一行中显示其中一些值时,我们可使用换行符 “\n” 
Comment("ADX Value is ", ADXValue);

如果您想看看该程序的完整代码,可查看以下内容:

//+------------------------------------------------------------------+
//|                                            Simple ADX System.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
//creating an array for prices
   double PriceArray[];

//sort price array from current data
   ArraySetAsSeries(PriceArray,true);

//identify ADX
   int ADXDef = iADX(_Symbol,_Period,14);

//Filling data according to created ADX
   CopyBuffer(ADXDef,0,0,3,PriceArray);

//Getting value of current data
   double ADXValue=NormalizeDouble(PriceArray[0],2);

//Comment with ADX value
   Comment("ADX Value is ", ADXValue);
  }
//+------------------------------------------------------------------+

编写此程序完毕之后,我们可以在 MetaTrader 5 交易终端的导航器窗口中看到此程序文件,如下所示:

Nav

双击文件,或将其拖放到图表上之后,将出现以下窗口:

Simple ADX window

在“允许算法交易”旁勾选,并按下“确定”按钮后,文件将被加载到图表上:

简单 ADX 加载

然后,将根据该交易系统得出的结果显示,下图是一个示例:

简单 ADX

现在,我们已创建的内容可有助于显示当前 ADX 值,然后我们需要添加一些帮助我们设计交易系统的内容。我们需要编写一个程序,帮助显示 ADX 指标的其它值(+DI 值,和 -DI 值),以下就是如何做到这一点:

  • 为每个数值(ADX 值、+DI 和 -DI)创建价格数组,并用 “double” 类型为其创建变量:
    • ADXArray: 用于 ADX 值
    • PDIArray: 用于 +DI 值
    • NDIArray: 用于 -DI 值
double ADXArray[];
double PDIArray[];
double NDIArray[];
  • 使用 “ArraySetAsSeries” 函数为当前数据中的每个价格数组设置排列顺序:
ArraySetAsSeries(ADXArray,true);
ArraySetAsSeries(PDIArray,true);
ArraySetAsSeries(NDIArray,true);

  • 使用 “iADX” 函数识别 ADX 指标:
int ADXDef = iADX(_Symbol,_Period,14);
  • 使用 “CopyBuffer” 函数依据根据识别的 ADX 填充数据:
CopyBuffer(ADXDef,0,0,3,ADXArray);
CopyBuffer(ADXDef,1,0,3,PDIArray);
CopyBuffer(ADXDef,2,0,3,NDIArray);
  • 获取当前的数值,使用 “double” 类型为每个值创建变量后,我们将使用 “NormalizeDouble: 函数:
double ADXValue=NormalizeDouble(ADXArray[0],2);
double PDIValue=NormalizeDouble(PDIArray[0],2);
double NDIValue=NormalizeDouble(NDIArray[0],2);
  • 使用 “Comment” 函数在新的一行中显示每个值:
Comment("ADX Value is ", ADXValue,"\n""+DI Value is ", 
PDIValue,"\n""-DI Value is ", NDIValue);

以下是该智能交易系统的完整代码:

//+------------------------------------------------------------------+
//|                                  Simple ADX System - 3 lines.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
   //creating an array for prices
   double ADXArray[];
   double PDIArray[];
   double NDIArray[];
   
   //sort price array from current data
   ArraySetAsSeries(ADXArray,true);
   ArraySetAsSeries(PDIArray,true);
   ArraySetAsSeries(NDIArray,true);

   //identify ADX
   int ADXDef = iADX(_Symbol,_Period,14);
   
   
   //Filling data according to created ADX
   CopyBuffer(ADXDef,0,0,3,ADXArray);
   CopyBuffer(ADXDef,1,0,3,PDIArray);
   CopyBuffer(ADXDef,2,0,3,NDIArray);
   
   //Getting value of current data
   double ADXValue=NormalizeDouble(ADXArray[0],2);
   double PDIValue=NormalizeDouble(PDIArray[0],2);
   double NDIValue=NormalizeDouble(NDIArray[0],2);
   
   //Comment with ADX value
   Comment("ADX Value is ", ADXValue,"\n""+DI Value is ", 
   PDIValue,"\n""-DI Value is ", NDIValue);
  }
//+------------------------------------------------------------------+

程序编写完毕后,我们可以在导航器窗口中找到其文件:

 Nav 2

双击文件,或将其拖放到图表上之后,将出现以下窗口:

简单 ADX - 3 线窗口

在“允许算法交易”旁勾选,并按下“确定”按钮后,文件将被加载到图表上:

简单 ADX - 3 线加载

之后,根据智能交易系统的指示,数值将出现在图表上:

简单 ADX - 3 线

现在,我们将为上述策略(ADX 走势、上行趋势和下行趋势)创建交易系统。

  • 策略一: 简单 ADX 系统 - ADX 走势:

当前 ADX 值 > 前一个 ADX 值 = ADX 正在上升。

当前 ADX 值 < 前一个 ADX 值 = ADX 正在下降。

以下是编写程序或智能交易系统的代码:

  • 为 ADX 值(当前、前值)创建价格数组:
    • ADXArray0: 用于当前 ADX 值。
    • ADXArray1: 用于前一个 ADX 值。
double ADXArray0[];
double ADXArray1[];

  • 价格数组排列顺序从当前数据开始:
ArraySetAsSeries(ADXArray0,true);
ArraySetAsSeries(ADXArray1,true);

  • 识别 ADX:
int ADXDef = iADX(_Symbol,_Period,14);
  • 依据 ADX 填充数据:
CopyBuffer(ADXDef,0,0,3,ADXArray0);
CopyBuffer(ADXDef,0,0,2,ADXArray1);
  • 创建变量后获取其值:
double ADXValue=NormalizeDouble(ADXArray0[0],2);
double ADXValuelast=NormalizeDouble(ADXArray1[1],2);
  • 根据 ADX 值设置 ADX 走势的条件:
if (ADXValue>ADXValuelast)
      {
       Comment("ADX is rising","\n""ADX Value is ", ADXValue,"\n""ADX Value last is ", 
   ADXValuelast);
      }
   
if (ADXValue<ADXValuelast)
     {
      Comment("ADX is falling","\n""ADX Value is ", ADXValue,"\n""ADX Value last is ", 
   ADXValuelast);
      }

以下是依据此策略创建的智能交易系统的完整代码:

//+------------------------------------------------------------------+
//|                             Simple ADX System - ADX Movement.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
   //creating an array for prices
   double ADXArray0[];
   double ADXArray1[];

   //sort price array from current data
   ArraySetAsSeries(ADXArray0,true);
   ArraySetAsSeries(ADXArray1,true);
      
   //identify ADX
   int ADXDef = iADX(_Symbol,_Period,14);
   
   //Filling data according to created ADX
   CopyBuffer(ADXDef,0,0,3,ADXArray0);
   CopyBuffer(ADXDef,0,0,2,ADXArray1);
   
   //Getting value of current data
   double ADXValue=NormalizeDouble(ADXArray0[0],2);
   double ADXValuelast=NormalizeDouble(ADXArray1[1],2);
   
   //ADX movement signal
   if (ADXValue>ADXValuelast)
      {
         Comment("ADX is rising","\n""ADX Value is ", ADXValue,"\n""ADX Value last is ", 
   ADXValuelast);
      }
   
   if (ADXValue<ADXValuelast)
     {
         Comment("ADX is falling","\n""ADX Value is ", ADXValue,"\n""ADX Value last is ", 
   ADXValuelast);
      }
  }
//+------------------------------------------------------------------+

创建该智能交易系统后,我们可以在导航器窗口中找到它:

Nav - adx3

双击或将其拖放到图表上之后,将出现以下窗口:

ADX 走势窗口 

在“允许算法交易”旁勾选,并按下“确定”按钮后,EA 将被加载到图表上:

ADX 走势加载

之后,它可以根据其条件执行,以下是测试结果的示例:

  • 当 ADX 上升时,我们可以看到智能交易系统在注释里显示数值,如下图所示:

ADX 走势 - 上升 


  • 当 ADX 下降时,我们可以看到智能交易系统在注释里显示数值,如下图所示:

ADX movement2.png

  • 策略二: 简单 ADX 系统 - 上行趋势:

ADX 值 > 25 且当前 ADX 值 > 前一个 ADX 值 --> 当 +DI 值 > -DI 值 = 做多

以下是如何创建智能交易系统来执行此策略:

  • 创建变量 "signal" 并赋值为空,因为会在之后再计算其值,我们将使用 “string” 类型:
string signal="";
  • 为当前 ADX 值、前一 ADX 值、+DI 值和 -DI 值创建数组:
    • ADXArray0: 用于当前 ADX 值
    • ADXArray1: 用于前一 ADX 值
    • PDIArray: 用于 +DI 值
    • NDIArray: 用于 -DI 值 
double ADXArray0[];
double ADXArray1[];
double PDIArray[];
double NDIArray[];
  • 价格数组排列顺序从当前数据开始:
ArraySetAsSeries(ADXArray0,true);
ArraySetAsSeries(ADXArray1,true);
ArraySetAsSeries(PDIArray,true);
ArraySetAsSeries(NDIArray,true);
  • 识别 ADX 指标:
int ADXDef = iADX(_Symbol,_Period,14);
  • 依据所创建的 ADX 填充数据:
CopyBuffer(ADXDef,0,0,3,ADXArray0);
CopyBuffer(ADXDef,0,0,2,ADXArray1);
CopyBuffer(ADXDef,1,0,3,PDIArray);
CopyBuffer(ADXDef,2,0,3,NDIArray);
  • 获取当前数据值:
double ADXValue=NormalizeDouble(ADXArray0[0],2);
double ADXValueLast=NormalizeDouble(ADXArray1[1],2);
double PDIValue=NormalizeDouble(PDIArray[0],2);
double NDIValue=NormalizeDouble(NDIArray[0],2);
  • 设置上升趋势策略的条件:
if (ADXValue>25&&ADXValue>ADXValueLast)
   if(PDIValue>NDIValue)
   {
    signal = "BUY";
   }
  • 注释里显示做多信号和数值,每个都在一行中:
Comment("Simple ADX System - Signal is ",signal,"\n""ADX Value is ", ADXValue,
"\n""ADX Value Last is ", ADXValueLast, "\n""+DI Value is ", PDIValue,
"\n""-DI Value is ", NDIValue);

以下是依据此策略创建的智能交易系统的完整代码:

//+------------------------------------------------------------------+
//|                     Simple ADX System - Uptrend - Buy Signal.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+

void OnTick()
  {
  
   // creating a variable for signal
   string signal="";
   
   //creating an array for prices
   double ADXArray0[];
   double ADXArray1[];
   double PDIArray[];
   double NDIArray[];
   
   //identify ADX, positive DI, negative DI
   int ADXDef = iADX(_Symbol,_Period,14);
   
   
   //sort price array from current data
   ArraySetAsSeries(ADXArray0,true);
   ArraySetAsSeries(ADXArray1,true);
   ArraySetAsSeries(PDIArray,true);
   ArraySetAsSeries(NDIArray,true);
   
   //Filling data according to created ADX
   CopyBuffer(ADXDef,0,0,3,ADXArray0);
   CopyBuffer(ADXDef,0,0,2,ADXArray1);
   CopyBuffer(ADXDef,1,0,3,PDIArray);
   CopyBuffer(ADXDef,2,0,3,NDIArray);
   
   //Getting value of current data
   double ADXValue=NormalizeDouble(ADXArray0[0],2);
   double ADXValueLast=NormalizeDouble(ADXArray1[1],2);
   double PDIValue=NormalizeDouble(PDIArray[0],2);
   double NDIValue=NormalizeDouble(NDIArray[0],2);
   
   //Comment with Buy signal according to Buy Strategy
    if (ADXValue>25&&ADXValue>ADXValueLast)
      if(PDIValue>NDIValue)
      {
         signal = "BUY";
      }
      
   Comment("Simple ADX System - Signal is ",signal,"\n""ADX Value is ", ADXValue,
   "\n""ADX Value Last is ", ADXValueLast, "\n""+DI Value is ", PDIValue,
   "\n""-DI Value is ", NDIValue);
  }
//+------------------------------------------------------------------+

之后,我们可以在导航器窗口中找到该智能交易系统:

Nav - ADX4

双击或将其拖放到图表上之后,将出现以下窗口:

ADX - 上升窗口

在“允许算法交易”旁勾选,并按下“确定”按钮后,EA 将被加载到图表上:

ADX - 上升加载

之后,我们可以找到根据策略出现的信号:

  • 做多信号。
  • 当前 ADX 值出现在一行。
  • 前一个 ADX 值出现在新的一行。
  • +DI 值出现在新的一行。
  • -DI 值出现在新的一行。
下图是该策略或智能交易系统测试结果的示例:


ADX - 做多信号

  • 策略三: 简单 ADX 系统 - 下行趋势:

ADX 值 > 25 且当前 ADX 值 > 前一个 ADX 值 --> 当 +DI 值 < -DI 值 = 做空

以下是如何创建执行此策略的智能交易系统:

//+------------------------------------------------------------------+
//|                Simple ADX System - Downtrend - Sell Strategy.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
  
   // creating a variable for signal
   string signal="";
   
   //creating an array for prices
   double ADXArray0[];
   double ADXArray1[];
   double PDIArray[];
   double NDIArray[];
   
   //identify ADX, positive DI, negative DI
   int ADXDef = iADX(_Symbol,_Period,14);
   
   
   //sort price array from current data
   ArraySetAsSeries(ADXArray0,true);
   ArraySetAsSeries(ADXArray1,true);
   ArraySetAsSeries(PDIArray,true);
   ArraySetAsSeries(NDIArray,true);
   
   //Filling data according to created ADX
   CopyBuffer(ADXDef,0,0,3,ADXArray0);
   CopyBuffer(ADXDef,0,0,2,ADXArray1);
   CopyBuffer(ADXDef,1,0,3,PDIArray);
   CopyBuffer(ADXDef,2,0,3,NDIArray);
   
   //Getting value of current data
   double ADXValue=NormalizeDouble(ADXArray0[0],2);
   double ADXValueLast=NormalizeDouble(ADXArray1[1],2);
   double PDIValue=NormalizeDouble(PDIArray[0],2);
   double NDIValue=NormalizeDouble(NDIArray[0],2);
   
   //Comment with Buy signal according to Buy Strategy
    if (ADXValue>25&&ADXValue>ADXValueLast)
      if(PDIValue<NDIValue)
      {
         signal = "SELL";
      }
      
   Comment("Simple ADX System - Signal is ",signal,"\n""ADX Value is ", ADXValue,
   "\n""ADX Value Last is ", ADXValueLast, "\n""+DI Value is ", PDIValue,
   "\n""-DI Value is ", NDIValue);
  }
//+------------------------------------------------------------------+

它们与上升趋势策略的步骤相同,但有区别如下:

  • 下行策略的条件:
    if (ADXValue>25&&ADXValue>ADXValueLast)
      if(PDIValue<NDIValue)
      {
         signal = "SELL";
      }
  • 依据信号显示注释:
   Comment("Simple ADX System - Signal is ",signal,"\n""ADX Value is ", ADXValue,
   "\n""ADX Value Last is ", ADXValueLast, "\n""+DI Value is ", PDIValue,
   "\n""-DI Value is ", NDIValue);

此策略的代码编写完成后,我们可以在导航器窗口中找到该智能交易系统的文件:

Nav - ADX 5

双击或将其拖放到图表上之后,将出现以下窗口:

ADX - 下行趋势窗口 

在“允许算法交易”旁勾选,并按下“确定”按钮后,EA 将被加载到图表上:

ADX - 下行趋势加载

然后,我们可以找到依据下行趋势策略出现的信号:

  • 做空信号。
  • 当前 ADX 值出现在一行。
  • 前一个 ADX 值出现在新的一行。
  • +DI 值出现在新的一行。
  • -DI 值出现在新的一行。

下图是根据该测试策略生成的信号示例:

ADX - 做空信号

结束语

现在和以后,凡提到本文的主题,料想您已详尽了解了一个流行且有用的指标,即 ADX 指标,以及如何运用它设计交易系统,因为我们已知道什么是 ADX,它测量什么,以及我们如何手工计算它。 我们还知道了基于 ADX 指标的简单策略,上升趋势和下降趋势期间,然后我们设计了针对这些策略的蓝图,来帮助我们逐步设计交易系统,如此即可令我们了解需要通知程序做什么。 我们还知道了如何设计一个基于这些 ADX 策略的自动操作交易系统,我们知道如何使用 MQL5(MetaQuotes 语言)编写这些交易策略的代码。

有许多策略可以运用 ADX 指标,从简单到复杂的交易,但在此我们只选取了一些简单的策略来学习指标的基本概念,本文主要目标是基于技术方法学习交易策略,并通过 MQL5 为其设计一个可用于 MetaTrader 5 平台的交易系统。

我还需要在这里提到的是,我们有很多有用的工具和策略可在我们的交易里加以运用。 这些工具可以单独使用,也可以组合各种有效工具来获得更好的结果,这是技术分析最有用的特征之一,因为它有许多基于不同概念的工具,它们可以强化我们的交易决策,而这必将令我们从交易中获得更好的结果。 我建议阅读我之前的文章,了解一些可用于简单策略的其它流行指标,以及如何基于这些策略通过 MQL5 设计一个简单的交易系统,供 MetaTrader 5 使用。 那么,我们的任务是学习这些概念和工具,看看哪些适合我们的交易风格和计划,因为您可以找到许多可能对某人有用,但对其他人无效的策略,每个人都必须有一个基于其交易策略的交易计划,我们理应知道,在使用每个新策略或工具之前,都要通过测试,并确认它们是否可用、以及是否有利可图,如此才可用于真实账户。

由于许多原因,程序化在这个阶段非常有用,它帮助我们轻松、顺利、准确地完成这项工作。 一旦我们找到了一个可盈利的策略,我们也可以为它设计一个交易系统,令计算机根据程序设定的条件自动为我们工作。 这将令我们避免在交易过程中产生有害情绪,因此,程序化有助于我们遵守纪律,这是交易成功的最重要关键之一。 因此,学习编程和 MQL5 很有益处,因为它们可以帮助实现这些目标。

我希望您能从本文发现对您的交易有用的内容,它令您产生了新的思路,并让您深入了解了文章的主题或任何相关主题,以帮助您提高交易结果,不断获得更好的结果,因为这是我们交易的主要目标,是获得良好的结果和实现利润的一致性,我希望这篇文章能为实现这一宝贵目标有所贡献和帮助。 


本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/10715

从头开始开发智能交易系统(第 13 部分):时序与交易(II) 从头开始开发智能交易系统(第 13 部分):时序与交易(II)
今天,我们将针对市场分析构建《时序与交易》系统的第二部分。 在前一篇文章《时序与交易(I)》当中,我们讨论了一种替代的图表组织系统,该系统能够针对市场上执行的成交进行最快速的解释。
学习如何基于 Stochastic 设计交易系统 学习如何基于 Stochastic 设计交易系统
在本文中,我们继续我们的研究系列 — 这次,我们将学习如何基于最流行的技术指标之一 Stochastic 振荡器指标设计交易系统。
从头开始开发智能交易系统(第 14 部分):添加价格成交量(II) 从头开始开发智能交易系统(第 14 部分):添加价格成交量(II)
今天,我们要将更多资源加入 EA。 这篇有趣的文章可以提供一些展示信息的新思路和方法。 与此同时,它能帮助修复项目中的小缺陷。
数据科学与机器学习(第 02 部分):逻辑回归 数据科学与机器学习(第 02 部分):逻辑回归
数据分类对于算法交易者和程序员来说是至关重要的。 在本文中,我们将重点关注一种分类逻辑算法,它有帮于我们识别“确定或否定”、“上行或下行”、“做多或做空”。