CCI 指标。 升级和新特征·进阶篇
📘

CCI 指标。 升级和新特征·进阶篇

第 2/2 篇

三种CCI算法在EURUSD上的实盘回测差异

经典 CCI 用样本均值加减绝对偏差均值来定边界,正常计算下时间序列的极值会戳出均值±偏差;而强健估算里原始序列所有值都收在边界内。光看公式差异不够直观,得拉到真实报价上跑。 我们把三种算法(经典、标准差版、强健版)各写成独立指标,核心变量就两个:应用的价格常量(MT5 里在指标属性设 PRICE_TYPICAL)和周期。周期至少得 3,小于此值容易算出过陡峭的失真值。 为避开肉眼对比的主观性,写了个极简 EA:新柱开盘算指标值,上穿负级别开多平空,下穿正级别开空平多。测试固定为 EURUSD、H1、2021 全年、周期 14、典型价、级别 150(对应经典 CCI 的 100 线)。 回测结果有清晰分界:标准差版交易次数减少,大额亏损随之减少;强健版进一步增加交易次数,且大幅亏损次数继续下降,这是该版本最实用的优势。外汇与贵金属属高风险品种,上述规律仅基于历史数据,未来走势可能偏离。 无论哪种版本,这套开平仓规则都还很粗糙,直接上实盘大概率要栽,必须重做过滤条件。

MQL5 / C++
class="macro">#class="kw">property indicator_applied_price PRICE_TYPICAL
class="kw">input class="type">class="kw">ushort iPeriod=class="num">14;class=class="str">"cmt">//indicator period
class="type">class="kw">double mean=class="num">0;                class=class="str">"cmt">//sample mean
for(class="type">int j=class="num">0; j<iPeriod; j++)
  {
    mean=mean+price[i+j];      class=class="str">"cmt">//sum up price values
  }
mean=mean/iPeriod;            class=class="str">"cmt">//sample mean for the period
class="type">class="kw">double mad=class="num">0;                          class=class="str">"cmt">//mean absolute deviation
for(class="type">int j=class="num">0; j<iPeriod; j++)
  {
    mad=mad+MathAbs(price[i+j]-mean);  class=class="str">"cmt">//sum up absolute difference values
  }
res=(price[i]-mean)*iPeriod/mad;
class="type">class="kw">double sumS=class="num">0,class=class="str">"cmt">//sum of prices
       sumQ=class="num">0;class=class="str">"cmt">//sum of price squares
for(class="type">int j=class="num">0; j<iPeriod; j++)
{
   sumS=sumS+price[i+j];
   sumQ=sumQ+price[i+j]*price[i+j];
}
class="type">class="kw">double denom=MathSqrt(iPeriod*sumQ-sumS*sumS);
res=(iPeriod*price[i]-sumS)/denom;
class="type">class="kw">double halfsums[],diff[];
class="type">int size=iPeriod*(iPeriod-class="num">1)/class="num">2; class=class="str">"cmt">//halfsums array size
ArrayResize(halfsums,size);     class=class="str">"cmt">//set the array size
indx10=size/class="num">2;
indx11=indx10;
if(MathMod(size,class="num">2)==class="num">0)
   indx11=indx10-class="num">1;
ArrayResize(diff,iPeriod);
indx20=iPeriod/class="num">2;
indx21=indx20;
if(MathMod(iPeriod,class="num">2)==class="num">0)
   indx21=indx20-class="num">1;
class="type">int cnt=class="num">0; class=class="str">"cmt">//counter of array elements
for(class="type">int j=iPeriod-class="num">2; j>=class="num">0; j--)
  {
    for(class="type">int k=iPeriod-class="num">1; k>j; k--)
      {
        halfsums[cnt]=(price[i+j]+price[i+k])/class="num">2; class=class="str">"cmt">//half sum value
        cnt++;                                   class=class="str">"cmt">//increase the counter
      }
  }
ArraySort(halfsums);                                            class=class="str">"cmt">//sort the array
class="type">class="kw">double mean=(halfsums[indx10]+halfsums[indx11])/class="num">2; class=class="str">"cmt">//robust mean

◍ 用绝对偏差中位数替代标准差

这段循环把最近 iPeriod 根 K 线的价格与均值之差取绝对值,塞进 diff 数组,目的是绕开经典标准差对异常值的过度敏感。 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; 排序后取第 20、21 个元素的均值作为稳健标准差,相当于用中间段绝对偏差代表离散度,样本量够大时比直接算方差更抗毛刺。 res 即标准化后的偏离度,外汇与贵金属波动常带跳空,用这套稳健量纲做 z-score 阈值,比普通 STD 更不容易被单根极端 K 线骗到,但杠杆品种高风险仍在,参数 iPeriod 与 indx20/21 需在 MT5 里按品种复盘调。

MQL5 / C++
for(class="type">int j=class="num">0; j<iPeriod; j++)
{
  diff[j]=MathAbs(price[i+j]-mean);
}
ArraySort(diff);
class="type">class="kw">double sd=(diff[indx20]+diff[indx21])/class="num">2; class=class="str">"cmt">//robust standard deviation
res=(price[i]-mean)/sd;

「给 CCI 加一个累计求和的改法」

CCI 指标原生就能取正值和负值,正区对应上升段,负区对应下降段。原版只看瞬时穿越,容易在震荡里反复挨耳光。 思路是把 CCI 从趋势起点到终点的值做累加,再和均值比,用来判断这段趋势走了多久、力度够不够。实现上用稳健估算版本打底,唯一改动是:只在 CCI 上穿零轴后才开始累加,输出这个累计额。 上升和下降的累计均值分开算,方便直接对照。图上看,曲线长时间贴着均值上沿跑,说明多头趋势在持续放量;跌破自身均值线,往往就是一段趋势进入尾声的信号。 基于这个改版指标,最简策略是:当累计额从高位回落并下穿平均级别,且原趋势强度高于均值时,价格朝反方向修正的概率偏高。外汇和贵金属波动杠杆大,这种反转只是概率倾向,必须配合止损。

画得少,看得清

把 CCI 拆成三套实现再比对,价值不在指标本身,而在验证「没有哪个版本是终局」。mCCI 给出三种 CCI 写法,EA_CCI 用 7.46 KB 的 MQ5 把不同版本丢进同一逻辑跑差异,tCCI 则另算累计趋势量——三者同附在文末压缩包,MT5 里直接编译就能复现。 真正能落地的动作很简单:下载那三个 .mq5,把 EA_CCI 里的 CCI 源切换成 mCCI 的三种模式各跑一周回测,看哪版在黄金 1 小时图上的假信号更少。外汇与贵金属杠杆高,回测优不代表实盘稳,结论只作概率参考。 指标永远留着被改的余地,与其追新,不如把手上这套改到顺手。

常见问题

实盘回测显示中位数绝对偏差版在EURUSD异常波动段假信号更少,可替换原标准差计算验证。
累计求和改法建议周期固定在20,并在横盘段人工屏蔽信号,避免数值无限累积。
小布可加载多种CCI变体做并排诊断,直接输出各算法在指定品种的回测差异供你决策。
叠加三种算法线易混乱,只留中位数偏差版主图、其余放副图,能明显减少误读。
贵金属跳空频繁,该改法仍可能滞后,须结合止损并认定其为概率信号而非确定性。