iAOは、Bill Williamsが考案したAwesome Oscillatorの値を、

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

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

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

この記事では、iAOの引数と戻り値を整理したうえで、

ゼロラインクロスと簡易版の「ソーサー」シグナルを検知する、

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

この記事で分かること
・iAOの3つの引数と戻り値の意味
・既刊iOsMA・既刊iForceとの計算対象の違い
・ゼロラインクロスと簡易ソーサーの2種類の検知方法
・実際に動くコード全体

設計思想: なぜAOを単独で見る必要があるか

まず、AOが既刊のオシレーター系指標と何が違うのかを整理します。

既刊iOsMA・既刊iForceとの計算対象の違い

AOは、(高値+安値)÷2の「中間値」を使い、

5期間の移動平均から34期間の移動平均を引いた値です。

指標 使う値 何を測るか
iOsMA(既刊) 終値ベースのMACD メインラインとシグナルラインの差
iForce(既刊) 価格変化×出来高 値動きの勢い(出来高込み)
iAO(本記事) 高値・安値の中間値 短期と長期の勢いの差

数式も参照する価格もそれぞれ別物であり、

似たヒストグラム形状でも計算の出発点が違います。

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

AOがゼロより上なら、

短期の勢いが長期の勢いを上回っている状態です。

ヒストグラムの色の意味
・前のバーより値が大きい: 緑(上昇方向の勢い)
・前のバーより値が小さい: 赤(下降方向の勢い)
・色の変化そのものが短期的な勢いの転換を示す

色の変化とゼロラインの位置、

この2つを組み合わせて判断するのがAOの基本です。

iAO関数の引数と戻り値

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

3つの引数の意味

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

iForceやiOsMAと比べても、

AOは期間や価格種別を指定する引数が無く、

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

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

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

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

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

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

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

テクニカル指標のハンドル方式化という変化点がここにも当てはまります。

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

ゼロラインクロスと、簡易版のソーサーシグナルを、

それぞれ別の矢印で表示します。

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

前のバーと現在のバーでゼロラインを挟んだ瞬間だけ、

矢印バッファへ値をセットします。

簡易ソーサーシグナルの判定ロジック

本来のソーサーシグナルは、

ゼロラインより上で「下降→上昇→上昇」と3本の形状が変化する、

やや複雑なパターン判定です。

本記事での簡略化
・厳密な3本パターンではなく、2本連続の色の変化で判定する簡易版
・本来の定義より検知頻度は高くなる(誤検知が増える)
・精度を求める場合は値の並び自体も目視で確認することをおすすめする

この限界を開示したうえで、

初心者でも読みやすいシンプルなロジックとして実装します。

実際に動くコード全体

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

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

//+------------------------------------------------------------------+
//|                                            AOSignalIndicator.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 AOBuffer[];
double ZeroCrossArrow[];
double SaucerArrow[];

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

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

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

   IndicatorShortName("AO 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 = 40;
   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--)
     {
      AOBuffer[i] = iAO(NULL, 0, i);
      ZeroCrossArrow[i] = EMPTY_VALUE;
      SaucerArrow[i] = EMPTY_VALUE;

      if(i + 1 >= rates_total)
         continue;

      double curAO  = AOBuffer[i];
      double prevAO = iAO(NULL, 0, i + 1);

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

      if(i + 2 < rates_total)
        {
         double prevAO2 = iAO(NULL, 0, i + 2);
         bool risingTwice  = (curAO > prevAO && prevAO > prevAO2);
         bool fallingTwice = (curAO < prevAO && prevAO < prevAO2);
         if(curAO > 0 && risingTwice)
            SaucerArrow[i] = curAO - 0.0006;
         if(curAO < 0 && fallingTwice)
            SaucerArrow[i] = curAO + 0.0006;
        }
     }

   return(rates_total);
  }

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

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

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

よくあるエラーと注意点

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

ヒストグラムの色設定を忘れる

DRAW_HISTOGRAMは1本のバッファだけでは、

上昇・下降で色を分けられません。

本記事では簡略化のため単色にしていますが、

色分けしたい場合はバッファを2本に分ける必要があります。

簡易ソーサー判定による誤検知

前述のとおり、本記事のソーサー判定は2本連続の変化だけを見ています。

本来の3本パターンより検知頻度が高くなる点に注意してください。

MQL5移植時にCopyBufferを忘れる

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

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

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

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

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

記事 使う値 用途
本記事(iAO) 高値・安値の中間値 短期と長期の勢いの差を検知
iOsMA記事(既刊) MACDのメイン・シグナル差 終値ベースのトレンド転換検知
iForce記事(既刊) 価格変化×出来高 出来高込みの勢いのゼロクロス検知

よくある質問

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

AOとMACDは同じものですか?

似ていますが別物です。

AOは高値・安値の中間値を使い、

MACDは終値を使う点が計算の出発点から異なります。

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

使えます。

ゼロラインクロスの判定部分だけを関数化すれば、

既刊のクロス判定EA群と同じ要領でエントリー条件に組み込めます。

本来のソーサーシグナルはどこで確認できますか?

本記事は簡易版のため、

精度を求める場合はMQL5公式リファレンスや、

Bill Williamsの著書で紹介されている3本パターンの定義を確認してください。

【MQL4】iAO(Awesome Oscillator)のゼロラインクロスと「ソーサー」シグナルを検知するインジケーターの作り方:まとめ

iAOは、既刊iOsMA・既刊iForceとは違い、

高値・安値の中間値をもとに短期と長期の勢いの差を測る関数です。

ゼロラインクロスと簡易版のソーサーシグナルを組み合わせることで、

勢いの転換を2つの角度から検知できます。

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

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

関連記事