English Русский Español Deutsch 日本語 Português 한국어 Français Italiano Türkçe
preview
CCI 指标。 升级和新特征

CCI 指标。 升级和新特征

MetaTrader 5示例 | 27 九月 2022, 10:36
2 548 0
Aleksej Poljakov
Aleksej Poljakov

简要历史

商品通道指数(CCI)是每位交易员都熟悉的。 它由唐纳德·兰伯特(Donald Lambert)开发,并于 1980 年首次在商品杂志(现名为现代交易者)上发表。自那时起,这一指标获得了应有的声誉,并在交易者中广受欢迎。 它存在于 MetaTrader 交易平台工具包中,既可用于手动交易,也可作为自动交易系统的一部分使用


计算算法

该指标的计算非常简单明了。 该指标显示价格相对于绝对偏差均值的平均偏离程度。 其算法如下所示。 指标周期为 N 个价格读数。 之后:

  • 计算均值 

均值

  • 求绝对偏差均值

MAD

  • 计算指标值

CCI

在原始指标中,校正系数 k=0.015。 选择它的方式是,1.5*MAD 的价格偏差等于 100 个指标单位。 在这种情况下,3*MAD 的偏差为 200 个单位。 (有趣的是,如果用乘法代替除法,则归一化系数k的值为 66.6)


可能的算法变化

该指标的显著特点是使用绝对偏差均值。 这种方式在计算机技术诞生之初就已经被完全证明是正确的,因为与计算更合适的标准偏差相比,计算绝对偏差所需的计算资源较少。 现代计算机可以在合理的时间内处理平方和根运算。 因此,计算算法如下。

  • 求数字之和:

sumS

  • 求平方和:

sumQ

  • 计算指标值:

CCI

这样的算法更精确,但仍不完美。 主要问题是,估算平均值和均方根值需要足够多的价格读数(不少于三十个)。 然而,较短周期也可用于交易。 例如,在 CCI 的经典版本中,建议周期采用 14 个样本。

这种情形需要强健的统计方法。 即使在金融市场过热的极端情况下,它们也能获得相当稳定和可靠的参数估算值。

我们来看看强健的方法是如何工作的,并拿它们与经典方法进行比较。 例如,我们取三个值的时间序列:p[0]=1,p[1]=3,p[2]=8。

然后将经典方式简并为以下计算:

  • Mean (1 + 3 + 8) / 3 = 4
  • 绝对偏差 (abs(1 – 4) + abs(3 – 4) + abs(8 – 4)) /3 = 2.67
  • 通道的下限和上限 1.33 – 6.67 

现在,我们取标准偏差进行计算:

  • Mean (1 + 3 + 8) / 3 = 4
  • 标准偏差 sqrt(((1 – 4)^2 + (3 – 4)^2 + (8 – 4)^2) / 3) = 2.94
  • 通道的下限和上限 1.06 – 6.94

强健估值的计算成本更高。 我们用泰尔-森(Theil-Sen)方法来估算平均值。 为此,我们应该首先找到时间序列值对分的所有半值合计。 这些对分的数量可以通过以下等式获得:num=(N*(N-1)) / 2。

在这种情况下,稳定的均值等于这半值合计的中位数。 为了找到中位值,我们应该首先按升序给数组进行排序。 然后中位值将与数组中心的值相对应。 为了找到中位值,如果数组大小是奇数,我们需要中心元素的索引,如果数组的大小是偶数,则需要两个中心元素的索引。 然后中位数等于这两个元素的平均值。

计算这两种情况索引值公式(“size” 是数组中的元素数量):

  • 尺寸为奇数

Index = size / 2

  • 尺寸为偶数

Index1 = size / 2 – 1; Index2 = size / 2

在我们的示例中,如下所示:

hs1 = (1 + 3) / 2 = 2

hs2 = (1 + 8) / 2 = 4.5

hs3 = (3 + 8) / 2 = 5.5

排序 2, 4.5, 5.5

  • 均值 = 4.5

现在我们继续讨论偏差。 我们需要找到原始时间序列的绝对值,与其平均值之间的中位数。

d1 = abs(1 – 4,5) = 3.5

d2 = abs(3 – 4,5) = 1.5

d3 = abs(8 – 4,5) = 3.5

排序 3.5, 1.5, 3.5

  • 偏离 = 3.5
  • 通道 1–8 的下限和上限


比较经典和升级的指标版本

我们来比较这些方式。 经由正常计算,时间序列的最小值和最大值超出了均值 +/- 偏差。 在强健估算的情况下,原始序列的所有值都符合这些边界。 这三种方式的差异是显而易见的,但这仅是我们的示例。 现在我们看看不同的计算方法在实际数据上的表现。 我们将这三种算法作为单独的指标来实现。 这也将令我们能更了解计算每个选项的特点。

该指标的出现在很大程度上取决于两个变量 — 应用的价格常数及其周期。 在 MQL5 里,价格常量可在定义指标属性时设置。

#property indicator_applied_price PRICE_TYPICAL

在 MQL4 里,我将使用单独的函数。

指标周期显示计算中采用的价格读数数量。

input ushort iPeriod=14;//indicator period

变量值应至少为三。 请记住,在周期较小的情况下,可能会得到不正确(过陡峭)的值。

经典 CCI 版本在第 i 根柱线上的计算如下。 首先,找到样本均值。

double mean=0;                //sample mean
for(int j=0; j<iPeriod; j++)
   {
    mean=mean+price[i+j];     //sum up price values
   }
mean=mean/iPeriod;            //sample mean for the period

现在是计算绝对偏差均值的时候了。

double mad=0;                          //mean absolute deviation
for(int j=0; j<iPeriod; j++)
   {
    mad=mad+MathAbs(price[i+j]-mean);  //sum up absolute difference values
   }

如果绝对偏差均值大于零,则指标等于:

res=(price[i]-mean)*iPeriod/mad;

采用标准偏差的指标版本计算如下。 首先,我们需要找到价格的总和,及其平方。

double sumS=0,//sum of prices
       sumQ=0;//sum of price squares
for(int j=0; j<iPeriod; j++)
   {
    sumS=sumS+price[i+j];
    sumQ=sumQ+price[i+j]*price[i+j];
   }

现在我们需要找到计算指标所需的分母。

double denom=MathSqrt(iPeriod*sumQ-sumS*sumS);

如果分母大于零,则结果如下:

res=(iPeriod*price[i]-sumS)/denom;

最后,我们研究采用强健方法进行的计算。 首先,我们需要准备两个数组来存储中间结果。 一个数组存储半和值,而另一个数组则存储绝对差值。

double halfsums[],diff[];

首先,准备半和值数组,留待进一步备用。 为此,我们来定义它的大小。

int size=iPeriod*(iPeriod-1)/2; //halfsums array size
ArrayResize(halfsums,size);     //set the array size

现在,我们找到数组中心元素的索引。 出于通用性缘故,我将使用两个索引。 如果大小是奇数,则这些索引将相互匹配,否则保持不同。

indx10=size/2;
indx11=indx10;
if(MathMod(size,2)==0)
   indx11=indx10-1;

然后,准备 diff 数组。 其大小与指标周期一致。 元素索引与前一种情况相同。

ArrayResize(diff,iPeriod);
indx20=iPeriod/2;
indx21=indx20;
if(MathMod(iPeriod,2)==0)
   indx21=indx20-1;

现在是开始计算指标值的时候了。 我们需要一个额外的计数器,方便用半和值来填充数组。

int cnt=0; //counter of array elements
for(int j=iPeriod-2; j>=0; j--)
   {
    for(int k=iPeriod-1; k>j; k--)
       {
        halfsums[cnt]=(price[i+j]+price[i+k])/2; //half sum value
        cnt++;                                   //increase the counter
       }
   }

填充数组后,应该对其进行排序。 来自数组中心的值应用作均值的估值。

ArraySort(halfsums);                               //sort the array
double mean=(halfsums[indx10]+halfsums[indx11])/2; //robust mean

在下一阶段,查找标准偏差的强健估值。

for(int j=0; j<iPeriod; j++)
   {
    diff[j]=MathAbs(price[i+j]-mean);
   }
    
ArraySort(diff);
double sd=(diff[indx20]+diff[indx21])/2; //robust standard deviation

如果标准偏差大于零,则指标值为:

res=(price[i]-mean)/sd;

现在我们可以比较不同版本的指标的行为。 在某些情况下,指标看起来非常相似。


但也有一些区域的差异非常明显。



比较指标的小型智能系统

视觉比较很主观,可能会导致错误的结论。 我们的结论需要更可靠的基础。 为了评估所有指标版本,我们编写一个简单的智能系统。 我们为它分配相同的开盘和收盘规则,并比较结果。 我将采用以下规则 — 穿过给定的水平面,则在一个方向开仓;在相反的方向平仓(如果有的话)。

EA 参数:

  • TypeInd - 指标类型(经典、方形、现代)
  • iPeriod - 指标周期
  • iPrice - 指标价格
  • Level - 欲跟踪其交叉的级别。 其值 150 对应于经典 CCI 中的 100 级。

为了加快测试速度,指标计算算法已移动到 EA 当中。 指标值在新柱线开盘时计算。 如果指标值向上穿过负级别值,则开多头仓位。 与此同时,空头持仓平仓。 如果指标值向下穿过正级别值,则开空头仓位(多头持仓平仓)。

测试参数:

EURUSD 货币对

H1 时间帧

时间区间 – 2021 全年

周期 = 14

价格类型 = PRICE_TYPICAL

级别 = 150

所有三种情况的余额曲线选项如下所示。

TypeInd = 经典

tester1

TypeInd = 方形

tester2

正如我们所见,应用标准差导致交易次数减少,随后大额亏损减少。

TypeInd = 现代

tester3

采用强健估算增加了交易次数,而大幅亏损的次数则进一步减少。 对于该指标版本来说这是一个很大的优势。

无论如何,在所有情况下,开仓和平仓规则都需要认真改进。


    用于评估趋势的指标修改

    在仔细观察 CCI 指标(任何版本)的同时,我有了一个惊人的发现 — 它即可以取正值,也可以取负值。 我不知道这是否值得诺贝尔奖,但 MetaQuotes 有限公司 应该设立自己的奖项。 我理应获得该奖项。 但开个玩笑就够了。

    正指标值与上升趋势相关,而负指标值与下降趋势相关。 我们来更详细地探讨一下这个问题。 新指标的总体思路如下:我们总结了从趋势开始到结束的 CCI 指标值。 当然,我们将把这个走势与均值进行比较。 以这种方式,我们就能够评估趋势走势的持续时间及其强度。

    采用强健估算的计算版本作为基础。 唯一不同的是,我们将在 CCI 指标值超过零轴后,对其总和进行累加。 此累计额的数值将用作输出。 上升趋势和下降趋势的平均数额将单独计算,以便进行比较。 该指标的总览图如下所示。


    依据这个指标,我们可以评估趋势的开始、结束和强度。 基于这个指标的最简单策略可能是这样的 — 在趋势完成时,如果趋势高于平均值(指标越过了相应的级别),我们可以预期价格会朝相反的方向移动。

    结束语

    正如我们所见,重新审视技术指标可能非常有用。 没有一个指标是最终版本 — 总是有可能针对具体策略进行细化和修改。 附带文件:

    • mCCI — 三种 CCI 版本的指标
    • EA CCI — 比较不同 CCI 版本的交易 EA
    • tCCI — 计算累计趋势量的指标。

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

    附加的文件 |
    mCCI.mq5 (3.84 KB)
    EA_CCI.mq5 (7.46 KB)
    tCCI.mq5 (4.55 KB)
    mCCI.mq4 (5.25 KB)
    EA_CCI.mq4 (6.26 KB)
    tCCI.mq4 (4.54 KB)
    学习如何基于 Williams PR 设计交易系统 学习如何基于 Williams PR 设计交易系统
    本系列中的一篇新文章,介绍了如何依据 MQL5 最流行的技术指标为 MetaTrader 5 设计交易系统。 在本文中,我们将学习如何依据 Williams‘ %R 指标设计交易系统。
    神经网络变得轻松(第十九部分):使用 MQL5 的关联规则 神经网络变得轻松(第十九部分):使用 MQL5 的关联规则
    我们继续研究关联规则。 在前一篇文章中,我们讨论了这种类型问题的理论层面。 在本文中,我将展示利用 MQL5 实现 FP-Growth 方法。 我们还将采用真实数据测试所实现的解决方案。
    从头开始开发智能交易系统(第 22 部分):新订单系统 (V) 从头开始开发智能交易系统(第 22 部分):新订单系统 (V)
    今天,我们将继续开发新订单系统。 实现一个新系统并非那么容易,因为我们经常会遇到各种问题令过程复杂化。 当这些问题出现时,我们必须停下来重新分析我们前进的方向。
    从头开始开发智能交易系统(第 21 部分):新订单系统 (IV) 从头开始开发智能交易系统(第 21 部分):新订单系统 (IV)
    最后,视觉系统将开始工作,尽管它尚未完工。 在此,我们将完成主要更改。 这只是它们当中很少一部份,但都是必要的。 嗯,整个工作将非常有趣。