iMAやiRSIのサンプルコードをそのまま真似て、

iCCIも`PRICE_CLOSE`を指定して使っていませんか。

実はCCI(商品チャネル指数)の教科書的な計算式は、

終値だけでなく高値・安値・終値の平均

(typical price)を使う設計になっています。

applied_priceにPRICE_CLOSEを指定しても

コンパイルエラーにはならず、それらしい値が返ってくるため、

多くの人がこのズレに気づかないまま使っています。

この記事では、iCCI関数のapplied_price引数の選び方と、

PRICE_CLOSEとPRICE_TYPICALで実際にどれだけ値が変わるのかを、

同じチャートに両方表示して見比べられるインジケーターで解説します。

CCI(商品チャネル指数)とは

CCIは、ドナルド・ランバートが考案したオシレーター系指標で、

価格が「その期間の平均からどれだけ乖離しているか」を数値化します。

教科書的な計算式は次の通りです。

典型価格(TP) = (高値 + 安値 + 終値) / 3
CCI = (TP - TPのSMA) / (0.015 × 平均偏差)

この式の主役は終値ではなく、

高値・安値・終値の平均である「典型価格(Typical Price)」です。

iCCI関数の書式

double iCCI(
   string symbol,        //通貨ペア(NULLで現在のチャート)
   int    timeframe,     //時間足(0で現在のチャートの時間足)
   int    period,        //CCIの計算期間(標準14)
   int    applied_price,  //計算に使う価格の種類
   int    shift           //何本前の足を見るか
   );

`iMA()`や`iRSI()`と形はほぼ同じですが、

`applied_price`に何を渡すかが実務上とても重要です。

applied_priceにPRICE_CLOSEを使うと何が起きるか

MT4の「挿入」→「インジケーター」から手動でチャートに追加した

標準のCCIインジケーターは、

内部で典型価格(PRICE_TYPICAL相当)を使って計算されています。

ところが`iCCI()`をプログラムから直接呼び出す場合、

`applied_price`は自分で明示的に指定する必要があります。

//教科書・標準CCIと一致する書き方
double cciTypical = iCCI(NULL,0,14,PRICE_TYPICAL,0);

//コンパイルは通るが、標準CCIとは違う値になる書き方
double cciClose = iCCI(NULL,0,14,PRICE_CLOSE,0);

`PRICE_CLOSE`を指定してもエラーは出ず、

CCIらしい形の数値が返ってくるため、

このズレに気づかないまま「なぜかチャート上の標準CCIと

数値が合わない」と悩むケースがよく起こります。

MT4標準のCCIと同じ挙動にしたいなら、

`PRICE_TYPICAL`を指定してください。

±100を超えても上限がない指標という点

CCIはRSIと違い、0〜100のような決まった範囲に収まりません。

理論上は青天井・底なしで、

±100という水準はあくまで「統計的に相場の大部分が収まる目安」

として使われている慣習的な基準です。

この閾値の設計や逆張りエントリーへの使い方は、

関連記事のCCI逆張りEAでさらに詳しく解説しています。

実際に動くコード全体(PRICE_TYPICALとPRICE_CLOSEを並べて表示)

同じ期間・同じ足で、applied_priceだけを変えたCCIを2本同時に計算し、

サブウィンドウに線として表示しつつ、

差分をComment()で数値表示する、

実際にMetaEditorでコンパイルできるインジケーターです。

//+------------------------------------------------------------------+
//|                                    CCIPriceCompare.mq4            |
//|                     Copyright 2026, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link      "https://creator.fx-ea-system-project.com/"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Red

input int CCIPeriod = 14;//CCIの計算期間

double CCITypical[];
double CCIClose[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0,CCITypical);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1);
   SetIndexLabel(0,"CCI(PRICE_TYPICAL)");

   SetIndexBuffer(1,CCIClose);
   SetIndexStyle(1,DRAW_LINE,STYLE_DOT,1);
   SetIndexLabel(1,"CCI(PRICE_CLOSE)");

   IndicatorShortName("CCI Price Compare");
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
   int limit=(prev_calculated==0) ? rates_total-1 : rates_total-prev_calculated+1;
   if(limit > rates_total-1)
      limit = rates_total-1;

   for(int i=limit;i>=0;i--)
     {
      CCITypical[i] = iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL,i);
      CCIClose[i]   = iCCI(NULL,0,CCIPeriod,PRICE_CLOSE,i);
     }

   double diff = CCITypical[1]-CCIClose[1];
   Comment(
      "CCI(PRICE_TYPICAL)= ", DoubleToString(CCITypical[1],2), "\n",
      "CCI(PRICE_CLOSE)  = ", DoubleToString(CCIClose[1],2), "\n",
      "差= ", DoubleToString(diff,2),
      "(標準CCIと一致させたい場合はPRICE_TYPICALを使ってください)"
     );

   return(rates_total);
  }
//+------------------------------------------------------------------+
Copy

MetaEditorで実際に動かす手順

  1. MT4の「ツール」→「MetaQuotes Language Editor」でMetaEditorを開く
  2. 「ファイル」→「新規作成」→「カスタムインディケータ」を選び、名前を「CCIPriceCompare」にして作成する
  3. テンプレートの中身をすべて削除し、上のコードを丸ごと貼り付ける
  4. F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
  5. チャートへ適用し、緑の実線(PRICE_TYPICAL)と赤の点線(PRICE_CLOSE)がどれだけズレるか、チャート左上のComment表示とあわせて確認する

コピペして動かない・意図と違うときに確認すること

  • MT4標準のCCIインジケーターと数値が合わない場合、`iCCI()`の`applied_price`に`PRICE_CLOSE`を指定していないか。`PRICE_TYPICAL`に変更する
  • 2本の線が完全に重なって見える場合、通貨ペアやボラティリティによっては差が小さく出ることもある。期間(`CCIPeriod`)を変えて差の出方を比較してみる
  • Comment表示が更新されない場合、他のインジケーター・スクリプトが同じチャートで`Comment()`を使っていないか確認する(後から実行された側の表示で上書きされる)

まとめ

`iCCI()`はiMAやiRSIと同じ形の関数ですが、

applied_priceに何を指定するかでCCIの意味そのものが変わります。

MT4標準のCCIインジケーターと同じ数値にしたい場合は、

必ず`PRICE_TYPICAL`を指定してください。

`PRICE_CLOSE`でもコンパイルは通るため、

このズレは実行してみるまで気づきにくい落とし穴です。

関連記事