【MQL4】iATR関数の使い方を徹底解説!ATR(アベレージ・トゥルー・レンジ)でボラティリティを味方につけよう

【中級編】MQLプログラムの読み方・書き方

「相場の勢いが強いのか弱いのか、数値で判断できたらいいのに…」そんな風に思ったことはありませんか?

MQL4には、ボラティリティ(価格変動の大きさ)を数値化できる便利な関数iATRが用意されています。ATR(Average True Range:アベレージ・トゥルー・レンジ)は、多くのプロトレーダーも活用している指標で、ストップロスの設定やエントリーフィルターなど、EA開発で大活躍します。

この記事では、iATR関数の基本的な使い方から、実践的なEAへの組み込み方まで、サンプルコード付きで徹底解説します!

ATR(アベレージ・トゥルー・レンジ)とは?

ATRを理解するには、まずTR(トゥルー・レンジ)を知る必要があります。TRは「そのローソク足の本当の値動き幅」を表すもので、次の3つの値のうち最も大きいものを採用します。

  • 当日の高値 − 当日の安値(通常の値幅)
  • 当日の高値 − 前日の終値の絶対値(上方向へのギャップを考慮)
  • 当日の安値 − 前日の終値の絶対値(下方向へのギャップを考慮)

ATRは、このTRを指定した期間で平均化したものです。一般的には14期間がよく使われます。

ATRの値が大きいほど「ボラティリティが高い(値動きが激しい)」、小さいほど「ボラティリティが低い(値動きが穏やか)」と判断できます。なお、ATRはあくまで値動きの「大きさ」を示すものであり、方向(上昇・下降)は示しません。

iATR関数の基本構文

MQL4でATRの値を取得するには、iATR関数を使います。基本構文は以下の通りです。

double iATR(
    string symbol,      // 通貨ペア名
    int    timeframe,   // 時間足
    int    period,      // 平均期間
    int    shift        // シフト(何本前のバーか)
);

各引数の詳細を見ていきましょう。

引数 説明
symbol string 対象の通貨ペア名。NULL を指定すると現在のチャートの通貨ペアになります。 NULL, “USDJPY”
timeframe int 時間足を指定します。0 を指定すると現在のチャートの時間足になります。 0, PERIOD_H1, PERIOD_D1
period int ATRを計算する平均期間。一般的には14が使われます。 14, 20
shift int 何本前のバーの値を取得するか。0は現在の未確定バー、1は直近の確定バーです。 0, 1

基本的な使い方 ― ATR値を取得してみよう

まずは最もシンプルな使い方です。現在のチャートで14期間ATRの値を取得し、エキスパートログに出力してみましょう。

void OnTick()
{
    // 直近の確定バー(shift=1)のATR値を取得
    double atrValue = iATR(NULL, 0, 14, 1);

    // ログに出力
    Print("現在のATR(14) = ", DoubleToString(atrValue, 5));
}

ここで重要なポイントはshift=1を使っていることです。shift=0だと現在形成中のバー(まだ確定していない)の値を参照するため、ティックごとに値が変動してしまいます。EAのロジックでは、基本的にshift=1(直近の確定バー)を使うのが安定した判断につながります。

実践サンプル①:ATRベースの動的ストップロス&テイクプロフィット

ATRの最も人気のある活用法の一つが、ボラティリティに応じてSL(ストップロス)とTP(テイクプロフィット)を動的に変える方法です。相場が激しく動いているときは広めに、穏やかなときは狭めに設定できます。

// --- 入力パラメータ ---
input int    ATR_Period    = 14;      // ATR期間
input double SL_Multiplier = 1.5;    // SLに使うATRの倍率
input double TP_Multiplier = 2.0;    // TPに使うATRの倍率
input double LotSize       = 0.1;    // ロットサイズ

void OnTick()
{
    // 既にポジションがあれば何もしない(簡略化のため)
    if(OrdersTotal() > 0) return;

    // ATR値を取得(確定バーを使用)
    double atr = iATR(NULL, 0, ATR_Period, 1);

    // ATRが0の場合は処理しない
    if(atr <= 0) return;

    // 動的なSL・TPを計算
    double sl_distance = atr * SL_Multiplier;
    double tp_distance = atr * TP_Multiplier;

    // 現在の価格を取得
    double askPrice = Ask;
    double bidPrice = Bid;

    // 買い注文の例
    double sl = askPrice - sl_distance;
    double tp = askPrice + tp_distance;

    // 小数点桁数を通貨ペアに合わせて丸める
    sl = NormalizeDouble(sl, Digits);
    tp = NormalizeDouble(tp, Digits);

    int ticket = OrderSend(
        Symbol(), OP_BUY, LotSize,
        askPrice, 3, sl, tp,
        "ATR-based SL/TP", 0, 0, clrBlue
    );

    if(ticket > 0)
    {
        Print("注文成功! SL=", DoubleToString(sl, Digits),
              " TP=", DoubleToString(tp, Digits),
              " ATR=", DoubleToString(atr, 5));
    }
    else
    {
        Print("注文失敗: エラーコード=", GetLastError());
    }
}

この例では、ATRの1.5倍をストップロスに、2.0倍をテイクプロフィットに設定しています。こうすることで、ボラティリティが高い相場では自然とSL/TP幅が広がり、低い相場では狭まります。固定pipsのSL/TPと比べて、相場環境に柔軟に対応できるのが大きなメリットです。

実践サンプル②:ATRでボラティリティフィルターを作る

もう一つの活用法が、ボラティリティフィルターです。「ボラティリティが一定以上あるときだけトレードする」というフィルターを作ることで、値動きが小さすぎるレンジ相場でのムダなエントリーを避けられます。

// ボラティリティが十分かどうかを判定する関数
bool IsVolatilityEnough(int atrPeriod, int checkBars, double threshold)
{
    // 現在のATR
    double currentATR = iATR(NULL, 0, atrPeriod, 1);

    // 過去のATRの平均を計算
    double sumATR = 0;
    for(int i = 2; i <= checkBars + 1; i++)
    {
        sumATR += iATR(NULL, 0, atrPeriod, i);
    }
    double avgATR = sumATR / checkBars;

    // 平均に対する比率で判定
    if(avgATR <= 0) return false;

    double ratio = currentATR / avgATR;

    // 比率がしきい値以上ならボラティリティ十分と判定
    if(ratio >= threshold)
    {
        Print("ボラティリティOK: 現在ATR=", DoubleToString(currentATR, 5),
              " 平均ATR=", DoubleToString(avgATR, 5),
              " 比率=", DoubleToString(ratio, 2));
        return true;
    }

    return false;
}

// 使用例
void OnTick()
{
    // 過去20本のATR平均と比較して、0.8倍以上なら十分と判定
    if(!IsVolatilityEnough(14, 20, 0.8))
    {
        // ボラティリティが低いのでトレードしない
        return;
    }

    // ここにエントリーロジックを記述
    // ...
}

この関数は、直近のATRが過去の平均ATRに対してどの程度の比率かを計算し、指定したしきい値以上であれば「ボラティリティ十分」と判定します。レンジ相場で無駄にエントリーしてしまう問題を軽減できる、実用的なフィルターです。

iATR関数を使う際の注意点

① shift=1を基本にしよう

先ほども触れましたが、EA内でATR値をロジック判定に使うときはshift=1(直近の確定バー)を使いましょう。shift=0はティックごとに値が変わるため、バックテストとリアルトレードで結果が乖離する原因になります。

② ATR値をpipsに換算する方法

ATRの戻り値は「価格の値幅」です。pipsに換算したい場合は、以下のようにします。

double atr = iATR(NULL, 0, 14, 1);

// pipsに換算(3桁/5桁ブローカー対応)
double atrPips;
if(Digits == 3 || Digits == 5)
    atrPips = atr / (Point * 10);
else
    atrPips = atr / Point;

Print("ATR = ", DoubleToString(atrPips, 1), " pips");

多くのブローカーは5桁(例:USDJPY = 110.123)または3桁(例:USDJPY = 110.12の場合もあり)の価格表示を使っています。Digitsの値を確認してpips換算することで、どのブローカーでも正しく動作するコードになります。

③ マルチタイムフレームでの活用

iATR関数のtimeframe引数を使えば、現在のチャートとは異なる時間足のATRを取得できます。

// 日足のATRを5分足チャート上で取得
double dailyATR = iATR(NULL, PERIOD_D1, 14, 1);

// 4時間足のATRを取得
double h4ATR = iATR(NULL, PERIOD_H4, 14, 1);

Print("日足ATR=", DoubleToString(dailyATR, 5),
      " 4時間足ATR=", DoubleToString(h4ATR, 5));

例えば、5分足でスキャルピングEAを作りつつ、日足のATRでその日全体のボラティリティを確認する、という使い方ができます。上位足のボラティリティ情報を加味することで、より精度の高いトレード判断が可能になります。

まとめ

この記事では、MQL4のiATR関数を使ってATR(アベレージ・トゥルー・レンジ)を取得・活用する方法を解説しました。最後にポイントを振り返りましょう。

  • ATRはボラティリティ(値動きの大きさ)を数値化した指標で、方向性は示さない
  • iATR関数は4つの引数(symbol, timeframe, period, shift)で手軽にATR値を取得できる
  • EAのロジックではshift=1(確定バー)を使うのが基本
  • 動的SL/TPに活用すれば、相場のボラティリティに応じた柔軟なリスク管理が可能
  • ボラティリティフィルターとして使えば、レンジ相場でのムダなエントリーを回避できる
  • pips換算やマルチタイムフレーム対応も忘れずに実装しよう

ATRは地味に見えるかもしれませんが、EA開発においては非常に汎用性の高い指標です。ストップロス、テイクプロフィット、ロットサイズの計算、エントリーフィルターなど、さまざまな場面で活躍します。ぜひ自分のEAに組み込んで、ボラティリティを味方につけてください!