English Русский Español Deutsch 日本語 Português
CCI 指标。 三个变换步骤

CCI 指标。 三个变换步骤

MetaTrader 5指标 | 9 十一月 2022, 14:34
1 842 0
Aleksej Poljakov
Aleksej Poljakov

前一篇文章里,我曾研究过传统的商品通道指数指标的可能变化。 它们涉及计算方法,但不影响该指标的实质。 在本文中,我将研究改良指标的计算逻辑,期望指标从略微不同的角度来观察。 我们来看看这些变化将如何影响指标结果。 当然,我将尝试评估所实现修改的有效性。


步骤一

CCI 基于简单直观的计算。 首先,计算当前价格与平均值之间的差值。 然后将该差值除以标准偏差。 换言之,我们取价格和样本中间值之间的差值,并与样本标准偏差相比,估算高出(或低出)的倍数。

一切都简单明了。 但也有一点缺陷,可能会导致错误的决定。 我们以两个序列为例:2, 1, 121, 11, 1。 如果我们将这些序列翻译成交易语言,那么第一个是横盘,第二个则是清晰而强劲的趋势。

这两个序列中的哪一个能给出更高的 CCI 值? 尝试根据您的直觉回答,并证明您的答案。 同时,我将进行必要的计算。

第一个序列

第二个序列

正如我们所看到的,两个序列产生的结果相同。 主要原因是我们使用了标准偏差。 对于第一个序列,当期值和平均值之间的差值很小。 但标准偏差也很小。 对于第二个序列,差值增加了,但标准偏差也增加了。 这就是为何两个不同的序列却导致相同的结果。

如果我们向任何交易者询问他们对技术指标的需求,那么他们很可能会说:特殊的情况应该导致特殊的指标值。 这对于 CCI 而言,是否有可能实现这样的愿望? 答案是肯定的。 但要达成这一点,我们需要摒弃除法,转而用乘法代替它。 然后指标公式将如下所示:

依据这样的变化,当差值和标准偏差都很大时,指标理应足够高亮示意价格走势趋势。 但这种方式有其自身的特点。 我们无法(甚至近似地)估算指标值的范围及其水平。 然而,这个缺点很容易克服。 让指标本身计算它需要什么值,以及多久需要。 收集此类数据后,我们就可以设置指标等级。 略微偏离零轴的指标读数会更频繁地出现。 较大的值不太会频繁地出现。 按出现的频率分隔指标值,我们就能够设置指标等级。 我们考虑到指标的正值和负值的统计数据也许彼此不同。 因此,我们要分别收集正等级和负等级的数据。

各种级别值能便利地设置为百分比。 例如,如果级别等于 70,那么这正是指标值在水平线和零轴之间的比例。 只有 30% 的值会超出级别。

为了计算级别,我们将进行如下操作。 我们创建两个数组来存储指标值(正值和负值彼此分开)。

int array_dn[],         // array for storing positive values
    array_up[],         // array for storing negative values
    size_dn=0,size_up=0;// array sizes

我们先要为数组设置大小。

ArrayResize(array_up,size_up,rates_total);
ArrayResize(array_dn,size_dn,rates_total);

当历史数据可用时,我们设置获得的结果。 请注意,我们在数组里把负值转换为正值。 这样做是为了方便后续处理。

if(cci>0)
  {
   ArrayResize(array_up,size_up+1);
   array_up[size_up]=(int)MathRound(cci/_Point);
   size_up++;
  }
if(cci<0)
  {
   ArrayResize(array_dn,size_dn+1);
   array_dn[size_dn]=(int)MathRound(-cci/_Point);
   size_dn++;
  }

在零号柱线开盘之前,您首先需要在数组里进行排序。 然后查找数组元素的索引。这些单元格将包含级别值。 不要忘记对于负值返回一个减号。

ArraySort(array_up);
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,array_up[size_up*level/100]*_Point);
ArraySort(array_dn);
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,-array_dn[size_dn*level/100]*_Point);

 

现在我们来看一下我们的新指标。


正如我们所看到的,所有计算选项都产生了类似的画面。 主要区别在于级别的数值。 有趣的是,所有选项的正值和负值的级别彼此不同。 这意味着从指标的角度来看,价格上涨和下跌的走势并不对称,我们的假设,及单独收集统计数据被证明是合理的。

然而,我们的新指标与传统 CCI 进行比较更有趣。 在此,我们可以遇到指标看起来非常相似的领域

 

以及指标显示出不同行为的部分。 如果我们注意指标线与其级别的交叉,这种差异变得特别明显。


现在我们来测试新指标的实际效果。 开发一个 EA 来依据其信号进行交易。 鉴于指标级别可能会发生变化,我们将按如下方式设置开仓规则。 如果指标的当期值低于负级别,并且指标的前期值低于当期值,则将开立多头仓位。 而如果指标的当期值高于正级别,并且指标的前期值高于当期值,则将开立空头仓位。 开仓类型会导致相反类型平仓。

测试参数:EURUSD H1, 2021.01.01 - 2021.12.31。

每次测试的主要结果如表所示

类型
净利润总额
毛利
毛损失
总交易
经典 248.21
1 361.74
-1 113.53
823
平方 -304.83
2 993.08
-3 297.91
3581
新式 -567.15
2 540.88
-3 108.03
3251

有趣的是,计算标准偏差的经典方法立即产生了正面的结果。 在最后两个选项中,交易数量明显增加。 这可能表明需要提高指标触发级别。 之后交易数量就会降低,且可能提高其效率。 经典版本的余额曲线示例如下所示。



步骤二

到目前为止,我是利用标准偏差来计算指标。 仅当数值分布符合正态定律时,才能证明使用标准偏差进行数值常规化是合理的。 针对 CCI 的情况下,初始数据是价格和平均值之间的差值。 我们来看看它们实际上是如何分布的。

为了强调所得结果的特征,我减少了样本量,并从中删除了零值。 如您所见,该图形结果相当奇特,甚至看起来都不像正态分布图。

如果差值根据某种经验定律分布,我们应当放弃标准偏差。 那么我们的指标就变成 CCI 的一半。

我们考虑一下这一步的后果。 显然,如果未经平滑,指标值的分布将非常大,看起来会有些不寻常。 此外,较大的价格走势会影响指标的视觉感知。 但这些缺点不能压倒一个巨大的优势。

当计算 CCI 指标值时,我们用到一个简单的均化。 这是一个众所周知的等式,但我仍然会在这里展示它:

这个公式背后是什么? 这可以是算术中间值、随机变量的数学期望、和矩形窗口。 我们盯上最后一个选项。 为什么是矩形窗口? 毕竟,我们还有其它可用的窗口函数。

我知道大约有五十个窗口函数有自己的名字。 而没有专有名称的窗口函数的数量数不胜数。

出于实验目的,我们将采用一个矩形窗口、一个三角形窗口、和平顶窗口。 最后一个窗口函数相当不寻常,因为它的某些权重采用负值。 我们也取三个不对称的窗口 - 线性、幂、和指数权重。 拥有线性和指数权重的平均值可在 MetaTrader 的移动平均线菜单中找到。
所有选项的一般视图如图所示(最低指标是经典 CCI)。

所有选项都非常相似,但它们的级别可能相差很大。 这取决于所采用的窗口函数 — 其中一些有滞后,指标值相对较大的可能会更频繁地出现。 其它窗口函数跟随价格,因此小偏差更常见。

此外,为防万一,指标添加了两个平滑选项。 它们不会改变计算的本质,但它们可令指标在视觉上更具魅力。

 

我们开发另一个 EA,来测试这个 hCCI 指标。 开仓和平仓的信号则与之前的 EA 完全相同。 测试参数及其时间间隔也与前一种情况相同。

主要测试结果如表所示。

窗型
净利润总额
毛利
毛损失
总交易
矩形
224.57
1 745.03
-1 520.46
726
三角形
94.17
1 532.10
-1 437.93
696
平顶
236.54
1 354.67
-1 118.13
643
LWMA
243.62
1 444.48
-1 200.86
639

44.57
1 175.79
-1 131.22
561
指数
-317.41
725.11
-1 042.52
359

    在所有窗口函数中,只有指数窗口产生了负结果。 这并不意味着它不适合交易。 这意味着需要对其参数进行微调。 平仓规则也应改进。 (这适用于所有 EA 版本)。 示意图展示了 LWMA 窗口函数的 EA 余额曲线。



    步骤三

    到目前为止,我们将 CCI 指标视为振荡器。 但是将其移至主图表,并查看它如何显示会更有趣。 我们看看如何达成这一目标。

    大多数振荡指标都基于一个简单的原理 — 抑制主要信号,同时突出微妙的价格走势。 因此,要将指标转移到主图表,我们需要在其值中添加一个参考信号。 针对 CCI 的情况下,当前价格或平均值可以作为参考信号。 那么计算指标值的公式如下:

     

    这两个选项都不稳定。 它们的数值可能严重偏离价格线。 但这两个指标都可以很好地突出价格走势的趋势,而这一事实弥补了上述缺点。


     


    结束语

    拟议指标的开发原则则根基于经典 CCI 指标之上。 新指标的优势无可置疑,它能够根据交易者的选择对其进行自定义。

    指标参数:

    pCCI 指标

     

    • TypeInd – 设置计算指标值的方法;
    • iPeriod – 指标周期,最小值 2;
    • iLevel – 指标级别值,有效值 1 – 99。

       hCCI 指标

    • Window – 采用的窗口函数类型;
    • Smoothing – 所应用的平滑方法;
    • iPeriod – 指标周期,最小值 2;
    • iLevel – 指标级别值,有效值 1 – 99。

      lCCI 指标

    • Window – 采用的窗口函数类型;
    • Direct – 参考信号类型;
    • iPeriod – 指标周期,最小值 2;

      差值分布脚本

    • Length – 移动均化周期;
    • Level – 最大样品值;
    • ViewDuration – 持续显示时间;
    • ScreenShot – 如果启用了该参数,则图表截图将保存在 “Files” 文件夹当中。

    EA pCCI

    其所有参数均与 pCCI 指标的参数相同。在新柱线开立时,生成开仓和平仓信号。

      EA hCCI

      其主要设置与 hCCI 指标的设置相对应。 

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

      附加的文件 |
      pCCI.mq5 (5.11 KB)
      hCCI.mq5 (4.68 KB)
      lCCI.mq5 (6.77 KB)
      EA_pCCI.mq5 (8.8 KB)
      EA_hCCI.mq5 (8.6 KB)
      pCCI.mq4 (6.51 KB)
      hCCI.mq4 (5.69 KB)
      lCCI.mq4 (4.39 KB)
      EA_pCCI.mq4 (7.64 KB)
      EA_hCCI.mq4 (7.44 KB)
      DoEasy. 控件 (第 13 部分): 优化 WinForms 对象与鼠标的交互,启动开发 TabControl WinForms 对象 DoEasy. 控件 (第 13 部分): 优化 WinForms 对象与鼠标的交互,启动开发 TabControl WinForms 对象
      在本文中,我将修复和优化当鼠标光标移离 WinForms 对象后 WinForms 对象的外观处理,并启动开发 TabControl WinForms 对象。
      学习如何基于柴金(Chaikin)振荡器设计交易系统 学习如何基于柴金(Chaikin)振荡器设计交易系统
      欢迎阅读我们系列的新篇章,学习如何基于最流行的技术指标设计交易系统。 通读这篇新文章,我们将学习如何基于柴金(Chaikin)振荡器指标设计交易系统。
      利用对象轻松制作复杂指标 利用对象轻松制作复杂指标
      本文提供了一种创建复杂指标的方法,同时还避免了在处置多个作图板、缓冲区、和/或组合来自多个来源的数据时出现的问题。
      神经网络变得轻松(第二十二部分):递归模型的无监督学习 神经网络变得轻松(第二十二部分):递归模型的无监督学习
      我们继续研究无监督学习算法。 这次我建议我们讨论自动编码器应用于递归模型训练时的特性。