「相場の勢いが強いのか弱いのか、数値で判断できたらいいのに…」そんな風に思ったことはありませんか?
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に組み込んで、ボラティリティを味方につけてください!

