CCIが+100以上なら上矢印、-100以下なら下矢印——その条件だけでインジケーターを作ると、

CCIが高いままの数本すべてに同じ矢印が並びます。

知りたいのは「閾値の外にいること」ではなく、「いま閾値を超えたこと」ではないでしょうか。

この記事では、CCIが+100を下から上へ、または-100を上から下へクロスした確定足だけに矢印を出すインジケーターを作ります。

同じ状態が続く間は再表示しません。

設計思想:状態ではなく変化を検知する

現在足だけを見た条件は次の通りです。

cci > 100

これではCCIが+100より上に5本滞在すると、5本すべてが条件を満たします。

クロスだけを検知するには、1本前との比較を加えます。

//下から+100を超えた
currentCCI > 100 && previousCCI <= 100

//上から-100を割った
currentCCI < -100 && previousCCI >= -100

また、形成中の0番足は値が変化します。

この記事のコードは1番以降の確定足を判定し、表示後に消えるシグナルを避けます。

iCCI関数の引数

double iCCI(
   string symbol,
   int    timeframe,
   int    period,
   int    applied_price,
   int    shift
);

CCIは終値だけでなく、標準的には高値・安値・終値の平均である`PRICE_TYPICAL`を使います。

`shift=1`は1本前の確定足です。

矢印インジケーターのコード全体

//+------------------------------------------------------------------+
//|                              CCICrossArrow.mq4                   |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LimeGreen
#property indicator_color2 Tomato

input int    CCIPeriod = 14;
input double Level     = 100.0;
input int    ArrowGap  = 20;//高値・安値から離すpoint数

double UpArrow[];
double DownArrow[];

int OnInit()
  {
   SetIndexBuffer(0,UpArrow);
   SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,1);
   SetIndexArrow(0,233);
   SetIndexEmptyValue(0,EMPTY_VALUE);

   SetIndexBuffer(1,DownArrow);
   SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,1);
   SetIndexArrow(1,234);
   SetIndexEmptyValue(1,EMPTY_VALUE);

   IndicatorShortName("CCI ±100 Cross Arrow");
   return(INIT_SUCCEEDED);
  }

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[])
  {
   if(rates_total < CCIPeriod+3)
      return(0);

   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);

   int limit=(prev_calculated==0) ? rates_total-2 : rates_total-prev_calculated+1;
   if(limit > rates_total-2)
      limit=rates_total-2;

   for(int i=limit;i>=1;i--)
     {
      UpArrow[i]=EMPTY_VALUE;
      DownArrow[i]=EMPTY_VALUE;

      double currentCCI = iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL,i);
      double previousCCI= iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL,i+1);

      if(currentCCI > Level && previousCCI <= Level)
         UpArrow[i]=low[i]-ArrowGap*Point;
      else if(currentCCI < -Level && previousCCI >= -Level)
         DownArrow[i]=high[i]+ArrowGap*Point;
     }

   //形成中の足には表示しない
   UpArrow[0]=EMPTY_VALUE;
   DownArrow[0]=EMPTY_VALUE;
   return(rates_total);
  }
Copy

MetaEditorでの実行手順

  1. MT4のMetaEditorで「新規作成」→「カスタムインディケータ」を選ぶ
  2. `CCICrossArrow`という名前で作成し、コード全体を置き換える
  3. F7でコンパイルし、エラー・警告が0件であることを確認する
  4. チャートへ適用し、MT4標準CCIも同時表示する
  5. 確定足で±100をクロスした位置と矢印が一致するか目視確認する

この矢印を売買サインと断定しない

CCIの+100超えは強い上昇、-100割れは強い下降を示す場面がありますが、

それだけで反転・継続のどちらかを保証しません。

逆張りなら過熱後の戻り、順張りならブレイク後の継続を別条件で確認する必要があります。

このインジケーターの役割は「CCIの状態変化を見落とさないこと」です。

EA化する場合は、上位足の方向、スプレッド、損切り、ポジション重複防止を追加してください。

矢印が出ない・多すぎるとき

  • 出ない:標準CCIの期間・適用価格が`CCIPeriod`・`PRICE_TYPICAL`と一致しているか
  • 多すぎる:Levelを低くしすぎていないか。100が一般的でも銘柄ごとの検証は必要
  • 位置が近すぎる:`ArrowGap`はpoint単位なので桁数に合わせて調整する
  • 最新足に出ない:意図的に確定足のみを判定している

まとめ

CCIの閾値通知では、`cci > 100`のような状態判定だけでなく、

前の足との比較でクロスを検知することが重要です。

この記事のコードは確定足だけを対象にし、±100の外側に滞在中は矢印を連発しません。

まず標準CCIと並べて表示を検証し、その後に利用目的に応じた方向・損切り条件を追加してください。

関連記事