MQL5 ATRボラティリティフィルターの実装方法

目次

1. MQL5のATRボラティリティフィルターとは何か

【結論】ATRボラティリティフィルターとは、「価格の動きが十分にある場面だけでトレードを行う」ための制御ロジックです。無駄なエントリーを減らし、期待値を安定させる目的で使われます。

1.1 ATR(Average True Range)の定義

【結論】ATRは「価格の変動幅(ボラティリティ)」を数値化した指標であり、トレンド方向ではなく“動きの大きさ”だけを測定します。

【定義】
ATR(Average True Range)は、一定期間における価格の上下幅(高値−安値+ギャップ)を平均化したインジケーターです。

具体的には、以下の特徴を持ちます。

  • 値が大きい → 相場が大きく動いている(高ボラティリティ)
  • 値が小さい → 相場があまり動いていない(低ボラティリティ)
  • 上昇・下降の方向は示さない(方向性は別指標が必要)

初心者がよく誤解する点として、「ATRが上がる=上昇トレンド」と考えてしまうケースがありますが、これは誤りです。ATRはあくまで“値動きの大きさ”のみを示します。

また、ATRは以下のような場面で重要になります。

  • スプレッド(spread)負けが起きやすい低ボラ環境の判定
  • スリッページ(slippage)が発生しやすい高ボラ環境の検出
  • execution条件(約定しやすさ)の間接的な判断

つまり、ATRは「トレードして良い市場かどうか」を判断する基準として使われます。


1.2 ボラティリティフィルターとは何か

【結論】ボラティリティフィルターとは、ATRなどの指標を使って「エントリーすべき相場だけを選別する仕組み」です。

ボラティリティフィルターの基本的な考え方は非常にシンプルです。

  • ATRが一定以上 → トレードする(動きがある)
  • ATRが一定未満 → トレードしない(動きが小さい)

このように、「市場の状態によってトレード可否を切り替える」ことで、無駄な注文(order)を減らします。

具体例:

  • スキャルピング
    → 低ボラ環境ではspreadに負けやすいため回避
  • ブレイクアウト戦略
    → 高ボラ環境でのみ有効なので条件に組み込む
  • トレンドフォロー
    → ボラがあるとトレンドが伸びやすいためフィルターとして有効

よくある失敗として、フィルターを使わずに常にエントリーしてしまうケースがあります。この場合、以下の問題が発生します。

  • レンジ相場でのダマシ増加
  • 無駄なエントリー増加 → 手数料・spread増加
  • PF(プロフィットファクター)の低下

そのため、ATRフィルターは「トレードの質を上げるための前提条件」として扱うのが基本です。


1.3 なぜMQL5で重要か

【結論】MQL5においてATRフィルターは、EAの安定性と再現性を大きく左右する重要な要素です。

自動売買(EA)では、以下の問題が常に存在します。

  • 市場状態が常に変化する
  • execution環境(約定・スリッページ)が一定ではない
  • spreadが時間帯・通貨ペアで変動する

これに対して、ATRフィルターは「市場の状態を定量的に判断する手段」として機能します。

具体的なメリット:

  • 無駄なエントリー削減 → 取引回数の最適化
  • ドローダウン(DD)抑制
  • 戦略の再現性向上(異なる相場でも安定)

特に重要なのは「期待値への影響」です。

ATRフィルターを使わない場合:

  • 勝率は上がるが、利益が伸びない
  • 小さな損益の積み重ねで消耗する

ATRフィルターを使う場合:

  • トレード回数は減る
  • 1トレードあたりの利益が大きくなる

この結果、長期的にはPFやリスクリワードが改善されやすくなります。

注意点として、ATRフィルターだけで完全な戦略になるわけではありません。

  • トレンド判定(MA、RSIなど)
  • コスト制御(spreadフィルター)
  • 時間帯制御(セッションフィルター)

これらと組み合わせて初めて、実運用レベルのEAになります。

2. ATRボラティリティフィルターの実装手順

【結論】MQL5でのATRフィルターは「iATRで指標取得 → CopyBufferで値取得 → 条件分岐でエントリー制御」という3ステップで実装できます。


2.1 iATR関数の基本構文

【結論】iATRはATRインジケーターの「ハンドル(識別子)」を取得する関数であり、実際の値は後から取得します。

MQL5では、インジケーターは直接値を返さず、「ハンドル」を経由して取得する設計になっています。

基本構文:

int iATR(
   string           symbol,     // 通貨ペア
   ENUM_TIMEFRAMES  timeframe,  // 時間足
   int              period      // 期間
);

使用例:

int atrHandle;

int OnInit()
{
   atrHandle = iATR(_Symbol, PERIOD_CURRENT, 14);
   
   if(atrHandle == INVALID_HANDLE)
   {
      Print("ATRハンドル取得失敗");
      return(INIT_FAILED);
   }

   return(INIT_SUCCEEDED);
}

ポイント:

  • _Symbol:現在の通貨ペア
  • PERIOD_CURRENT:現在の時間足
  • 14:一般的なデフォルト期間

よくある失敗:

  • ハンドル取得失敗のチェックをしない
  • OnInitではなくOnTickで毎回生成してしまう(非効率・メモリ浪費)

2.2 CopyBufferで値を取得する方法

【結論】ATRの実際の数値はCopyBuffer関数で取得し、配列として扱います。

MQL5では、インジケーターの値は「バッファ(配列)」として取得されます。

基本構文:

int CopyBuffer(
   int       indicator_handle,
   int       buffer_num,
   int       start_pos,
   int       count,
   double    buffer[]
);

実装例:

double atrBuffer[];

void GetATRValue()
{
   ArraySetAsSeries(atrBuffer, true);

   if(CopyBuffer(atrHandle, 0, 0, 1, atrBuffer) <= 0)
   {
      Print("ATR取得失敗");
      return;
   }
}

重要ポイント:

  • buffer_num = 0:ATRは1本のみ
  • start_pos = 0:最新バー
  • count = 1:1本だけ取得
  • ArraySetAsSeries(true):時系列を逆順に(最新が[0])

よくある失敗:

  • ArraySetAsSeriesを設定しない → インデックスが逆になる
  • CopyBufferの戻り値チェックをしない → 無効データ使用

2.3 フィルター条件の実装例

【結論】ATR値と閾値(threshold)を比較するだけで、シンプルにフィルターを構築できます。

代表的なパターン:

■ 高ボラ時のみエントリー

double threshold = 0.0010;

if(atrBuffer[0] > threshold)
{
   // エントリー許可
}

■ 低ボラ回避

if(atrBuffer[0] < threshold)
{
   // エントリー禁止
}

実務での考え方:

  • 通貨ペアごとに値は異なる(例:USDJPYとEURUSD)
  • 時間足によってATR値は大きく変わる

例:

  • M1 → 小さい値
  • H1 → 大きい値

よくある失敗:

  • thresholdを固定値で使い回す
  • 通貨ペアごとの最適化をしない
  • 桁数(小数点)を誤認する

2.4 実践コード例(シンプル)

【結論】ATRフィルターはOnTick内で「条件チェック → OrderSend前に判定」という流れで組み込みます。

最小構成:

int atrHandle;
double atrBuffer[];

int OnInit()
{
   atrHandle = iATR(_Symbol, PERIOD_CURRENT, 14);
   return(INIT_SUCCEEDED);
}

void OnTick()
{
   ArraySetAsSeries(atrBuffer, true);

   if(CopyBuffer(atrHandle, 0, 0, 1, atrBuffer) <= 0)
      return;

   double atr = atrBuffer[0];
   double threshold = 0.0010;

   // フィルター条件
   if(atr < threshold)
      return; // 低ボラなのでエントリーしない

   // --- ここからエントリー処理 ---
   // OrderSend等のロジック
}

実務的な補足:

  • OrderSendの直前にフィルターを置くのが安全
  • spreadフィルターと併用するのが一般的
  • execution環境(VPS・遅延)も影響する

よくある失敗:

  • フィルター位置が早すぎる(シグナル前)
  • フィルターが強すぎてトレードゼロになる
  • バックテストだけで判断する(フォワード未確認)

3. なぜATRフィルターが有効なのか

【結論】ATRフィルターは「不利な市場環境を事前に除外する」ことで、無駄な損失を減らし、結果的にトレードの期待値(利益の出やすさ)を改善します。


3.1 低ボラ相場の問題

【結論】低ボラ相場では値動きが小さく、スプレッドや手数料に対して利益幅が不足し、期待値が下がりやすくなります。

低ボラ(ATRが小さい状態)の特徴:

  • 値動きが狭い(レンジ状態)
  • ノイズ(ダマシ)が多い
  • 明確なトレンドが発生しにくい

この環境でトレードすると、以下の問題が発生します。

  • エントリーしても価格が伸びない
  • spread(スプレッド)分のコスト負けが起きる
  • 損切りにかかりやすい(微小な上下で刈られる)

特にスキャルピングや短期EAでは致命的です。

例:

  • 利益目標:5pips
  • スプレッド:2pips

→ 実質的な利益余地が非常に小さい

よくある失敗:

  • ATRを使わずに常時エントリーする
  • レンジ相場で無限にトレードを繰り返す
  • 勝率だけを見てロジックを評価する

重要なのは、「トレードしない判断」も戦略の一部であるという点です。


3.2 高ボラ相場の特性

【結論】高ボラ相場では価格の動きが大きく、利益幅を確保しやすいため、リスクリワードが改善します。

高ボラ(ATRが大きい状態)の特徴:

  • トレンドが発生しやすい
  • ブレイクアウトが機能しやすい
  • 利益が伸びやすい

この環境では、以下のメリットがあります。

  • 少ないトレード回数で利益が出る
  • slippage(スリッページ)があっても吸収可能
  • executionコストより値動きの方が大きい

ただし注意点もあります。

  • 急変動による逆行リスク
  • スリッページ増加
  • 約定遅延(execution問題)

よくある誤解:

  • 「ボラが高い=安全」ではない
    → 正しくは「利益が出やすいがリスクも高い」

そのため、ATRフィルターは「使うか使わないか」ではなく、どの水準で使うかが重要になります。


3.3 期待値への影響

【結論】ATRフィルターは「損失トレードを減らす」ことで、結果的にプロフィットファクター(PF)と期待値を改善します。

期待値の基本構造:

  • 期待値 = 勝率 × 平均利益 − 負率 × 平均損失

ATRフィルターの役割:

  • 低ボラ時の無駄なトレードを削減 → 負率低下
  • 高ボラ時のみエントリー → 平均利益増加

結果として:

  • PF(利益 ÷ 損失)が改善
  • DD(ドローダウン)が抑制
  • 資金曲線が安定

具体的な変化:

指標フィルターなしフィルターあり
トレード回数多い少ない
勝率高い(場合あり)やや低下
利益幅小さい大きい
PF低い高い

重要ポイント:

  • 勝率より「利益幅」が重要
  • トレード回数を減らすことは悪ではない

よくある失敗:

  • 勝率が下がっただけでロジックを捨てる
  • トレード回数の減少をマイナス評価する
  • PFや期待値を見ずに判断する

3.4 EA設計における役割

【結論】ATRフィルターはEAにおいて「エントリー前の品質チェック」として機能し、戦略の安定性を支えます。

EA設計における位置づけ:

  • シグナル生成(例:MAクロス)
  • フィルター(ATR・spread・時間)
  • エントリー実行(OrderSend)

この中でATRは「フィルター層」に属します。

役割:

  • 市場状態の定量評価
  • 不利な環境の排除
  • ロジックの再現性向上

実務での使い方:

  • ATR単体ではなく複合フィルターとして使用
  • 例:
    • ATR + spreadフィルター
    • ATR + トレンド判定(MA, RSI)
    • ATR + セッションフィルター

なぜ複合化が必要か:

  • ATRは「動きの大きさ」しか見ない
  • 方向性・コスト・時間は別軸

よくある失敗:

  • ATRだけで戦略を組む
  • フィルターを増やしすぎる(過剰最適化)
  • バックテストのみで評価する

実務的な結論:

  • ATRは「単体では弱いが、組み合わせると強い」
  • EAの品質を底上げする“基盤パーツ”

4. 他のフィルター手法との比較

【結論】ATRフィルターは「市場の動きの大きさ」を判断する指標であり、他のフィルター(spread・トレンド・時間)とは役割が異なります。単体では不十分であり、組み合わせることで実務レベルの精度になります。


4.1 ATRフィルターとスプレッドフィルターの違い

【結論】ATRは「市場の状態」、スプレッドフィルターは「取引コスト」を制御するため、役割が根本的に異なります。

スプレッドフィルターの役割:

  • エントリーコストの制御
  • 異常なspread拡大時の回避

実装イメージ:

double spread = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID)) / _Point;

if(spread > maxSpread)
   return;

比較:

項目ATRフィルタースプレッドフィルター
対象市場の動き取引コスト
目的有利な相場選別不利なコスト回避
性質間接的直接的

重要ポイント:

  • ATRが高くてもspreadが広いと不利
  • 両方を同時にチェックするのが基本

よくある失敗:

  • ATRだけで判断する
  • spread無視でエントリー → execution負け

4.2 ATRフィルターとトレンドフィルターの違い

【結論】ATRは「強さ」、トレンドフィルター(MA・RSIなど)は「方向」を判断するため、役割が補完関係にあります。

トレンドフィルターの例:

  • 移動平均(MA)
  • RSI
  • MACD

特徴:

  • 上昇・下降を判定できる
  • エントリー方向を決める

ATRとの違い:

項目ATRトレンドフィルター
判定内容変動幅方向
役割エントリー可否エントリー方向
単体性能低い中程度

組み合わせ例:

if(atr > threshold && price > ma)
{
   // 上昇トレンドかつ高ボラ → エントリー
}

よくある失敗:

  • ATRだけで売買方向を決める
  • トレンド無視でエントリー

結論:

  • ATRは「動くかどうか」
  • トレンドは「どっちに動くか」

4.3 ATRフィルターと時間フィルターの違い

【結論】ATRは市場状況に応じた「動的制御」、時間フィルターは固定ルールによる「静的制御」です。

時間フィルターの例:

  • ロンドン時間のみトレード
  • ニューヨーク時間回避
  • 指標発表前後を除外

実装イメージ:

int hour = TimeHour(TimeCurrent());

if(hour < 8 || hour > 20)
   return;

比較:

項目ATRフィルター時間フィルター
性質動的静的
柔軟性高い低い
再現性中程度高い

重要ポイント:

  • 同じ時間帯でもボラは変化する
  • ATRの方が市場に適応する

ただし:

  • 時間フィルターは再現性が高く安定
  • ATRは過去最適化の影響を受けやすい

よくある失敗:

  • 時間だけで判断する
  • ATRだけで時間帯無視

4.4 比較まとめ(実務判断基準)

【結論】最も効果的なのは「ATR+他フィルターの組み合わせ」であり、単体運用は推奨されません。

総合比較:

フィルター精度再現性実装難易度有効な場面
ATRボラ判定
spreadコスト制御
トレンド方向判定
時間安定運用

実務での最適構成:

  • ATR(市場状態)
  • spread(コスト)
  • トレンド(方向)
  • 時間(安定性)

例:

if(atr > atrThreshold &&
   spread < maxSpread &&
   price > ma &&
   hour >= 8 && hour <= 20)
{
   // 高品質なエントリー条件
}

重要ポイント:

  • フィルターは「減らす」のではなく「役割で分ける」
  • 過剰に増やすとトレード機会消失

よくある失敗:

  • フィルターを増やしすぎる(過剰最適化)
  • 1つのフィルターに依存する
  • バックテストのみで判断する

実務的な結論:

  • ATRは「核ではなく補助」
  • 複合設計が前提

5. よくある失敗と注意点

【結論】ATRフィルターは有効ですが、「閾値設定・期間設定・過剰最適化」を誤ると、トレード機会の消失や成績劣化を招きます。実装ミスより“設計ミス”が致命的になりやすい領域です。


5.1 閾値(threshold)の設定ミス

【結論】thresholdは通貨ペア・時間足ごとに最適値が異なり、固定値の流用は機能不全の原因になります。

よくある問題:

  • EURUSDの値をUSDJPYにそのまま適用
  • M1とH1で同じthresholdを使う
  • 小数点桁を誤認(_Point未考慮)

対策:

  • 通貨ペア別に個別最適化する
  • 時間足ごとに別パラメータを持つ
  • ATRをポイント換算して扱う

例(ポイント換算):

double atrPoints = atrBuffer[0] / _Point;
if(atrPoints < minAtrPoints) return;

なぜ重要か:

  • ATRは「絶対値」なのでスケール差が大きい
  • 通貨ごとにボラ特性が異なる

5.2 ATR期間の誤設定

【結論】期間は短すぎるとノイズに反応し、長すぎると市場変化に追従できません。

典型的な挙動:

  • 短期(例:5〜10)
    • 反応が速いがノイズが多い
  • 標準(例:14)
    • バランスが良い
  • 長期(例:50以上)
    • 安定するが遅れる

選定指針:

  • スキャルピング → 短期寄り
  • デイトレード → 標準
  • スイング → 長期寄り

よくある失敗:

  • 期間を固定して検証しない
  • バックテストでのみ最適化してしまう

5.3 過剰フィルタリング

【結論】フィルターを厳しくしすぎるとトレード回数が激減し、期待値が逆に悪化します。

典型例:

if(atr < threshold) return;
if(spread > maxSpread) return;
if(price < ma) return;
if(hour < 8 || hour > 20) return;

問題:

  • 条件が多すぎてエントリーが発生しない
  • バックテストでは良く見えるが実運用で崩れる

対策:

  • 各フィルターの役割を明確化
  • 「削るためのフィルター」と「質を上げるフィルター」を分ける

判断基準:

  • トレード回数が極端に減る → 過剰
  • PFだけ高い → 要注意(過学習の可能性)

5.4 スプレッド・スリッページ未考慮

【結論】ATRだけではコストを制御できないため、spread・slippageを必ず別で管理する必要があります。

問題点:

  • 高ボラ=スプレッド拡大しやすい
  • 指標時にslippageが増大

対策:

double spread = (Ask - Bid) / _Point;
if(spread > maxSpread) return;

重要ポイント:

  • ATRは「市場状態」しか見ない
  • コスト(execution条件)は別管理が必須

よくある失敗:

  • ATRが高いから安全と誤解
  • コスト無視でバックテストだけ良好

5.5 バックテスト最適化の罠(過剰最適化)

【結論】ATRの閾値や期間を過去データで最適化しすぎると、将来の再現性が失われます。

典型パターン:

  • 特定期間だけ極端に良いパラメータを採用
  • フォワードで崩壊

原因:

  • ATRは市場状態に依存するため変動が大きい
  • 過去のボラ構造が未来と一致しない

対策:

  • フォワードテスト必須
  • 複数期間で検証(ウォークフォワード)
  • パラメータをシンプルに保つ

判断基準:

  • 少し性能を落としても安定性を優先
  • 「最適」より「ロバスト」を選ぶ

5.6 実務的なチェックリスト

【結論】以下を満たしていれば、ATRフィルターは実運用に耐えやすくなります。

チェック項目:

  • 通貨ペアごとにthresholdを調整している
  • ATR期間を戦略に合わせている
  • spreadフィルターを併用している
  • トレンドフィルターと役割分担している
  • フォワード検証を行っている

6. 実務での使いどころ(戦略別)

【結論】ATRフィルターは「戦略ごとに使い方を変える」ことで最大効果を発揮します。単一ルールではなく、戦略の特性に合わせて条件を設計することが重要です。


6.1 トレンドフォロー戦略での使い方

【結論】トレンドフォローでは「ATRが一定以上のときのみエントリー」とすることで、伸びる相場だけを狙えます。

トレンドフォローの特徴:

  • トレンドに乗ることで利益を伸ばす
  • 横ばい相場では損失が出やすい

ATRフィルターの役割:

  • トレンドが発生しやすい局面のみ抽出
  • レンジ相場を回避

実装イメージ:

if(atr > atrThreshold && price > ma)
{
   // 上昇トレンドかつ高ボラ → 買い
}

ポイント:

  • MAなどのトレンドフィルターと併用必須
  • ATR単体では方向が分からない

よくある失敗:

  • ATRだけでエントリーする
  • トレンド判定を省略する

6.2 ブレイクアウト戦略での使い方

【結論】ブレイクアウトでは「ATRの上昇タイミング」を使うことで、ダマシを減らせます。

ブレイクアウトの課題:

  • レンジ内の偽ブレイクが多い
  • ボラが低いと失敗しやすい

ATRフィルターの活用:

  • ATRが上昇しているタイミングのみエントリー
  • ボラ拡大=本物の動きの可能性が高い

実装例:

if(atr > atrThreshold && atr > prevAtr)
{
   // ボラ拡大中のみブレイクアウト採用
}

ポイント:

  • ATRの「絶対値」だけでなく「増加」も見る
  • CopyBufferで複数バー取得して比較する

よくある失敗:

  • ATRの変化を見ない
  • 静的thresholdだけで判断する

6.3 スキャルピングでの使い方

【結論】スキャルピングでは「低ATR時の回避」が最重要であり、トレードしない判断が利益に直結します。

スキャルの特性:

  • 利益幅が小さい
  • spreadの影響が大きい

問題:

  • 低ボラ時はspread負けしやすい
  • execution遅延で不利になる

ATRフィルターの役割:

  • 低ボラ環境を除外
  • 最低限の値動きを保証

実装例:

if(atr < minAtrThreshold)
   return; // エントリー禁止

重要ポイント:

  • 「高ボラで攻める」より「低ボラを避ける」が重要
  • spreadフィルターとの併用が必須

よくある失敗:

  • 常時トレードしてしまう
  • ATRを使わず回数で勝負する

6.4 複合フィルター設計(実運用)

【結論】実運用ではATR単体では不十分であり、「複数フィルターの組み合わせ」が前提になります。

代表的な構成:

  • ATR → 市場状態
  • spread → コスト制御
  • トレンド → 方向
  • 時間 → 安定性

実装例:

double spread = (Ask - Bid) / _Point;
int hour = TimeHour(TimeCurrent());

if(atr > atrThreshold &&
   spread < maxSpread &&
   price > ma &&
   hour >= 8 && hour <= 20)
{
   // 高品質なエントリー
}

設計の考え方:

  • 各フィルターは役割を分担
  • 重複機能を避ける(冗長設計防止)

実務的な判断軸:

  • ATR → 「動くか」
  • spread → 「コストに耐えられるか」
  • トレンド → 「方向が合っているか」

よくある失敗:

  • フィルターを増やしすぎる
  • すべてをATRで解決しようとする
  • バックテストだけで判断する

6.5 実運用での最適な考え方

【結論】ATRフィルターは「エントリーを増やすためではなく、減らすために使う」ことが本質です。

重要ポイント:

  • トレード回数は少なくて良い
  • 質の高いエントリーだけを残す
  • PFとDDで評価する

判断基準:

  • トレード回数が減る → 正常
  • PFが上がる → 成功
  • DDが減る → 実用レベル

最終的な役割:

  • ATRは「フィルターの中核」
  • ただし単体では成立しない

7. 実装テンプレート(再利用用)

【結論】ATRフィルターは「OnInitでハンドル生成 → OnTickで値取得 → 条件分岐でエントリー制御」という最小構成にまとめると、どのEAにも再利用できます。


7.1 初期化処理(OnInit)

【結論】iATRのハンドルはOnInitで一度だけ生成し、毎ティックで再生成しないことが重要です。

int atrHandle;

int OnInit()
{
   atrHandle = iATR(_Symbol, PERIOD_CURRENT, 14);

   if(atrHandle == INVALID_HANDLE)
   {
      Print("ATRハンドル取得失敗");
      return(INIT_FAILED);
   }

   return(INIT_SUCCEEDED);
}

ポイント:

  • _Symbol:現在の通貨ペア
  • PERIOD_CURRENT:現在の時間足
  • 14:一般的な初期値(調整可能)

よくある失敗:

  • OnTickで毎回iATRを呼ぶ → パフォーマンス低下
  • INVALID_HANDLEチェックをしない → 異常動作

7.2 OnTickでのATR取得処理

【結論】CopyBufferで最新のATR値を取得し、必ずエラーチェックを行います。

double atrBuffer[];

bool GetATR(double &atr)
{
   ArraySetAsSeries(atrBuffer, true);

   if(CopyBuffer(atrHandle, 0, 0, 1, atrBuffer) <= 0)
   {
      Print("ATR取得失敗");
      return false;
   }

   atr = atrBuffer[0];
   return true;
}

使い方:

double atr;

if(!GetATR(atr))
   return;

重要ポイント:

  • 最新値は atrBuffer[0]
  • CopyBuffer失敗時は処理を止める

よくある失敗:

  • バッファ未初期化
  • 戻り値チェックをしない
  • 古いバーの値を使う

7.3 フィルター条件の実装

【結論】ATRとthresholdを比較するだけで、シンプルにエントリー制御が可能です。

double atrThreshold = 0.0010;

if(atr < atrThreshold)
{
   // 低ボラ → エントリーしない
   return;
}

応用(ポイント換算):

double atrPoints = atr / _Point;

if(atrPoints < minAtrPoints)
   return;

ポイント:

  • 通貨ペアごとに調整必須
  • 時間足ごとにthresholdを変える

よくある失敗:

  • 固定値を使い回す
  • 桁数ミス(JPY系など)

7.4 エントリー制御(OrderSend前)

【結論】ATRフィルターは「エントリー直前」に配置することで、安全かつ柔軟に制御できます。

void OnTick()
{
   double atr;

   if(!GetATR(atr))
      return;

   double atrThreshold = 0.0010;

   // ATRフィルター
   if(atr < atrThreshold)
      return;

   // --- ここからエントリー ---
   // OrderSend等の処理
}

推奨構成(実務):

if(atr > atrThreshold &&
   spread < maxSpread &&
   price > ma)
{
   // 高品質なエントリー条件
}

重要ポイント:

  • フィルターはOrderSendの直前に置く
  • 他フィルターと組み合わせる

よくある失敗:

  • フィルターをシグナル前に置く(ロジック破壊)
  • 条件を分散させる(可読性低下)

7.5 最小テンプレート(コピペ用)

【結論】以下のコードは、そのままEAに組み込める最小構成です。

int atrHandle;
double atrBuffer[];

int OnInit()
{
   atrHandle = iATR(_Symbol, PERIOD_CURRENT, 14);
   return(INIT_SUCCEEDED);
}

bool GetATR(double &atr)
{
   ArraySetAsSeries(atrBuffer, true);

   if(CopyBuffer(atrHandle, 0, 0, 1, atrBuffer) <= 0)
      return false;

   atr = atrBuffer[0];
   return true;
}

void OnTick()
{
   double atr;

   if(!GetATR(atr))
      return;

   double atrThreshold = 0.0010;

   if(atr < atrThreshold)
      return;

   // --- エントリー処理 ---
}

7.6 実務での拡張ポイント

【結論】テンプレートはそのまま使うのではなく、戦略に応じて拡張することで価値が出ます。

拡張例:

  • ATRの増減を判定(ボラ拡大)
  • 通貨ペアごとのパラメータ分岐
  • 時間足別ロジック
  • 複数インジケーターとの統合

注意点:

  • 複雑にしすぎると過剰最適化
  • パラメータ増加=再現性低下

実務的な結論:

  • シンプルに始める
  • フォワード検証で調整

8. よくある質問

8.1 ATRボラティリティフィルターとは何ですか?

【結論】ATRボラティリティフィルターとは、ATRの値を基準にして、トレードする相場と見送る相場を分ける仕組みです。

ATRは価格の変動幅を示すため、低ボラティリティ相場を避けたり、高ボラティリティ相場だけを狙ったりする判断に使えます。MQL5では、iATRCopyBuffer を使ってATR値を取得し、エントリー条件に組み込みます。


8.2 ATRの期間は何に設定すればよいですか?

【結論】一般的には14期間が使われますが、最適な期間は戦略・通貨ペア・時間足によって異なります。

短期売買では短めのATR期間、スイングや長期戦略では長めのATR期間が合う場合があります。ただし、過去データだけで最適化しすぎると過剰最適化になりやすいため、フォワード検証も必要です。


8.3 ATRが低いときはエントリーしない方がよいですか?

【結論】多くのEAでは、ATRが低いときはエントリーを避ける設計が有効です。

低ボラティリティ相場では値幅が小さく、spreadやslippageなどの取引コストに負けやすくなります。特にスキャルピングや短期売買では、ATRが一定未満の場面を除外することで、無駄なトレードを減らせます。


8.4 ATRフィルターだけで勝てるEAになりますか?

【結論】ATRフィルターだけで勝てるEAを作るのは難しく、方向性やコスト管理との組み合わせが必要です。

ATRは値動きの大きさを示すだけで、上昇・下降の方向は示しません。そのため、移動平均、RSI、MACDなどのトレンド判定や、spreadフィルター、時間帯フィルターと組み合わせて使うのが実務的です。


8.5 ATRフィルターの閾値は固定でよいですか?

【結論】ATRの閾値を固定値で全通貨ペア・全時間足に使い回すのは避けるべきです。

ATRは価格そのものの変動幅を示すため、USDJPY、EURUSD、XAUUSDなどで値のスケールが異なります。実務では、ATRを _Point で割ってポイント換算するか、通貨ペア・時間足ごとに閾値を分ける設計が必要です。

double atrPoints = atr / _Point;

if(atrPoints < minAtrPoints)
   return;

8.6 ATRフィルターとスプレッドフィルターはどちらが重要ですか?

【結論】役割が異なるため、どちらか一方ではなく両方を使うのが基本です。

ATRフィルターは市場のボラティリティを判断し、スプレッドフィルターは取引コストを制御します。ATRが高くてもspreadが広い場面では不利な約定になる可能性があるため、OrderSend前に両方を確認する設計が安全です。


8.7 バックテストでATR閾値を最適化してもよいですか?

【結論】最適化は可能ですが、過剰最適化を避けるために、複数期間の検証とフォワードテストが必要です。

ATRの閾値は相場環境に依存するため、特定期間だけに合わせると実運用で機能しない可能性があります。PFだけで判断せず、DD、取引回数、平均利益、平均損失も確認する必要があります。


8.8 ATRフィルターはどの戦略と相性が良いですか?

【結論】ATRフィルターは、トレンドフォロー、ブレイクアウト、スキャルピングと相性が良いです。

トレンドフォローでは高ボラ相場だけを狙う用途、ブレイクアウトではボラ拡大の確認、スキャルピングでは低ボラ回避に使えます。ただし、ATRは方向性を示さないため、売買方向を決めるロジックと組み合わせる必要があります。