MT4で「トレンドが出ているかどうか」を判定したくて`iADX()`のリファレンスを調べても、

公式ドキュメントには`MODE_MAIN`・`MODE_PLUSDI`・`MODE_MINUSDI`という3つの定数が並んでいるだけで、

「結局どれを使えば方向まで分かるのか」がすぐには分かりません。

ADXという指標名から「上か下かを教えてくれる指標」だと誤解したまま実装してしまう人も少なくありません。

この記事では、`iADX()`関数の3つのバッファ(MODE_MAIN/MODE_PLUSDI/MODE_MINUSDI)がそれぞれ何を表すのか、

パラメーターとshift引数の意味、そして「ADX主線だけではトレンドの方向は分からない」

という実務上の落とし穴を、実際にMetaEditorでコンパイルできるサンプルコードとあわせて解説します。

なお、ADXの生数値を「レンジ/様子見/強いトレンド」のような日本語ラベルに変換して表示する応用インジケーターは別記事([ADXの数値をそのまま見ていませんか?](https://creator.fx-ea-system-project.com/mt4-indicator/adx-strength-indicator/))で扱っています。

この記事は状態変換の一歩手前、`iADX()`という関数そのものの使い方に絞って解説します。

ADXは「強さ」しか表さない指標

ADX(Average Directional Movement Index、

平均方向性指数)は、J.ウェルズ・ワイルダーが考案したトレンド系指標で、

「トレンドがどれだけ強く出ているか」を0〜100の数値で表します。

ここで見落とされがちなのが、ADXの主線(ADX Main Line)は上昇トレンドと下降トレンドを区別しないという点です。

ADX主線が同じ40という数値でも、それが強い上昇トレンドなのか強い下降トレンドなのかは、

主線の値だけでは判断できません。

方向を判定するには、ADXと同時に計算される+DI(Plus Directional Indicator、

上昇方向の勢い)と-DI(Minus Directional Indicator、

下降方向の勢い)という別の2本の値が必要です。

MT4では、この3つの値(ADX主線・+DI・-DI)をすべて`iADX()`という1つの関数から、

mode引数を変えて取得します。

iADX関数の書式

double iADX(
   string symbol,        //通貨ペア(NULLで現在のチャート)
   int    timeframe,     //時間足(0で現在のチャートの時間足)
   int    period,        //ADXの計算期間(標準14)
   int    applied_price, //価格の種類(通常PRICE_CLOSE)
   int    mode,          //取得するバッファの種類
   int    shift          //何本前の足を見るか(0=最新、1=1つ前の確定足)
   );

`iMA()`や`iATR()`と同じ「symbol, timeframe, …パラメーター…, shift」

という並びですが、`applied_price`(計算に使う価格の種類)と`mode`(3つのバッファのどれを取得するか)という2つの引数が挟まる点が異なります。

`applied_price`は通常`PRICE_CLOSE`を指定します(ADXの計算方法上、

他の価格種別を指定しても計算式は高値・安値・終値を内部で使うため、

実務上はPRICE_CLOSE固定で問題ありません)。

mode引数で3つのバッファを使い分ける

mode引数には、以下のいずれかの定数を指定します。

  • MODE_MAIN(値は0) — ADX主線(トレンドの「強さ」。方向は表さない)
  • MODE_PLUSDI(値は1) — +DI(上昇方向の勢い)
  • MODE_MINUSDI(値は2) — -DI(下降方向の勢い)

3つとも同じ`period`・`applied_price`で計算されますが、

呼び出しはmode引数を変えて3回行う必要があります。

double adx    = iADX(NULL, 0, 14, PRICE_CLOSE, MODE_MAIN, 1);    //ADX主線
double plusDI = iADX(NULL, 0, 14, PRICE_CLOSE, MODE_PLUSDI, 1);  //+DI
double minusDI= iADX(NULL, 0, 14, PRICE_CLOSE, MODE_MINUSDI, 1); //-DI

`iIchimoku()`が5本の線を1つの関数のmode引数で使い分ける設計だったのと同じ考え方です。

「ADXという名前の指標なのに、なぜ+DI/-DIまで同じ関数から取得するのか」

と疑問に思うかもしれませんが、これはADX自体の計算過程で+DI/-DIを内部的に使っているため、

MT4側もこの3つをセットの指標として扱っているからです。

shift引数の考え方

`shift`は`iMA()`や`iATR()`と同じく「何本前の確定足を見るか」

を指定します。

`shift=0`は形成中の足(まだ確定していない最新の値)を返すため、

値がティックのたびに変化します。

EAやインジケーターの判定に使う場合は、`shift=1`(直近に確定した1本前の足)を指定するのが安全です。

実務上の注意点: ADX単体では方向が分からない

ここが最も誤解されやすいポイントです。

「ADXが25を超えたらトレンド発生」という基準だけでエントリー判定を組むと、

上昇トレンドでも下降トレンドでも同じように「トレンド発生」と判定されてしまいます。

ADX主線(MODE_MAIN)は「強さ」の指標であり、「方向」の指標ではないためです。

方向まで判定したい場合は、+DIと-DIの大小関係を見る必要があります。

+DIが-DIを上回っていれば上昇方向の勢いが強く、逆であれば下降方向の勢いが強いと判断できます。

mql-coverage-gap.mdの備考にもある通り、この「ADXで強さを絞り込み、

他の指標で方向を確認する」という使い方は、パーフェクトオーダー系のエントリー条件(移動平均線の並び順で方向を判定するEA)と特に相性が良いという指摘があります。

ADXだけでエントリーの可否を決めるのではなく、「ADXが閾値を超えている(=トレンドが強い)ときだけ、

パーフェクトオーダー等の方向判定ロジックを有効にする」というフィルターとしての使い方が実務的です。

実際に動くコード全体

ここまでの内容をまとめた、ADX主線と+DI/-DIの3つの値をチャート左上に表示する、

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

強さ(ADX)と方向(+DI/-DIの大小関係)を別々の行で表示し、

両者が独立した情報であることが分かるようにしています。

//+------------------------------------------------------------------+
//|                                                  iADXValues.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_chart_window
#property indicator_buffers 0

input int ADXPeriod = 14;//ADXの計算期間
//このインジケーターはチャートに線を描かず、値をComment()で表示するだけなので、
//バッファ0個で問題ありません(線を描く場合は1以上が必要です)。

//+------------------------------------------------------------------+
//| 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[])
  {
   double adx     = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
   double plusDI  = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, 1);
   double minusDI = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, 1);

   string direction = "方向感なし";
   if(plusDI > minusDI)
      direction = "▲上昇方向の勢いが優勢";
   else if(minusDI > plusDI)
      direction = "▼下降方向の勢いが優勢";

   Comment(
      "[強さ] ADX(", ADXPeriod, ")= ", DoubleToString(adx, 1), "\n",
      "[方向] +DI= ", DoubleToString(plusDI, 1), " / -DI= ", DoubleToString(minusDI, 1), "\n",
      "判定: ", direction, "\n",
      "(ADX主線はあくまで「強さ」であり、方向の判定には+DI/-DIの比較が必要です)"
     );

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

MetaEditorで実際に動かす手順

  1. MT4の「ツール」→「MetaQuotes Language Editor」でMetaEditorを開く
  2. 「ファイル」→「新規作成」→「インジケーター」を選び、名前を「iADXValues」にして作成する(中身は空のテンプレートで構いません)
  3. テンプレートの中身を全て削除し、上のコードを丸ごと貼り付ける
  4. F7キー(またはコンパイルボタン)でコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
  5. MT4の「ナビゲーター」パネルからインジケーターを探し、チャートへドラッグ&ドロップする
  6. チャート左上に「[強さ] ADX(14)= 27.3」「[方向] +DI= 24.1 / -DI= 15.8」のような表示が出れば成功です

コピペしてコンパイルが通らないときに確認すること

  • 拡張子が「.mq4」になっているか
  • mode引数の定数名(MODE_MAIN・MODE_PLUSDI・MODE_MINUSDI)のスペルミスがないか(1文字でも違うと未定義識別子としてコンパイルエラーになります)
  • ADXの値が常に0で表示される場合、チャートを開いた直後で`ADXPeriod`分の過去データがまだ読み込まれていない可能性があります。しばらく待つか、通貨ペアの履歴データをダウンロードし直してください

まとめ

`iADX()`は1つの関数をmode引数(MODE_MAIN/MODE_PLUSDI/MODE_MINUSDI)で使い分けることで、

ADX主線と+DI/-DIの3つの値を取得できます。

最も注意すべき点は、ADX主線が表すのは「トレンドの強さ」だけであり、

「方向」は+DI/-DIの大小関係を別途比較しないと分からないということです。

今回のコードで取得した3つの値は、そのままADXが一定値以上のときだけ他のロジック(パーフェクトオーダー等)を有効にするフィルター条件として、

EA側に組み込めます。

ADXの値を状態ラベルに変換して表示するインジケーターの作り方は、

関連記事のADX応用編で扱っています。

関連記事