iACは、Bill Williamsが考案した、

Accelerator/Decelerator Oscillatorの値を、

MQL4で直接取得できる組み込み関数です。

既刊のテクニカルインジケーター関数一覧記事で名前だけは触れていましたが、

このサイトではまだiAC単独の解説記事がありませんでした。

この記事では、iACの引数と戻り値を整理したうえで、ゼロラインクロスと、

2本連続の色変化という本来の定義どおりのシグナルを検知する、

実際に動くインジケーターの作り方を解説します。

この記事で分かること
・iACの3つの引数と戻り値の意味
・既刊iAOとの計算対象の違い(AOの”差”とACの”差の変化”)
・ゼロラインクロスと2本連続色変化の2種類の検知方法
・実際に動くコード全体

設計思想: AOだけでは見えない「変化の速さ」

まず、ACが既刊iAOと何が違うのかを整理します。

既刊iAOとの計算対象の違い

既刊のiAO記事で解説したAOは、

高値・安値の中間値をもとにした、

5期間SMAと34期間SMAの差でした。

ACは、そのAOの値自体を5期間でさらに平均し、「AO – SMA(AO, 5)」

という引き算で求めます。

指標 何を計算するか 何を測るか
iAO(既刊) 短期SMAと長期SMAの差 短期と長期の勢いの差そのもの
iAC(本記事) AOと、AOの5期間SMAの差 その勢いの差が「加速しているか減速しているか」

AOが「今、勢いの差がどちらに傾いているか」を示すのに対し、

ACは「その傾きが強まっているか弱まっているか」を示す、

いわば勢いの変化そのものを測る指標です。

ゼロラインと色が示す意味

ACがゼロより上なら、AOの値が自身の平均より大きい、つまり勢いが加速している状態です。

ヒストグラムの色の意味
・前のバーより値が大きい:緑(勢いが加速している)
・前のバーより値が小さい:赤(勢いが減速している)
・2本連続で同じ色が続くことが、本来のBillWilliamsのシグナル定義

AOのように3本パターンの近似をしなくても、ACは「2本連続の色変化」

という定義そのままで実装できる点が特徴です。

iAC関数の引数と戻り値

公式リファレンス(MQL4 Reference: iAC)の内容を整理します。

3つの引数の意味

double iAC(
   string symbol,    // 通貨ペア名(NULLで現在のチャート)
   int    timeframe, // 時間足(0で現在の時間足)
   int    shift       // 何本前のバーの値を取得するか
);

iAOと同じく、ACも期間や価格種別を指定する引数が無く、

シンプルな引数構成になっています。

MQL5版との違い: 戻り値が直接の値かハンドルか

MQL4のiACは、値をdoubleで直接返します。

一方、MQL5のiAC(MQL5 Reference: iAC)は、

値ではなくインジケーターのハンドル(int)を返します。

MQL5移行時の注意
・MQL5のiACはハンドルを返すだけで、値そのものは返さない
・実際の値はCopyBuffer()で別途取得する必要がある
・引数もsymbolとperiodの2つだけに減っている(iAOと同じ減り方)

既刊のMQL4→MQL5移行チェックリストと同じ、

テクニカル指標のハンドル方式化という変化点が、

ここにも当てはまります。

サンプルインジケーター: 2種類のシグナルを検知する設計

ゼロラインクロスと、2本連続の色変化シグナルを、それぞれ別の矢印で表示します。

ゼロラインクロスの矢印表示

前のバーと現在のバーでゼロラインを挟んだ瞬間だけ、矢印バッファへ値をセットします。

加速・減速の傾向がゼロを境に反転したタイミングが一目で分かります。

2本連続色変化の判定ロジック

ゾーン(ゼロラインより上か下か)の中で、

直近2本のバーが同じ方向に連続して動いたときだけ、

シグナルを出します。

本記事でのシグナル定義
・プラスゾーンで2本連続上昇:買いシグナル(加速が強まっている)
・マイナスゾーンで2本連続下降:売りシグナル(減速が強まっている)
・ACの2本連続色変化そのものを見る、最も基本的な読み方

Bill Williamsの著書では、

AOのゾーンと組み合わせたより細かい売買ルールも紹介されていますが、

本記事ではAC単独で判断できる基本形に絞って実装しています。

実際に動くコード全体

実際にMetaEditorでコンパイルできる、

ACのヒストグラムと2種類のシグナル矢印を表示するインジケーターです。

//+------------------------------------------------------------------+
//|                                            ACSignalIndicator.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 3
#property indicator_color1 Lime
#property indicator_color2 DodgerBlue
#property indicator_color3 Magenta
#property indicator_width2 2
#property indicator_width3 2

double ACBuffer[];
double ZeroCrossArrow[];
double ColorChangeArrow[];

int OnInit()
  {
   SetIndexBuffer(0, ACBuffer);
   SetIndexStyle(0, DRAW_HISTOGRAM);

   SetIndexBuffer(1, ZeroCrossArrow);
   SetIndexStyle(1, DRAW_ARROW, EMPTY, 2);
   SetIndexArrow(1, 159);
   SetIndexEmptyValue(1, EMPTY_VALUE);

   SetIndexBuffer(2, ColorChangeArrow);
   SetIndexStyle(2, DRAW_ARROW, EMPTY, 2);
   SetIndexArrow(2, 108);
   SetIndexEmptyValue(2, EMPTY_VALUE);

   IndicatorShortName("AC Signal Detector");
   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[])
  {
   int needed = 45;
   if(rates_total < needed)
      return(0);

   int limit = (prev_calculated == 0) ? rates_total - needed : rates_total - prev_calculated + 1;

   for(int i = limit; i >= 0; i--)
     {
      ACBuffer[i] = iAC(NULL, 0, i);
      ZeroCrossArrow[i] = EMPTY_VALUE;
      ColorChangeArrow[i] = EMPTY_VALUE;

      if(i + 2 >= rates_total)
         continue;

      double cur   = ACBuffer[i];
      double prev1 = iAC(NULL, 0, i + 1);
      double prev2 = iAC(NULL, 0, i + 2);

      bool crossedUp   = (prev1 <= 0 && cur > 0);
      bool crossedDown = (prev1 >= 0 && cur < 0);
      if(crossedUp)
         ZeroCrossArrow[i] = cur - 0.0003;
      if(crossedDown)
         ZeroCrossArrow[i] = cur + 0.0003;

      bool risingTwice  = (cur > prev1 && prev1 > prev2);
      bool fallingTwice = (cur < prev1 && prev1 < prev2);

      if(cur > 0 && risingTwice)
         ColorChangeArrow[i] = cur - 0.0006;
      if(cur < 0 && fallingTwice)
         ColorChangeArrow[i] = cur + 0.0006;
     }

   return(rates_total);
  }

MetaEditorでのコンパイル・実行手順

実際にMT4で動かすまでの手順です。

  1. MetaEditorで新規インジケーター「ACSignalIndicator」を作成し、上のコードを貼り付けてコンパイルする
  2. エラー・警告が0件であることを確認する
  3. サブウィンドウにヒストグラムが表示されることを確認する
  4. ゼロラインを跨いだバーに青い矢印が出ることを確認する
  5. 同じゾーンで2本連続同方向に動いたバーにピンクの矢印が出ることを確認する

よくあるエラーと注意点

実装でつまずきやすいポイントをまとめます。

AOとACを混同する

名前も見た目のヒストグラムも似ていますが、AOは「勢いの差」

、ACは「その差の変化」という別の情報です。

既刊iAO記事と本記事を両方読んでから使い分けを決めてください。

ゾーンを無視して色変化だけで判断する

2本連続の色変化シグナルは、

プラスゾーンかマイナスゾーンかという前提を無視すると、

誤読につながります。

本記事のコードは、cur > 0またはcur < 0の条件を、

必ず確認している点に注意してください。

MQL5移植時にCopyBufferを忘れる

前述のとおり、MQL5版は値ではなくハンドルを返すため、

iAC()の戻り値をそのままdoubleとして使おうとすると、

コンパイルエラーになります。

既刊のオシレーター系記事との使い分け

似た目的の記事が複数あるため、使い分けを整理します。

記事 何を測るか 用途
本記事(iAC) AOの変化(加速・減速) 勢いの転換が強まっているかを検知
iAO記事(既刊) 短期と長期の勢いの差 勢いの方向そのものを検知
iOsMA記事(既刊) MACDのメイン・シグナル差 終値ベースのトレンド転換検知

よくある質問

iACについて、よくある疑問に回答します。

ACとAO、どちらを優先して見るべきですか?

目的によって使い分けます。

勢いの方向を知りたいならAO、

勢いの変化の速さ(強まっているか弱まっているか)を知りたいなら、

ACが向いています。

両方を併用し、AOの方向とACの変化が一致したときだけを採用する、

という使い方もよく紹介されます。

このインジケーターをEAのフィルターに使えますか?

使えます。

2本連続色変化の判定部分だけを関数化すれば、

既刊のクロス判定EA群と同じ要領で、

エントリー条件に組み込めます。

AOとACを両方表示することはできますか?

できます。

本記事のインジケーターとは別にAOインジケーターをチャートに追加すれば、

同時に表示して見比えることができます(サブウィンドウが2つになります)。

【MQL4】iAC(Accelerator/Decelerator Oscillator)で勢いの「加速・減速」を検知するインジケーターの作り方:まとめ

iACは、既刊iAOの値をさらに5期間で平均し、

その差分を取ることで「勢いの変化の速さ」を測る関数です。

ゼロラインクロスと2本連続の色変化という、

2つの基本的なシグナルで、加速・減速の転換を検知できます。

MQL5では戻り値がハンドルに変わる点に注意し、

CopyBuffer()での値取得とセットで覚えておくと移行時の事故を防げます。

関連記事