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);
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MT4の「ツール」→「MetaQuotes Language Editor」でMetaEditorを開く
- 「ファイル」→「新規作成」→「カスタムインディケータ」を選び、名前を「CCIPriceCompare」にして作成する
- テンプレートの中身をすべて削除し、上のコードを丸ごと貼り付ける
- F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- チャートへ適用し、緑の実線(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`でもコンパイルは通るため、
このズレは実行してみるまで気づきにくい落とし穴です。
コメント