
学习如何基于 DeMarker 设计交易系统
概述
这篇是我们系列的新文章,关于学习如何根据最流行的技术指标设计交易系统。 我们将详细学习一种新的技术工具或指标,可以在交易中为我们提供便益。 该指标是 DeMarker 指标,我们将全方位涵盖以下主题:
我们将利用 MetaTrader 5 交易终端,及在终端中内置的 MQL5 来编写交易系统代码,并对其进行测试。 如果您不知道如何下载和使用 MetaTrader 5,您可以阅读上一篇文章中的在 MetaEditor 中编写 MQL5 代码主题来学习更多信息。
如果您想发展自己的交易和编程技能,并获取最大收益,我建议您自行应用自本文中所学,因为实践是任何学习步骤中非常重要的因素。 我想提醒并确认上述策略的主要目标是学习指标背后的主要概念。 因此,主要目标只是教学,您在真实账户中运用任何策略之前,必须对其进行测试,从而确保它能盈利,或适合您的交易。
免责声明:所有信息“按原样”提供仅用于教学目的,并非出于交易目的或建议。 这些信息不能保证任何结果。 如果您选择在您的任何交易账户上使用这些材料,您将自行承担风险,您是唯一的责任人。
DeMarker 定义
如果我们打算更详尽地辨别和学习 DeMarker 指标,我们需要学习它是什么、它测量什么、我们如何计算它、以及如何按我们的偏好读取它。 DeMarker 指标是一种振荡器技术工具,它是由技术分析师 Thomas DeMark 创造的。 这很明显,该指标的名称来源于其创建者,据知也称为 “DeM” 指标。 该技术指标衡量金融产品的需求,并取当前最高和最低价格与前期的价格进行比较,来评估行情的趋势方向。
若要手工计算此指标,我们可以按以下步骤来完成:
DMark (i) = SMA (DeMax, N) / (SMA (DeMax, N) + SMA (DeMin, N))
其中:
- DMark (i) = 当期 DeMark 值。
- SMA = 简单均线
- DeMax = DeMark 最大值
- N = 所用周期
- DeMin = DeMark 最小值
DeMax 可计算如下:
DeMax (i) = HIGH (i) - HIGH (i - 1)
否额:
DeMax (i) = 0
DeMin 可计算如下:
DeMin (i) = LOW (i - 1) - LOW (i)
否额:
DeMin (i) = 0
计算指标后,我们可以看出它产生一条介于 0 到 1 之间的振荡线,来衡量我们所提金融产品的需求。 现如今,我们不需要手工计算它,因为它内置于 MetaTrader 5 交易平台当中,我们要做的只是从可用指标中选择它,并将其插入图表,然后读取它。
此为我们如何在 MetaTrader 5 中插入 DeMarker 技术指标:
打开 MetaTrader 5 交易终端时,我们点击插入 --> 指标 --> 振荡器 --> DeMarker
之后,我们将看到该指标的参数窗口,如下所示:
1 - 确定周期。
2 - 设置指标线的颜色。
3 - 设置指标线的样式。
4 - 设置指标线的宽度。
前面的参数设置完毕,并按“确定”后,我们将看到指标插入到图表中,与如下相同:
正如我们在上一张图表的下半部分所见,我们已加载了指标,且我们有一条介于 0 和 1 之间的振荡器线。 我们可判定上述区域中指标线的位置,读取该指标。 如果指标逼近 0.70,则意味着我们处于超买状况;但如果指标逼近 0.30,则意味着我们处于超卖状况。
DeMarker 策略
现在, 我们需要学习如何根据其背后的主要概念运用 DeMarker 指标。 因此,我们将借助三种简单策略来学习如何运用它。
基于此策略,我们要观察 DeMarker 值,和指标的最后 5 周期平均值,来判定 DeMarker 信号的强弱。 如果 DeMarker 指标的当期值大于 DeMarker 的最后 5 个周期,这是一个强信号。 在另一种情况下,如果指标的当期值低于 DeMarker 的最后 5 个周期,这是一个疲软信号。
简而言之,
DeMarker 值 >= DeMarker 5-周期均值 --> DeMarker 强劲
DeMarker 值 <= DeMarker 5-周期均值 --> DeMarker 疲软
基于此策略,我们要求在指标到达超买和超卖区域时获取信号。 如果当期 DeMarker 值大于或等于 0.70 水平,这是接近超买区域的信号。 如果当期 DeMarker 值低于或等于 0.30 水平,这是接近超卖区域的信号。
简而言之,
DeMarker 值 >= 0.70 --> 超买
DeMarker 值 <= 0.30 --> 超卖
基于此策略,我们需要获得看涨或看跌背离的信号,从而得到改变当前走势概率的见解。 我们需要通过观察当前高点、前高点、当前 DeMarker、和前 DeMarker 这四个数值来获取这些信号。 值得一提的是,这是一种简单的背离情况,但最有效的情况是比较和观察价格与指标的高点和低点。 在这种简单情形下,我们要求得到一个看跌背离信号,如果当期高点大于前期高点,同时当期 DeMarker 值低于前期。 在另一种情况下,如果当期低点低于前期低点,同时当期 DeMarker 值大于前期,则这是看涨背离信号。
简而言之,
当期高点 > 前期高点,且当期 DeMarker < 前期 --> 看跌背离
当期低点 < 前期低点,且当期 DeMarker > 前期 --> 看涨背离。
DeMarker 策略蓝图
学习如何在简单策略里运用 DeMarker 指标之后。 在本主题中,我们将为每个策略创建一个简单的蓝图,来帮助我们顺利地为其创建交易系统。
根据此策略,我们需要创建一个交易系统,该系统可创建或定义两个数值,然后自动检查它们。 这些值是当期 DeMarker 值和最后五个 DeMarker 平均值。 如果当期值大于平均值,我们要求交易系统返回以下值作为图表上的注释:
- DeMarker 强劲
- 当期 DeMarker 值
- 5 -周期 DeMarker 均值
在另一种场景下,如果当期值低于平均值,我们需要交易系统根据此条件返回以下值:
- DeMarker 疲软
- 当期 DeMarker 值
- 5 -周期 DeMarker 均值
根据此策略,我们需要创建一个可根据特定条件生成信号的交易系统。 我们要求交易系统连续检查三个值,即当期 DeMarker 值、指标上的 0.70 水平、和指标上的 0.30 水平。 如果当期 DeMarker 值大于或等于 0.70 水平,我们要求交易系统返回以下值作为图表上的注释:
- 超买
- DeMarker 值
在另一种场景下,如果当期 DeMarker 值低于或等于 0.30 水平,我们要求交易系统在图表上返回以下值:
- 超卖
- DeMarker 值

根据此策略,我们需要创建一个交易系统,可连续检查四个值来生成看涨或看跌背离信号。 如果当期高点大于前期高点,同时当期 DeMarker 值低于前期 DeMarker 值,我们要求交易系统返回以下值作为图表上的注释:
- 看跌背离
- 当期高点值
- 前期高点值
- 当期 DeMarker 值
- 前期 DeMarker 值
在另一种场景下,如果当期低点同时低于前期低点,且当期 DeMarker 值大于前期 DeMarker 值,我们要求系统在图表上返回以下值:
- 看涨背离
- 当期高点值
- 前期高点值
- 当期 DeMarker 值
- 前期 DeMarker 值
DeMarker 交易系统
在这一部分中,我们将为每个提到的策略创建一个交易系统,并在 MetaTrader 5 中执行,从而生成自动化信号。 首先,我们创建一个简单的交易系统,用作所有上述策略的基础。 该系统将取 DeMarker 指标的当期值生成图表上的注释,下面讲解以下代码行如何创建此系统:
步骤一:
创建 “double” 数据类型的 deMarkerArray 数组,其可返回分数。
double deMarkerArray[];
步骤二:
调用 “ArraySetAsSeries” 函数为 deMarkerArray 设置排序 AS_SERIES 标志,该数组返回一个 true 或 false 的布尔值。
ArraySetAsSeries(deMarkerArray,true);
步骤三:
调用 “iDeMarker” 函数返回定义的 DeMarker 指标句柄。 其参数为:
- symbol: 确定交易品种,我们将采用(_Symbol)应用当前品种。
- period: 确定周期或时间帧,我们将采用(_period)应用当前时间帧。
- ma_period: 确定均化周期,我们将采用(14)。
int deMarkerDef = iDeMarker(_Symbol,_Period,14);
步骤四:
调用 “CopyBuffer” 函数从 DeMarker 指标的缓冲区获取数据。 其参数为:
- indicator_handle: 我们将采用(deMarkerDef)里定义的指标句柄。
- buffer_num: 确定指标缓冲区编号,我们将采用(0)。
- start_pos: 确定起始位置,我们将采用(0)。
- count: 确定要复制的数量,我们将采用(3)。
- buffer[]: 确定要复制的目标数组,我们将采用(deMarekerArray)。
CopyBuffer(deMarkerDef,0,0,3,deMarkerArray);
步骤五:
调用 “NormalizeDouble” 函数定义当前 deMarker 值,并返回双精度类型的值。 其参数为:
- value: 确定需规范化的数字。
- digits: 确定小数点后的位数。
double deMarkerVal = NormalizeDouble(deMarkerArray[0],6);
步骤六:
调用 “Comment” 函数返回当前 DeMarker 指标的值作为图表上的注释。
Comment("DeMarker Value is ",deMarkerVal);
如果您欲求此交易系统的完整代码,您可以看到它与以下内容相同。
//+------------------------------------------------------------------+ //| Simple DeMarker 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() void OnTick() { double deMarkerArray[]; ArraySetAsSeries(deMarkerArray,true); int deMarkerDef = iDeMarker(_Symbol,_Period,14); CopyBuffer(deMarkerDef,0,0,3,deMarkerArray); double deMarkerVal = NormalizeDouble(deMarkerArray[0],6); Comment("DeMarker Value is ",deMarkerVal); } //+------------------------------------------------------------------+
这段代码编译完毕后,我们会在导航器中找到与以下内容相同的智能系统:
将智能系统拖放到图表上,我们会发现与以下内容相同的窗口:
按下“确定”后,我们会发现智能系统附加到图表上,如下所示:
正如我们在右上角的图表上所见,简单 DeMarker 系统加载到图表上,我们现在已准备好根据此策略获得所需的信号。 前面的步骤与编译之前策略的所有代码相同,在 MetaTrader 5 中执行它们的步骤亦相同。
以下是根据这个简单交易系统进行测试生成的信号:
正如我们在左上角的图表上所见,我们可以看到 DeMarker 指标的当期值。
以下是基于此策略所创建交易系统的完整代码。
//+------------------------------------------------------------------+ //| DeMarker Strength.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() { double deMarkerArray[]; ArraySetAsSeries(deMarkerArray,true); int deMarkerDef = iDeMarker(_Symbol,_Period,14); CopyBuffer(deMarkerDef,0,0,6,deMarkerArray); double deMarkerVal = NormalizeDouble(deMarkerArray[0],4); double deMarkerVal1 = NormalizeDouble(deMarkerArray[1],4); double deMarkerVal2 = NormalizeDouble(deMarkerArray[2],4); double deMarkerVal3 = NormalizeDouble(deMarkerArray[3],4); double deMarkerVal4 = NormalizeDouble(deMarkerArray[4],4); double deMarkerVal5 = NormalizeDouble(deMarkerArray[5],4); double deMarkerAvgVal = (deMarkerVal1+deMarkerVal2+deMarkerVal3+deMarkerVal4+deMarkerVal5)/5; if(deMarkerVal>deMarkerAvgVal) { Comment("DeMarker is strong","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); } if(deMarkerVal<deMarkerAvgVal) { Comment("DeMarker is weak","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); } } //+------------------------------------------------------------------+
此代码中的区别:
调用 “NormalizeDouble” 函数定义当期 deMarker 值之后,再调用同一函数定义最后五个 deMarker 值。
double deMarkerVal = NormalizeDouble(deMarkerArray[0],4); double deMarkerVal1 = NormalizeDouble(deMarkerArray[1],4); double deMarkerVal2 = NormalizeDouble(deMarkerArray[2],4); double deMarkerVal3 = NormalizeDouble(deMarkerArray[3],4); double deMarkerVal4 = NormalizeDouble(deMarkerArray[4],4); double deMarkerVal5 = NormalizeDouble(deMarkerArray[5],4);
创建 “double” 数据类型的 deMarkerAvgVal 变量,基于最后五个 deMarker 值的合计,再除以 5,计算出均值 deMarkerAvgVal。
double deMarkerAvgVal = (deMarkerVal1+deMarkerVal2+deMarkerVal3+deMarkerVal4+deMarkerVal5)/5;
设置策略的条件
依据 deMarkerAvg 值比较当期 deMarker。 在 deMarker 为强信号的情况下,我们需看到当期 deMarker 值大于 deMarkerAvg 值。 我们将使用 “If” 函数及其语法:
if(表达式) --> 操作符
在强劲情况下,若 deMarkerVal 大于语法表达式的 deMarkerAvgVal 时,我们要求交易系统返回一个强信号作为作为图表上的注释。
if(deMarkerVal>deMarkerAvgVal) { Comment("DeMarker is strong","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); }
如果 deMarker 疲软,我们需看到当期 deMarker 值低于表达式的 deMarker Avg 值,然后在图表上返回注释,其中包含疲软和其它值,每个值都在单独的行中。
if(deMarkerVal<deMarkerAvgVal) { Comment("DeMarker is weak","\n", "Current DeMarker Value is ",deMarkerVal,"\n", "AVG DeMarker Value is ",deMarkerAvgVal); }
与我们之前学到的相同,编译此代码,并从导航器执行它之后,我们可以看到该策略的智能系统已加载,且与以下内容相同:
正如我们在右上角所见,我们已将此策略的智能系统加载到图表上,并已准备好从测试中获得与以下示例相同的信号。
强劲信号情况:
正如我们在左上角的图表上所见,该交易系统基于交易策略生成了一个信号,它与以下内容相同:
- DeMarker 强劲 --> 因为我们的 DeMarker 当期值高于 DeMarker 指标的最后五个平均值。
- 当期 DeMarker 值。
- DeMarker 平均值。
疲软信号情况:
正如我们在左上角的图表上所见,我们有一个与以下内容相同的信号:
- DeMarker 疲软 --> 因为我们的当期 DeMarker 值低于 DeMarker 指标的最后五个平均值。
- 当期 DeMarker 值。
- DeMarker 平均值。
以下是该策略的完整代码:
//+------------------------------------------------------------------+ //| Simple DeMarker 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() void OnTick() { double deMarkerArray[]; ArraySetAsSeries(deMarkerArray,true); int deMarkerDef = iDeMarker(_Symbol,_Period,14); CopyBuffer(deMarkerDef,0,0,3,deMarkerArray); double deMarkerVal = NormalizeDouble(deMarkerArray[0],6); if(deMarkerVal<=0.30) { Comment("Oversold","\n", "DeMarker Value is ",deMarkerVal); } if(deMarkerVal>=0.70) { Comment("Overbought","\n", "DeMarker Value is ",deMarkerVal); } if(deMarkerVal>0.30 && deMarkerVal<0.70) { Comment("DeMarker Value is ",deMarkerVal); } } //+------------------------------------------------------------------+
此代码中的区别:
此代码的条件。
在超卖信号的情况下,若当期值低于或等于 0.30 时,这是 “if” 函数中的表达式,它将是一个超卖信号,它也是在图表上的注释里出现的超卖操作符。
if(deMarkerVal<=0.30) { Comment("Oversold","\n", "DeMarker Value is ",deMarkerVal); }
在超买信号的情况下,若当期 deMarker 值大于或等于 0.70 时,就会存在这种情况。
if(deMarkerVal>=0.70) { Comment("Overbought","\n", "DeMarker Value is ",deMarkerVal); }
在没有信号或平衡(表达式)的情况下,若当前 deMarker 值介于 0.30 和 0.70 之间(操作符)时,将发出信号。
if(deMarkerVal>0.30 && deMarkerVal<0.70) { Comment("DeMarker Value is ",deMarkerVal); }
编译此智能系统代码,并执行后,我们会发现它已加载到图表上,如下所示:
现在,我们已准备好接收基于此策略的信号,以下是测试示例。
超买的情况:
正如我们在左上角的图表中所见,生成的信号与以下内容相同:
- 超买
- DeMarker 当期值
超卖的情况:
正如我们所见,生成的信号与以下内容相同:
- 超卖
- DeMarker 当期值
无信号或平衡情况:
正如我们所见,我们得到的是一个生成的 DeMarker 当期值信号。
以下是依据此策略创建的交易系统的完整代码。
//+------------------------------------------------------------------+ //| DeMarker Divergence.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() { double deMarkerArray[]; MqlRates pArray[]; ArraySetAsSeries(deMarkerArray,true); ArraySetAsSeries(pArray,true); int deMarkerDef = iDeMarker(_Symbol,_Period,14); int pData = CopyRates(_Symbol,_Period,0,14,pArray); CopyBuffer(deMarkerDef,0,0,14,deMarkerArray); double deMarkerVal = NormalizeDouble(deMarkerArray[0],4); double deMarkerPrevVal = NormalizeDouble(deMarkerArray[1],4); double currentHigh = NormalizeDouble(pArray[0].high,6); double currentLow = NormalizeDouble(pArray[0].low,6); double prevHigh = NormalizeDouble(pArray[1].high,6); double prevLow = NormalizeDouble(pArray[1].low,6); if(currentHigh>prevHigh && deMarkerVal<deMarkerPrevVal) { Comment("Bearish divergence","\n", "Current High is ",currentHigh,"\n", "Prev. High Value is ",prevHigh,"\n", "Current DeMarker Value is ",deMarkerVal,"\n", "Prev. DeMarker Value is ",deMarkerPrevVal); } if(currentLow<prevLow && deMarkerVal>deMarkerPrevVal) { Comment("Bullish divergence","\n", "Current Low is ",currentLow,"\n", "Prev. Low Value is ",prevLow,"\n", "Current DeMarker Value is ",deMarkerVal,"\n", "Prev. DeMarker Value is ",deMarkerPrevVal); } } //+------------------------------------------------------------------+
代码中的差异。
创建两个数组,一个是 "double"数据类型的 deMarkerArray,另一个是 “MqlRates” 数据结构 pArray(价格),存储价格、交易量、和点差等信息。
double deMarkerArray[]; MqlRates pArray[];
为这两个创建的数组设置 AS_SERIES 标志。
ArraySetAsSeries(deMarkerArray,true); ArraySetAsSeries(pArray,true);
定义 deMarketDef, pData
int deMarkerDef = iDeMarker(_Symbol,_Period,14); int pData = CopyRates(_Symbol,_Period,0,14,pArray);
填充 deMarkerArray
CopyBuffer(deMarkerDef,0,0,14,deMarkerArray);
定义 deMarkerVal, deMarkerPrevVal, current high, current low, prev. high, 和 prev. low
double deMarkerVal = NormalizeDouble(deMarkerArray[0],4); double deMarkerPrevVal = NormalizeDouble(deMarkerArray[1],4); double currentHigh = NormalizeDouble(pArray[0].high,6); double currentLow = NormalizeDouble(pArray[0].low,6); double prevHigh = NormalizeDouble(pArray[1].high,6); double prevLow = NormalizeDouble(pArray[1].low,6);
策略的条件。
看跌背离的情况:
if(currentHigh>prevHigh && deMarkerVal<deMarkerPrevVal) { Comment("Bearish divergence","\n", "Current High is ",currentHigh,"\n", "Prev. High Value is ",prevHigh,"\n", "Current DeMarker Value is ",deMarkerVal,"\n", "Prev. DeMarker Value is ",deMarkerPrevVal); }
在看跌背离的情况下:
if(currentLow<prevLow && deMarkerVal>deMarkerPrevVal) { Comment("Bullish divergence","\n", "Current Low is ",currentLow,"\n", "Prev. Low Value is ",prevLow,"\n", "Current DeMarker Value is ",deMarkerVal,"\n", "Prev. DeMarker Value is ",deMarkerPrevVal); }
编译完这段代码后,我们可以在导航器中找到它,并执行它。 然后我们会发现它已加载到图表上,如下所示:
正如我们在上一个图表的左上角所见,我们将智能系统加载到图表上,现在,我们可以根据此交易策略从该智能系统那里接收信号,如下所示。
在看跌背离的情况下:
正如我们在上一张图表的左上角所见,我们有以下生成的信号:
- 看涨背离
- 当期高点值
- 前期高点值
- 当期 DeMarker 值
- 前期 DeMarker 值
看跌背离的情况:
正如我们在上一张图表的左上角所见,我们有以下生成的信号:
- 看跌背离
- 当期高点值
- 前期高点值
- 当期 DeMarker 值
- 前期 DeMarker 值
结束语
根据您在本文中学到的内容,推测您已经详细辨别了这个 DeMarker 技术指标,因为我们学习了它是什么、它测量什么、我们如何计算它、以及如何基于其背后的主要概念在简单策略里读取和运用它。 这些简单的策略是:
- DeMarker 强度: 根据当前 DeMarker 的位置和指标值的最后 5 周期平均值接收强弱信号。
- DeMarker, 超买 - 超卖: 根据当期 DeMarker 值在其 0 到 1 范围内的位置,接收超买或超卖信号。
- DeMarker 背离: 根据当前DeMarker,前一个DeMarker,当前高点和先前高点的位置接收看涨或看跌背离的信号。
除此之外,我们还为提到的每个策略设计了一个分步蓝图,来帮助我们顺畅地为其创建交易系统。 然后,我们学习了最有趣的主题,因为我们根据我们在上述策略蓝图中设计的内容创建了一个交易系统,能自动接收 MetaTrader 5 的信号。
我要再次确认,在运用任何策略之前,您必须对其进行测试,确保其适合您的交易,因为没有任何东西能适合所有人。 我希望您能发现这篇文章对自己有用,并获得有关文章主题,或任何相关主题的新见解,如果您想阅读更多类似的文章,您可以参阅我之前在本系列中为初学者撰写的文章,了解最技术指标,以及我们如何基于它们创建简单的交易系统。
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/11394



