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では、iATR と CopyBuffer を使って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は方向性を示さないため、売買方向を決めるロジックと組み合わせる必要があります。