最終更新: 2026年6月
DMIとADXは、ひとつのインジケーターに異なる情報が統合された複合指標だ。+DI・−DI・ADXの3本のラインを正しく読み取ることで、「相場にトレンドがあるか」と「そのトレンドはどちら向きか」を同時に確認できる。
筆者がEA開発の現場でADXフィルターを初めて実装したのは5年ほど前のことだが、当時「なぜADX25を閾値にするのか」を定量的に理解せずに使っていた。その後バックテストで統計的に検証してみると、ADX25前後を境にトレンドフォロー系戦略の勝率分布が明確に変化することが確認できた。
この記事では、MQL5での実装コードを中心に、ADXフィルターの理論的背景と実装上のトレードオフを解説する。
Claudeと会話しながらインジケータが作れるhedgrow.ioはこちら
DMI・ADXとは何か——3本のラインが示すもの
DMI(Directional Movement Index)は1978年にJ.W.ワイルダーが発表した指標体系だ。構成要素は3つある。
+DI(Plus Directional Indicator):上昇方向への動きの強さを0〜100で表す。 −DI(Minus Directional Indicator):下降方向への動きの強さを0〜100で表す。 ADX(Average Directional Movement Index):+DIと−DIから計算されるトレンド強度指標。方向は問わず、数値が大きいほど強いトレンド。
重要なのはADXが「方向を持たない」点だ。上昇トレンドでも下降トレンドでもADXは上昇する。方向の判定は+DIと−DIの大小関係で行う。
ADX数値の読み方
| ADX水準 | 相場の状態 |
|---|---|
| 0〜20未満 | トレンドなし(レンジ) |
| 20〜25 | 弱いトレンドの萌芽 |
| 25〜40 | 明確なトレンド(トレンドフォロー有効) |
| 40〜60 | 強いトレンド |
| 60以上 | 極めて強いトレンド(過熱感に注意) |
ADX=25というラインはワイルダー自身が「トレンドの存在を確認するための最低基準」として設定した数値だ。多くのトレーダーがこの閾値を参照しているため、自己実現的な側面もある。
MQL5でのiADX実装——4ステップの実装手順
MQL5でDMI/ADXの値を取得するにはiADX関数を使う。実装は4つのステップで構成される。
Step 1: グローバル変数とハンドル宣言
input int ADXPeriod = 14; // ADX期間(デフォルト14)
input double ADXThreshold = 25.0; // フィルター閾値
int ADXHandle;
Step 2: OnInit()でハンドル取得
int OnInit()
{
ADXHandle = iADX(_Symbol, _Period, ADXPeriod);
if(ADXHandle == INVALID_HANDLE)
{
Print("ADXハンドル取得失敗");
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
Step 3: 3つの配列でバッファを受け取る
double mainLineArray[]; // ADXメインライン
double plusDIArray[]; // +DI
double minusDIArray[]; // -DI
ArraySetAsSeries(mainLineArray, true);
ArraySetAsSeries(plusDIArray, true);
ArraySetAsSeries(minusDIArray, true);
Step 4: CopyBufferで値を取得してフィルター判定
bool IsTrendValid()
{
if(CopyBuffer(ADXHandle, 0, 0, 3, mainLineArray) < 3) return false;
if(CopyBuffer(ADXHandle, 1, 0, 3, plusDIArray) < 3) return false;
if(CopyBuffer(ADXHandle, 2, 0, 3, minusDIArray) < 3) return false;
double adx = NormalizeDouble(mainLineArray[0], 2);
double plusDI = NormalizeDouble(plusDIArray[0], 2);
double minusDI = NormalizeDouble(minusDIArray[0], 2);
// ADXが閾値以上かつ方向性が明確な場合のみtrue
return (adx >= ADXThreshold);
}
bool IsBuySignal()
{
return IsTrendValid() && (plusDIArray[0] > minusDIArray[0]);
}
bool IsSellSignal()
{
return IsTrendValid() && (minusDIArray[0] > plusDIArray[0]);
}
CopyBufferの第3引数(バッファインデックス)は、0がADXメインライン、1が+DI、2が−DIに対応する。これはMT5のビルトイン仕様であり、MQL4のiADX()関数とは引数構造が異なる点に注意が必要だ。
ADXフィルター設計の4つのパターン
ADXフィルターには複数の設計パターンがある。それぞれのトレードオフを把握してから選択すべきだ。
パターン1: 単純ADX閾値フィルター
// ADXが25以上のときのみエントリーを許可
if(adx >= 25.0 && plusDI > minusDI) { /* 買いエントリー */ }
最も単純で解釈しやすい。ただし、ADXが25を超えた瞬間にエントリーすると、すでにトレンドの中盤以降になっているケースがある。
パターン2: ADX上昇確認フィルター(モメンタム確認)
// ADXが閾値以上かつ前足より上昇中のみ
bool isADXRising = (mainLineArray[0] > mainLineArray[1]);
if(adx >= 25.0 && isADXRising && plusDI > minusDI) { /* 買い */ }
トレンド発生の初期段階を狙う場合に有効だ。ADXが上向きに転換し始めたタイミングを捉えられる。
パターン3: +DI/-DIクロス + ADX確認
// +DIが-DIをクロスアップし、かつADX>20
bool dmiCrossUp = (plusDIArray[1] < minusDIArray[1]) &&
(plusDIArray[0] > minusDIArray[0]);
if(dmiCrossUp && adx >= 20.0) { /* 買い */ }
クロスを方向転換のシグナルとして使い、ADXで信頼性を確認する。レンジ相場でのダマシが多いため、ADXの下限を下げることでシグナル数を増やしやすい。
パターン4: マルチタイムフレームADXフィルター
// 上位足のADXが25以上の場合のみ、下位足でエントリー
int ADXHandleH4 = iADX(_Symbol, PERIOD_H4, 14);
double h4ADX[];
CopyBuffer(ADXHandleH4, 0, 0, 3, h4ADX);
if(h4ADX[0] >= 25.0 && currentTimeframeSignal) { /* エントリー */ }
上位足でトレンドの存在を確認してから下位足でタイミングを計る。筆者がバックテストで確認した範囲では、H4 ADX≥25を条件に追加すると、M30でのエントリーシグナルの精度が向上する傾向があった(ただしシグナル数は大幅に減少する)。
複数パターンを組み合わせる際の設計指針——3層フィルター構造とADX上限設定
上記4パターンは単体でも機能するが、実運用では「3層のフィルター」として重ねる設計にすると、各レイヤーが独立した情報を分担し、フィルターの重複(同じ情報を二重に確認する冗長設計)を避けられる。
Layer 1: トレンドの「存在」確認(パターン1相当。ADXが閾値以上か) Layer 2: トレンドの「方向」確認(パターン3相当。+DIと−DIの大小関係) Layer 3: エントリーの「タイミング」確認(具体的なトリガー)
Layer 3には、RSIが50ラインをクロスしたタイミングをエントリートリガーに使う設計が実装しやすい。
// Layer 3の例: RSIが50ラインを上抜けたタイミングをトリガーにする
int RSIHandle = iRSI(_Symbol, _Period, 14, PRICE_CLOSE);
double rsiArray[];
ArraySetAsSeries(rsiArray, true);
CopyBuffer(RSIHandle, 0, 0, 3, rsiArray);
bool rsiCrossUp50 = (rsiArray[1] <= 50.0 && rsiArray[0] > 50.0);
// Layer1(トレンド存在) + Layer2(方向) + Layer3(タイミング)が揃った場合のみエントリー
if(IsTrendValid() && plusDIArray[0] > minusDIArray[0] && rsiCrossUp50)
{
// 買いエントリー処理
}
また、ADXフィルターには下限(トレンド存在の確認)だけでなく上限も設定しておくとよい。「MQL5でのiADX実装」で示したIsTrendValid()に、ADX上限のチェックを1行加えるだけで実装できる。
input double ADXMaxLevel = 60.0; // 過熱相場の除外閾値
bool IsTrendValid()
{
if(CopyBuffer(ADXHandle, 0, 0, 3, mainLineArray) < 3) return false;
if(CopyBuffer(ADXHandle, 1, 0, 3, plusDIArray) < 3) return false;
if(CopyBuffer(ADXHandle, 2, 0, 3, minusDIArray) < 3) return false;
double adx = NormalizeDouble(mainLineArray[0], 2);
// ADXThreshold以上ADXMaxLevel以下の範囲のみ有効
return (adx >= ADXThreshold && adx <= ADXMaxLevel);
}
ADXが60〜80以上に達する局面では、トレンドがすでに終盤に差し掛かっており、逆張りが有効になるケースもある。下限だけのフィルターでは、この過熱局面でエントリーして「トレンドの末期に飛び乗って損失を出す」パターンを避けられない。上限を設定することで、この失敗パターンを回避しやすくなる。
バックテストで見えるADXフィルターの効果
ADXフィルターの効果を定量的に把握するためには、フィルターありとなしの両条件でバックテストを比較する必要がある。
一般的な傾向(複数の検証レポートから):
| 条件 | トレード数 | 勝率 | プロフィットファクター |
|---|---|---|---|
| ADXフィルターなし | 多い | 50〜55% | 1.0〜1.3 |
| ADX≥25フィルターあり | 減少(30〜60%減) | 55〜65% | 1.3〜1.8 |
トレード数が減る分、1トレードあたりの期待値が上昇するケースが多い。ただしこれは戦略・通貨ペア・時間足によって大きく異なる。自分の戦略に対して実際に検証することが不可欠だ。
Claudeと会話しながらインジケータが作れるhedgrow.ioはこちら
注意点——ADXフィルターが機能しにくいケース
ADXフィルターが万能でないことも理解しておくべきだ。
横ばい後の急騰・急落初期: ADXは遅行性があり、トレンドが発生してからADX数値が追いつくまでにタイムラグがある。急騰の最初のN本は「ADX<25」の状態でのエントリー機会を逃す。
ニュース・経済指標直後: 短期的な価格のスパイクでADXが上昇するが、その後すぐに反転することが多い。この局面でのADX信号は信頼性が低い。
通貨ペアの特性差: AUD/JPYのようなボラティリティが高い通貨ペアと、EUR/CHFのような低ボラティリティペアでは、同じADX=25でも相場の状態が異なる。閾値のキャリブレーションが必要になる場合がある。
実装チェックリスト
ADXフィルターをEAに組み込む前の確認事項:
- OnDeinit()でIndicatorRelease(ADXHandle)を呼んでハンドルを解放しているか
- CopyBufferの戻り値チェック(失敗時はエントリーをスキップ)を実装しているか
- フィルターあり・なしの両条件でバックテスト比較を実施したか
- ADX閾値をinputパラメータ化して最適化可能にしているか
- 上位足ADXとの組み合わせ(マルチタイムフレーム)を検討したか
あわせてSuperTrend FXとは——MT5設定・パラメータ最適化・EA実装も参照すると理解が深まる。
よくある質問(FAQ)
Q: ADXの期間はデフォルトの14から変える必要がありますか? A: 多くのトレーダーが14を使用しているためシグナルが機能しやすい面があります。スキャルピングでは7〜10、スイングでは20〜25に調整することもあります。変更する場合はフォワードテストで効果を確認してください。
Q: +DIと-DIのクロスだけでエントリーしても機能しますか? A: クロスシグナル単独ではレンジ相場でのダマシが多く発生します。ADX≥20以上を組み合わせることでシグナルの信頼性が向上します。バックテストで比較検証することを推奨します。
Q: MQL4とMQL5でiADXの使い方は違いますか? A: はい、構造が異なります。MQL4ではiADX()関数が直接値を返しますが、MQL5ではハンドルを取得してからCopyBufferで値を取り出す設計になっています。MQL5の方がリソース管理が明示的で、複数インジケーターを扱う大型EAに向いています。
Q: ADXが25以上の相場でも損失が続く場合はどうすべきですか? A: ADXはトレンドの強さを示しますが、エントリータイミングまでは教えてくれません。ADXフィルターに加えて、エントリートリガー(MAクロス・ブレイクアウト等)の精度を見直すことと、バックテスト期間を複数の相場サイクルにまたがるよう延長して再検証することを推奨します。
Q: Hedgrow FXのツールでADXフィルターは実装できますか? A: Claudeと会話しながらインジケーターを作成できるhedgrow.ioでは、ADXフィルターの実装要件を自然言語で伝えるとコードの雛形生成をサポートしてもらえます。
著者情報
本記事は金融工学・アルゴリズム取引の実務経験を持つライターが執筆しています。
免責事項: 本記事はFXの教育・情報提供を目的としており、投資勧誘や特定の売買戦略の推奨を行うものではありません。FX取引にはリスクが伴い、元本割れの可能性があります。実際の取引は自己責任で行ってください。過去のバックテスト結果は将来の運用成果を保証するものではありません。
