English Русский Español Deutsch 日本語 Português
preview
基于改进的十字星(Doji)烛条形态识别指标的交易策略

基于改进的十字星(Doji)烛条形态识别指标的交易策略

MetaTrader 5测试者 | 12 九月 2023, 13:27
757 0
ds2
ds2

概述

文章“依据十字星(Doji)示例的描述识别改进的烛条形态”讨论了元柱线的概念。 简而言之,元柱线是将若干根连续柱线的按照条件组合成一根大型柱线。 这类似于更高时间帧的柱线,但又不完全是,因为元柱线的大小不是固定的(它在给定范围内“浮动”),并且柱线的开始和结束时间并未与特定时刻绑定。 因此,元柱线的使用允许交易者检更频繁地测烛条的各种形态,并进行分析。

在上一篇文章中,我讲述了在元柱线上创建十字星烛条指标,并演示了它的工作原理。

现在我们将尝试利用该指标创建交易策略。 理论上,由于元柱线允许我们更频繁地检测烛条形态,因此该策略能够比传统柱线达成更多成交。 这是赚取更多利润的绝佳机会。


交易策略概念:蜡烛够用吗?

我们将利用来自上述文章中的元柱线获取十字星指标。 不幸的是,不可能简单地根据该指标的读数开立和了结交易。 原因既不在于指标,也非归因元柱线。 十字星烛条形态通常并非设计用作独立交易信号。

因为它是一个潜在的趋势逆转信号。 这意味着在十字星蜡烛出现之前应该有相应方向的趋势。 如果没有趋势,那么基于十字星蜡烛进行交易就没有意义了。


将趋势和元柱线结合在一起

解决这项任务并不像乍一看那么困难。 事实上,它恰恰很容易。 十字星烛条是一根元柱线,但趋势不一定出现在元柱线上,它也可以建立在常规柱线上。 对于烛条,柱线内最大和最小价格偏差的比率很重要,并且(正如我们在上一篇文章中发现的)它们在很大程度上取决于元柱线的宽度(即其中包含的普通柱线的数量),及其时间偏移。 然而,趋势线没有显示出任何极端比率,它只是穿过一组柱线中的平均价格值。 为了计算平均值,将柱线组按部分划分大小并不是特别重要。

一般来说,我们将在常规柱线上建立趋势。

我们唯一需要知道的是趋势的结束时间,即指标检测到的十字星蜡烛已经开始的柱线数量,因为该蜡烛的宽度可以在很宽的范围内变化(在指标设置中指定)。 构成烛台元柱线的柱线不应被视为趋势的一部分。 十字星烛条是它的潜在转折点,这意味着它不再是旧趋势,但也不是新趋势。 或者它既是旧趋势又是新趋势,这取决于您如何看待它。 一般来说,它也可以被认为是一段横盘,因为它的收盘价接近开盘价。

因此,我们不会将含有十字星烛条的元柱线包含在构建趋势的柱线组中,从而避免统计趋势特征时造成误差。

在计算趋势时,找出十字星蜡烛何时开始的最简单方式是在绘制该蜡烛的同一指标中计算趋势。 换言之,我们将修改上一篇文章中的指标,令其包含一个过滤器,仅显示之前有相应趋势的十字星蜡烛。 此外,拥有此类设置的指标变得更适合交易:可以利用其信号执行交易,而无需任何额外的分析。

目前,该指标的输入其名称均以 “Candle_” 开头。 这些是各种蜡烛参数。 现在我们需要向指标代码添加各种趋势输入。 至少,应该有以下两个参数。

  • 最小趋势宽度(柱线数量):
input int     Trend_WidthMin        = 10;
  • 最大趋势宽度(柱线数量):
input int     Trend_WidthMax        = 50;     

当检测到十字星蜡烛时,指标将分析其前面的一组柱线,其数量为这两个参数指定的范围。 它还将评估柱线是否有对应的趋势。

稍后将提及要设置的其它趋势输入。 与此同时,我们关注一个微小,但技术上很重要的细微差别。

由于现在指标需要分析大量以前的柱线,才能在图表上绘制信号(因为建立烛条的元柱线宽度也已扩展到趋势的宽度),我们需要在指标代码中进行小的修正。 OnInit 函数中有一行,用于计算价格历史开始时应该跳过多少根柱线。 换言之,指标无法在这些柱线上计算和绘制(由于历史数据不足):

SkipBars = Candle_WidthMax; 
现在这句代码应该如下所示:
SkipBars = Candle_WidthMax + Trend_WidthMax;

计算相应趋势的方法

我们可以利用各种算法检测趋势。 其中一些很容易,有些则很复杂。 对于十字星蜡烛的运用,我认为不仅要检测趋势,还要为其定义一些特征,这一点很重要。 我们在图表上展示这一点:

十字星蜡烛之前的趋势示例

上图显示了两个趋势示例。 在左边,我们看到一根十字星蜡烛,其高度与之前趋势中的价格走势相当,甚至略高于。 可以假设,这根十字星蜡烛内部确实发生了一些重大事件,导致对立力量的严重冲突。 其中一股力量以前所未有的力量推动价格上涨(在整个趋势发展期间),但另一股力量不允许价格保持在顶部,并将价格打回到蜡烛开盘的初始水平。 换言之,在这根蜡烛上,我们可以看出一股可以抵抗趋势增长的力量发挥作用的时刻。 因此,我们可以假设趋势已经耗尽,并准备扭转。

在右边,我们看到与趋势内部发生的走势相比,十字星蜡烛的高度并不特别。 这意味着在这根烛台内逆转价格的力量几乎不足以扭转整个趋势。 在这样的十字星蜡烛上进行交易可能要冒一种不合理的风险。 我们的交易策略有机会以某种方式区分这两种情况那就好了。

这可以通过使用线性回归方法判定趋势来完成。 在这种情况下,我们不仅会检测趋势,还会定义穿过趋势通道中间的直线方程:

y = A + B * x

方程组成:

x — 图表沿水平轴的点坐标(在我们的例子中,这些是柱线编号)。

y — 沿垂直(价格)轴的坐标。 这些是由这个线性回归方程计算出的坐标,以便在价格图表上为每根柱线建立一个点,并通过这些点画一条直线。 这样就是一条趋势线。

B — 表征趋势线斜率的比率。 这个比率越高,趋势就越陡峭和强劲。 如果比率为正,则趋势线将从左到右增加,这对应于上升趋势。 负比率值对应于下降趋势。

A 只是将趋势线定位在所需图表高度的辅助系数。 它在交易层面没有任何意义。

计算线性回归的算法是众所周知的。 它是数理统计设备基础的一部分,除交易外还用于许多应用领域。 作为算法操作的结果,计算上述系数 A 和 B。

在指标代码中,它简约地看起来像这样(完整的指标代码附在文后)。 在循环内,累加所衡量趋势中包含的所有柱线的各种中间总和:

      double BarPrice = (open[CurBar] + close[CurBar] + high[CurBar] + low[CurBar])/4;
        
      X = TrendBarNum;
      Y = BarPrice;
      N = TrendBarNum;
      S1 += X;
      S2 += Y;
      S3 += X * Y;
      S4 += X * X;

当收集趋势柱线的所有总和时,将显示回归方程的比率:

         B = (N * S3 - S1 * S2) / (N * S4 - S1 * S1);
         A = (S2 - B * S1) / N;

当我们计算线性回归方程时,通过分析比率 B,我们可以找出这组柱线中是否存在趋势,以及它是否与蜡烛的方向一致:

         if ((CandleDir < 0)&&(B < 0)) continue;
         if ((CandleDir > 0)&&(B > 0)) continue;

评估趋势是否足够强劲,即倾斜的陡峭程度也是有用的。 趋势斜率太小可能只是噪声,一个横盘误差。 此外,微小的价格走势产生的收益太少,无法偿付交易费用。 因此,我们在指标代码中添加一个参数,用于设置最小允许的趋势斜率。 它以每分钟点数为单位:

input double  Trend_PowerMin        = 0.01;

在代码中,该参数被转换为与回归方程中的比率 B 相同的单位,并取它们进行比较:

         if (MathAbs(B) < (Trend_PowerMin*_Point*PeriodSeconds()/60)) continue;

现在,我们继续讨论我们利用线性回归来判定趋势的最重要事情。

由于回归线穿过趋势通道的中心,我们现在可以计算该通道本身的宽度。 趋势通道的宽度是柱线价格相对于回归线的最大分布。 更准确地说,它是向上和向下最大偏差的总和:

为了计算通道宽度,您需要遍历趋势的所有柱线,计算每根柱线的回归值(与之前获得的线性回归方程中的 “y” 相同),计算该值与柱线价格之间的差值,并累积这些差值的最大值:

         for (X=1; X<=TrendBarNum; X++)
         {
            int TmpCurBar=CandleStartBar+X;
            Y = A + B*X;
            DH=high[TmpCurBar]-Y;
            DL=low [TmpCurBar]-Y;
            if ((DH > maxDH)||(X==1)) maxDH=DH;
            if ((DL < minDL)||(X==1)) minDL=DL;
         }

我们可以将通道的宽度与十字星蜡烛的高度进行比较,从而得出结论,该蜡烛的走势是否足够强大,以至扭转这一趋势。 为此,向指标里再添加一个趋势输入参数,该参数设置通道宽度与找到的十字星烛条高度的最大允许比率:

  input double  Trend_ChanelPowerMax  = 1;

在指标代码中,参考如下:

         if ((maxDH-minDL) > Trend_ChanelPowerMax*CandleHeight) break; 

完整的指标代码附在下面。


策略的最终指标算法

现在我们有了检测趋势存在的代码,我们将其作为过滤器连接。 如此,只有那些十字星蜡烛才能显示在指标图表上,在指标图表前面有一个与所有层面相适的趋势 — 方向、长度和宽度。

我们将所有与趋势特征可接受性的计算和评估相关的代码放入指标代码中的一个单独函数当中:

bool DetectTrend(
                 int CandleStartBar,
                 int CandleDir,
                 double CandleHeight,
                 const double& open[],
                 const double& high[],
                 const double& low[],
                 const double& close[]
                )

它返回的逻辑值,指示是否存在相适的趋势。 每次找到十字星蜡烛时,我们都会调用此函数:

               if (DojiExists)
               {
                  if (DetectTrend(CurBar, CandleDir, CandleHeight, open, high, low, close))
                     break; // there is a candle and a trend, there is no need to expand the metabar further 
                  else
                     DojiExists=false;
               }

完整的指标代码附在下面。 稍后我们将一并检查它与 EA 的工作状况。


EA 算法

如此,我们有一个修改后的指标,用于在元柱线上寻找十字星蜡烛,且同一指标可判定蜡烛之前是否存在趋势。 现在,只有当十字星蜡烛和与蜡烛尖端方向相同的趋势同时存在时,指标才会在图表上绘制一条线。 在其它情况下,指标不会绘制任何内容。

故此,这种指标的读数已可作为交易 EA 现成的信号。 当指标上出现一条线时,执行交易。 剩下的就是决定何时完成成交。

鉴于在我们的例子中,指标的信号是针对可能的趋势逆转的预测,并指示其方向,故当指标显示与开仓信号相反的信号时,应把现有持仓平仓。 这是成交了结的最佳信号,因为理想情况下,它的出现意味着,在趋势开始时入场(根据之前的信号),智能系统将在趋势的末段退出,也就是说,它将从这种市场状况中赚取最大可能的利润。

顺便说一下,这个信号不仅仅是成交了结。 立即以相反的方向开立新的成交,因为我们也依据该指标信号入场。

然而,市场价格并不总是遵循交易者的理想轨迹。 趋势的开始和结束也并不总是清楚地标记出来。 从一个趋势结束到,下一个趋势开始,之间也可能需要很长时间。 这将段时期是横盘、或短期价格上下乱窜的走势。 我们的指标针对这种情况不会以任何方式做出反应。 这意味着我们将在很长一段时间内都不会收到来自它的完结信号。 尽管最初的趋势已经耗尽,并且在市场上运用该策略已不再有任何意义。

对于任何交易策略,添加附加平仓条件的最简单途径就是为所有已开仓交易设置止盈和止损价位。 可以在 EA 设置中设置它们的数值。

此外,您需要将所有指标参数添加到 EA 设置当中:十字星蜡烛大小范围、趋势大小范围、等等。 EA 将通过自身启动指标(不可见),将设置传递给它。

交易 EA 的完整代码在文章的附录之中。 在本文中讲述代码是没有意义的,因为 EA 非常简单且典型。 整个市场分析由指标执行,而 EA 仅根据现成的信号开仓和平仓。


检验成品 EA

在基于历史记录进行大规模测试之前,我们先检查一下一切是否正常。 我们在 MetaTrader 5 策略测试器中依据一小段历史运行 EA ,并检查图表上显示的交易。

可以看出,智能系统的行为与预期的算法相对应。 此处是依据正确的指标信号开仓时的情况:

该指标在前两根柱线的元柱线上发出向上的十字星烛条信号,
并在蜡烛之前发出上升趋势的信号。 EA 则据其开立交易


之后,该笔交易依据相反的信号平仓,并在相反的方向上开立了一笔新交易:

该指标在前三根柱线的元柱线上检测到向下的十字星蜡烛,
并在蜡烛之前检测到下降趋势。 EA 则平仓了结,并开立了一笔反向交易。


指标长时间没有逆反信号,且交易由止盈平仓的情况:

指标并无信号。 EA 开立的交易在达到止盈价位时了结。


准备交易策略的回测

成品交易 EA 具有非常灵活的设置。 我们可以将其设置为基于元柱线、或传统(单根)柱线的十字星蜡烛进行交易。 蜡烛之前的趋势参数也可以调整为零值(这实际上意味着不考虑趋势的存在)。 所有这些都极大地影响了 EA 的行为。 您甚至可以考虑有条件地将这些设置划分为不同的交易策略。 优化将显示这些选项中哪些是最有效的。

在各种交易资源中,建议在不低于一小时的时间帧内运用十字星形态,否则价格噪音会发出很多虚假信号。

我们依据 EURUSD H4 进行测试。 对于高品质的统计数据,在随机性和调整效果的影响最小的情况下,我们将取 10 年长度的区间。 MetaTrader 5 中的策略测试器允许我们将选定的部分划分成两半:前半部分将用于训练 EA 交易,后半部分将用于训练后的自动测试(前向验证测试)。



我们将进行两次测试(和训练)以便判定哪个更有效:元柱线或经典蜡烛。 我们将通过挽救系数进行比较 — 赚取的盈利与回撤的比率。 此参数越大,策略越有利可图。

EA 有很多优化的参数,所以为了加快优化速度,我们不应通过穷举搜索来执行它,而是通过遗传算法来执行它。


单根(常规)十字星蜡烛的设置

时间帧为 H4。 蜡烛宽度严格限定 1 根柱线。 其余设置具有广泛的优化范围:

EA 参数 开始
步长
停止
Candle_WidthMin 1
Candle_WidthMax 1
Candle_HeightPowerMin 0.2 0.2 2
Candle_BodyPowerMax 0.1 0.1 0.4
Candle_ShadowPowerMax 0.1 0.1 0.4
Trend_WidthMin 1 3 10
Trend_WidthMax 1 4 40
Trend_PowerMin 0 0.2 2
Trend_ChanelPowerMax 0.5 0.2 2
Lots 0.1
TakeProfit 300 300 3000
StopLoss 300 300 3000

这意味着有超过 63 万个参数组合。 不过,遗传优化将减少数千次穷举,并允许我们在几分钟内得到适配结果。


元柱线十字星蜡烛的设置

元柱线可以在无限的范围内具有可变宽度,也就是说EA 可以基于大量不同宽度的蜡烛即刻交易。 但为了实验的准确性,我们不会在测试时设置比一根柱线蜡烛宽太多的范围。 最接近 H4 的标准可用时间帧是 H3 和 H6。 我们将仅用元柱线捕获这些数值之间的差距。 允许您执行此操作的最近的较小时间帧是 M30。 据其运行 EA,我们就能够在宽度等于以下任何一项的所有元柱线上进行交易:H3.5、H4、H4.5、H5、H5.5。 这些时间帧中只有一个(H4)可用于在经典的十字星蜡烛上进行交易。 如果没有元柱线,我们就无法依据其它进行交易。 元柱线上的蜡烛就像魔术师从空帽子里拿出的兔子。 然而,与预先存在的兔子不同,元柱线捕捉到真正的额外价格变动(我们在上一篇文章中看到了这一点)。 我们即将发现是否可以把这些变化转化为真正的额外利润。

所有其它 EA 设置与单柱线变体测试中的设置完全相同。 我们只需要缩放它们:由于 M30 时间帧比 H8 小 4 倍,因此所有以柱线测量的 EA 输入都应乘以 8。

与单柱线测试不同的参数以粗体显示。

Timeframe M30 (H4 及附近,以元柱线为代价进行模拟)。

EA 参数 开始
步长
停止
Candle_WidthMin 7
Candle_WidthMax 11
Candle_HeightPowerMin 0.2 0.2 2
Candle_BodyPowerMax 0.1 0.1 0.4
Candle_ShadowPowerMax 0.1 0.1 0.4
Trend_WidthMin 8 24 80
Trend_WidthMax 8 32 320
Trend_PowerMin 0 0.2 2
Trend_ChanelPowerMax 0.5 0.2 2
Lots 0.1
TakeProfit 300 300 3000
StopLoss 300 300 3000


依据历史记录测试交易策略的结果

在依据 5 年历史优化 EA 的同时,策略测试器遍历了大约 5 千个组合设置,并构建了一个图表,显示 EA 在每个选项上取得的结果。 我们可以将以下图表与单柱线 EA 和元柱线 EA 并排放置,根据垂直标尺(恢复因子)对齐它们:


单柱线(左)和元柱线(右)EA 的全部优化结果


这些图表显示元柱线通常会导致更好的结果。

但这只是一个初步且非常粗略的结论。 我们将优化结果导出到外部程序(如 Excel),以便进行更详细的分析。 如果我们计算 EA 按照不同设置进行了多少笔交易,那么差距将如下所示:

蜡烛类型 交易数量
(每一次 EA 验算教程历史)
平均
单柱线
0
54
1472
元柱线
0
82
3796

基于这样的样本,我们只能可靠地判断元柱线确实允许我们执行更多交易。

然而,现在评估盈利能力还为时过早,因为样本包含大量的设置选项,其中 EA 进行的交易很少 — 只有几笔甚至一笔...... 故此,无论 EA 看起来多么有效,我们都不能轻信这个结果,因为本质上它可能出于偶然。

为了得出统计上可靠的结论,我们需要在样本中只留下导致 EA 执行大量交易的选项。 我们针对示例应用以下最小合理筛选器:

  • number of trades >= 120 (这意味着 5 年内每月 2 笔交易)

在那之后,在大约 5000 个设置选项中,单柱线 EA 只剩下大约 600 笔,元柱线 EA 只剩下大约 900 笔(因为它平均进行更多交易)。 我们基于它们构建一个图形来比较单柱线 EA 和元柱线 EA 的训练阶段:

最小得可靠优化结果


该图形显示,单柱线 EA(从回归线可以看出)在整个训练期间的平均结果略好。 但元柱线 EA 的结果分布范围更广,无论是更大损失方向上,还是在更大盈利能力方向上。 这可以用在元柱线上进行了更多交易的事实来精确解释,这作为一种增幅器:无利可图的 EA 使损失成倍增加(因为它们进行了更多无利可图的交易),而有利可图的 EA 则盈利倍增。

因此,元柱线 EA 取得了最有利可图的结果。 该图形显示,只有 EA 能够一次性达成高于 6 的恢复因子。

现在我们来看看具有最佳设置的 EA 在前瞻测试中基于未来 5 年历史的表现。 最后一个图表显示,平均(回归线)训练结果值达到 2。 如此,我们将高于此平均值的所有内容视为良好值。 附加过滤器适用于上图中显示的示例:

  • recovery factor >= 2 (在 5 年的历史中,回撤为 50%,这相当于每年 20%)。

单柱线和元柱线 EA 的样本量现已减少到约 200 个数值。 对于此示例中的所有设置,我们找到在前向验证测试中实现的结果,并基于它们构建图形:


基于优化期间获得最佳设置进行前向验证测试


前向验证测试图形显示,元柱线 EA 设法保持其领先地位,因为它在最佳结果中占据主导地位。 甚至,现在它的平均结果也略好于单柱线 EA。

此图表中的所有 EA 进行了多少笔交易? 我们来计算一下:

蜡烛类型 交易数量
(每一次 EA 依据历史前向验算)
平均
单柱线
121
231
543
元柱线
122
352
1173

可以看出,EA 在前向验证测试中与在训练阶段一样活跃 — 最小交易数量与我们之前应用的过滤器值大体一致。 大多数交易是据元柱线 EA 进行的。

您可能还记得,这是本文的目标 — 判定元柱线能否允许您进行更多交易(而不仅仅是找到更多蜡烛),以及这能否会增加收益。 现在我们可以回答这两个问题:“是”。

作为一项边缘研究,我们可以评估十字星蜡烛交易策略的有效性。 前向验证测试图形已经进行了评估 — 其上所有策略的结果都比训练阶段差很多。 因此,为了真正有效的交易,我们需要创建一个更先进的交易系统和/或更仔细地选择最优设置、时间帧、货币对和历史范围。 作为奖励,我在这里展示一些最独特的 EA 设置,这些设置在上面的前向验证测试图上显示出良好的结果:

时间帧 H4 M30
输入
Candle_WidthMin 1 7
Candle_WidthMax 1 11
Candle_HeightPowerMin 0.4 2 1.8 1.6
Candle_BodyPowerMax 0.2 0.1 0.2 0.2
Candle_ShadowPowerMax 0.1 0.4 0.4 0.3
Trend_WidthMin 1 80 80 80
Trend_WidthMax 13 296 296 168
Trend_PowerMin 1.6 0 0 0
Trend_ChanelPowerMax 1.5 1.9 1.7 1.9
Lots 0.1
TakeProfit 900 300 300 300
StopLoss 300 3000 1200 3000


结束语

实验可以证明,依据元柱蜡烛而不是传统的(单根柱线)蜡烛可令交易策略执行更多的交易。

元柱线应谨慎使用。 毕竟,若是亏损策略,那么进行更多交易,将变得更加无利可图;而盈利策略则可以变得更加有利可图。

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/12355

附加的文件 |
MQL5.zip (4.82 KB)
如何在 MQL5 中集成 ONNX 模型的示例 如何在 MQL5 中集成 ONNX 模型的示例
ONNX(开放神经网络交换)是一种表现神经网络的开放格式。 在本文中,我们将展示如何在一个智能交易系统中同时使用两个 ONNX 模型。
开发回放系统 — 市场模拟(第 05 部分):加入预览 开发回放系统 — 市场模拟(第 05 部分):加入预览
我们已设法开发了一套以逼真和可访问的方式来实现市场回放的系统。 现在,我们继续我们的项目,并添加数据,从而提升回放行为。
MetaTrader 中的多机器人:从单图表中启动多个机器人 MetaTrader 中的多机器人:从单图表中启动多个机器人
在本文中,我将研究一个简单的模板,用来创建通用的 MetaTrader 机器人,该机器人可以在多个图表上使用,同时仅附加到一个图表,无需在每个单独的图表上为每个机器人实例进行配置。
利用 MQL5 实现 Janus 因子 利用 MQL5 实现 Janus 因子
加里·安德森(Gary Anderson)基于他称之为Janus因子的理论,开发了一套市场分析方法。 该理论描述了一套可揭示趋势和评估市场风险的指标。 在本文中,我们将利用 mql5 实现这些工具。