1. iADX関数の概要と実務での活用法
MQL5のiADX関数は、相場のトレンドの強さを測定するテクニカル指標「ADX(Average Directional Movement Index)」のハンドルを取得するための関数です。ADXは、相場が上昇しているか下降しているかという「方向性」ではなく、現在のトレンドに「勢いがあるかどうか」を0〜100の数値で示します。
実務での活用シーン
実務開発において、ADXは主に「レンジ相場の回避」と「トレンドフォローの実行判定」に使用されます。
* フィルタリング: ADXが25(または20)以下のときは、トレンドが弱いと判断してエントリーを見送る。
* トレンド判断: ADXが上昇傾向にあり、かつ+DIが-DIを上回っていれば強い上昇トレンドと判断する。
初心者がつまずきやすいポイント
MQL5のiADXは、呼び出した瞬間にADXの数値(例:30.5)を返すわけではありません。
返ってくるのは「指標の計算設定を保持した識別番号(ハンドル)」です。このハンドルを使って、後述するCopyBuffer関数で実際のデータを取り出すという2ステップの工程が必要になる点が、MQL4(旧バージョン)との大きな違いです。
2. 構文と戻り値
iADX関数の基本的な構文は以下の通りです。
int iADX(
string symbol, // 通貨ペア名(NULLなら現在のチャート)
ENUM_TIMEFRAMES period, // 時間軸(0なら現在の時間軸)
int adx_period // 平均化期間(一般的に14)
);
パラメーター解説
- symbol: 対象となる通貨ペアを指定します。通常は現在表示中のチャートを指す
_Symbolを指定します。 - period: 時間軸を指定します。
PERIOD_H1(1時間足)や、現在の時間軸を指す_Periodを指定します。 - adx_period: ADXを計算する期間です。デフォルトでは「14」が使われることが一般的です。
戻り値
- 成功した場合:指標のハンドル(int型の整数)を返します。
- 失敗した場合:
INVALID_HANDLEを返します。
取得できるバッファの種類
iADXには3つのラインデータが含まれており、CopyBufferで指定するインデックス番号によって取得できる値が変わります。
* 0: MAIN_LINE (ADX本体)
* 1: PLUSDI_LINE (+DI)
* 2: MINUSDI_LINE (-DI)
3. 具体的な使い方・実践サンプルコード
以下は、ADXのハンドルを作成し、最新の値を抽出してログに出力するシンプルなEA(エキスパートアドバイザー)のテンプレートです。
//+------------------------------------------------------------------+
//| ADX_Sample_EA.mq5 |
//+------------------------------------------------------------------+
#property strict
// グローバル変数
int handleADX; // ADXのハンドルを格納する変数
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// 1. ADXのハンドルを取得(期間14)
handleADX = iADX(_Symbol, _Period, 14);
// ハンドル取得に失敗した場合はエラーを出力
if(handleADX == INVALID_HANDLE)
{
Print("ADXハンドルの取得に失敗しました。");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double adxValues[]; // ADX値を格納する動的配列
double plusDIValues[]; // +DI値を格納する動的配列
double minusDIValues[];// -DI値を格納する動的配列
// 配列を時系列順(最新がインデックス0)に設定
ArraySetAsSeries(adxValues, true);
ArraySetAsSeries(plusDIValues, true);
ArraySetAsSeries(minusDIValues, true);
// 2. 実際のデータをコピー(直近3本分)
if(CopyBuffer(handleADX, 0, 0, 3, adxValues) < 0 ||
CopyBuffer(handleADX, 1, 0, 3, plusDIValues) < 0 ||
CopyBuffer(handleADX, 2, 0, 3, minusDIValues) < 0)
{
Print("データのコピーに失敗しました。");
return;
}
// 最新(インデックス0)のADX値を取得
double currentADX = adxValues[0];
double currentPlusDI = plusDIValues[0];
double currentMinusDI = minusDIValues[0];
// トレンド判断の例
if(currentADX > 25.0)
{
if(currentPlusDI > currentMinusDI)
Comment("強い上昇トレンド中: ADX=", currentADX);
else
Comment("強い下降トレンド中: ADX=", currentADX);
}
else
{
Comment("レンジ相場(トレンド弱): ADX=", currentADX);
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 3. 使用したハンドルを解放(メモリ管理)
IndicatorRelease(handleADX);
}
4. 使用上の注意点とよくあるエラー
① ハンドルの作成はOnInitで行う
iADX関数をOnTick内で毎回呼び出すのはNGです。ティックが動くたびに新しいハンドルを作成すると、メモリを大量に消費し、ターミナルの動作が極端に重くなったり、最悪の場合フリーズしたりします。必ずOnInitで一度だけ作成するようにしてください。
② CopyBufferの戻り値を確認する
データが十分に溜まっていないチャート(読み込み直後など)では、CopyBufferが失敗することがあります。戻り値を確認せずに配列を参照すると、「Array out of range(配列の範囲外アクセス)」エラーでEAが停止する原因になります。
③ インジケーターの「遅行性」を理解する
ADXは移動平均に基づいた指標であるため、急激な価格変動に対して反応が遅れる(ラグがある)特性があります。ADXが上昇したときには、既にトレンドの旬が過ぎていることもあるため、他のオシレーター系指標やプライスアクションと組み合わせて使うのが定石です。
5. 【重要】自動売買における約定スピードと環境の罠
どんなに優れたADXのロジックを組み上げたとしても、それを実行する「環境」が貧弱であれば、安定した利益を出すことは不可能です。自宅のPCや一般的な光回線を使った自動売買には、目に見えない「ネットワーク遅延(レイテンシ)」という巨大なリスクが潜んでいます。FX市場の価格は1ミリ秒(0.001秒)単位で変動しており、自宅から海外にあるブローカーのサーバーまで注文が届くまでの間に価格が滑る「スリッページ」が発生し、期待した約定価格から乖離してしまうのです。
この約定スピードの壁を突破し、理論通りのパフォーマンスを発揮させるためには、ブローカーのサーバーと同じデータセンター内、あるいは至近距離に設置された「自動売買専用のVPS(仮想専用サーバー)」の利用が不可欠です。24時間365日、安定した電源と超高速なバックボーン回線で稼働するVPS環境は、もはやおまけではなく、プロのクオンツエンジニアにとっては「必須の装備」と言えます。ネットワーク遅延によるわずかな損失の積み重ねは、長期的には数万円、数十万円という致命的な機会損失に繋がることを忘れてはいけません。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント