この記事の結論
MQL5でトレンドフィルターを設計する目的は、EAの売買シグナルを相場の方向性に合わせて制限することです。
移動平均線、ADX、ATR、上位足の方向を組み合わせると、条件を分離しやすくなります。
ただし、フィルターを増やしすぎると取引回数が減り、過剰最適化の原因になります。
実運用前には、バックテストだけでなくフォワードテストで再現性を確認する必要があります。
1. このロジックの役割
【結論】
MQL5のトレンドフィルターは、EAがエントリーしてよい相場環境を判定するためのロジックです。
売買シグナルそのものではなく、シグナルを採用するか除外するかを決める役割を持ちます。
【定義】
トレンドフィルターとは、EAの売買条件を相場の方向性や強さに合わせて制限する仕組みです。
トレンドフィルターを入れると、EAの処理は次のように分けやすくなります。
相場認識
↓
フィルター判定
↓
シグナル判定
↓
リスク確認
↓
注文前チェック
↓
注文送信
↓
約定後管理
↓
決済・停止判定
MQL5のEAでは、OnTickで毎回すべての処理を混ぜるよりも、相場判定、シグナル判定、リスク確認、注文処理を分離したほうが検証しやすくなります。

この図は、トレンドフィルターがEA内部でどの位置にあるかを示しています。
1.1 トレンドフィルターが防ぐもの
トレンドフィルターは、主に次のようなエントリーを減らすために使います。
- 上昇傾向の中での安易な売り
- 下降傾向の中での安易な買い
- レンジ相場でのだましシグナル
- ボラティリティ不足時の小さな値動きへの反応
- 上位足と逆方向の短期シグナル
トレンドフィルターは損失をなくす仕組みではありません。
トレンドフィルターは、EAの条件を整理し、検証対象を明確にするための設計要素です。
2. 基本的な考え方
【結論】
トレンドフィルターは、方向、強さ、変動幅、時間軸を分けて設計します。
一つの指標だけで相場全体を判定しようとすると、特定の相場に依存しやすくなります。
MQL5でトレンドフィルターを設計するときは、次の4つを分けて考えます。
| 判定項目 | 目的 | 例 |
|---|---|---|
| 方向 | 上昇、下降、横ばいを判定する | 移動平均線の傾き、価格と移動平均線の位置 |
| 強さ | トレンドが十分かを見る | ADX |
| 変動幅 | 値動きが小さすぎないかを見る | ATR |
| 時間軸 | 短期足と上位足の整合性を見る | 上位足移動平均線 |
トレンドフィルターは、エントリー条件を増やすためではなく、エントリーしてはいけない状況を除外するために使います。
2.1 最新足と確定足の違い
MQL5でインジケータ値を使う場合、最新足と確定足を区別する必要があります。
最新足は形成中の足であり、ティック更新によって値が変わります。
確定足はすでに閉じた足であり、判定の再現性を確認しやすくなります。
EAの検証では、確定足を使った判定のほうがバックテストとフォワードテストの差を確認しやすくなります。
ただし、確定足を使うと反応は遅くなります。
3. 代表的な設計パターン
【結論】
代表的なトレンドフィルターには、移動平均線、ADX、ATR、上位足確認があります。
それぞれ役割が違うため、同じ意味の条件を重ねすぎないことが重要です。
3.1 移動平均線フィルター
移動平均線フィルターは、価格と移動平均線の位置、または移動平均線の傾きで方向を判定します。
実装しやすいため、初心者から中級者向けのEA設計で使いやすい方法です。
例として、終値が移動平均線より上にあり、移動平均線が上向きなら買い方向だけを許可します。
終値が移動平均線より下にあり、移動平均線が下向きなら売り方向だけを許可します。
3.2 ADXフィルター
ADXフィルターは、トレンドの強さを判定するために使います。
ADXは方向そのものではなく、相場に一定の方向性があるかを判断する補助として扱います。
ADXだけで買いか売りかを決める設計は不十分です。
方向判定には、移動平均線、価格位置、上位足判定などを組み合わせます。
3.3 ATRフィルター
ATRフィルターは、相場の変動幅を判定するために使います。
ATRが小さすぎる場合、スプレッドや手数料の影響が相対的に大きくなりやすくなります。
ATRは売買方向を決める指標ではありません。
ATRは、取引を行うだけの値動きがあるかを確認するためのフィルターです。
3.4 上位足フィルター
上位足フィルターは、短期足のシグナルを上位足の方向に合わせる方法です。
短期足で買いシグナルが出ても、上位足が下降傾向ならエントリーを見送る設計にできます。
上位足フィルターは相場認識を安定させやすい一方で、取引回数を大きく減らす場合があります。
4. 実装方法
【結論】
MQL5では、インジケータ関数でハンドルを作成し、CopyBufferで値を取得する流れが基本です。
EAでは、OnInitでハンドルを作成し、OnTickで判定し、OnDeinitで必要に応じてハンドルを解放します。
MQL5のインジケータ利用は、値を直接取得する構造ではなく、インジケータハンドルを通じてバッファ値を取得する構造になることが多いです。
4.1 実装の流れ
トレンドフィルターの実装は、次の順番で整理します。
OnInitで移動平均線やADXなどのハンドルを作成する。- ハンドルが
INVALID_HANDLEでないか確認する。 OnTickで必要な本数のデータがあるか確認する。CopyBufferでインジケータ値を取得する。- 取得件数が不足している場合は判定を中止する。
- 確定足または最新足のどちらを使うか決める。
- フィルター結果を買い許可、売り許可、取引不可に分ける。
4.2 注文処理との分離
トレンドフィルターは、注文処理と直接結合しないほうが扱いやすくなります。
フィルター関数は、買いを許可するか、売りを許可するか、取引しないかだけを返す設計にします。
注文を送る前には、ロット、証拠金、スプレッド、ストップレベル、取引可能時間、既存ポジションを確認します。
MQL5で注文処理を行う場合は、MqlTradeRequest、MqlTradeResult、必要に応じてMqlTradeCheckResultとOrderCheckを使う設計が安全です。
5. サンプルコード
【結論】
次のコードは、移動平均線を使って買い方向と売り方向を判定する検証用サンプルです。
インジケータハンドル、CopyBuffer、確定足判定、エラーハンドリングの基本形を含めています。
#property strict
enum TrendFilterState
{
TREND_FILTER_NONE = 0,
TREND_FILTER_BUY = 1,
TREND_FILTER_SELL = 2
};
input int InpMAPeriod = 50;
input ENUM_MA_METHOD InpMAMethod = MODE_EMA;
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE;
int ma_handle = INVALID_HANDLE;
int OnInit()
{
ma_handle = iMA(_Symbol, _Period, InpMAPeriod, 0, InpMAMethod, InpAppliedPrice);
if(ma_handle == INVALID_HANDLE)
{
Print("Failed to create moving average handle");
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
if(ma_handle != INVALID_HANDLE)
{
IndicatorRelease(ma_handle);
ma_handle = INVALID_HANDLE;
}
}
void OnTick()
{
TrendFilterState trend_state = GetTrendFilterState();
if(trend_state == TREND_FILTER_NONE)
{
return;
}
if(trend_state == TREND_FILTER_BUY)
{
Print("Buy direction is allowed by trend filter");
}
else if(trend_state == TREND_FILTER_SELL)
{
Print("Sell direction is allowed by trend filter");
}
}
TrendFilterState GetTrendFilterState()
{
if(ma_handle == INVALID_HANDLE)
{
Print("Moving average handle is invalid");
return TREND_FILTER_NONE;
}
if(BarsCalculated(ma_handle) < 3)
{
Print("Not enough calculated bars for moving average");
return TREND_FILTER_NONE;
}
double ma_buffer[];
double close_buffer[];
ArraySetAsSeries(ma_buffer, true);
ArraySetAsSeries(close_buffer, true);
int ma_copied = CopyBuffer(ma_handle, 0, 0, 3, ma_buffer);
int close_copied = CopyClose(_Symbol, _Period, 0, 3, close_buffer);
if(ma_copied < 3 || close_copied < 3)
{
Print("Failed to copy enough data for trend filter");
return TREND_FILTER_NONE;
}
const int CURRENT_FORMING_BAR = 0;
const int CURRENT_CLOSED_BAR = 1;
const int PREVIOUS_CLOSED_BAR = 2;
double current_closed_close = close_buffer[CURRENT_CLOSED_BAR];
double current_closed_ma = ma_buffer[CURRENT_CLOSED_BAR];
double previous_closed_ma = ma_buffer[PREVIOUS_CLOSED_BAR];
bool ma_is_rising = current_closed_ma > previous_closed_ma;
bool ma_is_falling = current_closed_ma < previous_closed_ma;
if(current_closed_close > current_closed_ma && ma_is_rising)
{
return TREND_FILTER_BUY;
}
if(current_closed_close < current_closed_ma && ma_is_falling)
{
return TREND_FILTER_SELL;
}
return TREND_FILTER_NONE;
}
このコードは注文送信を行いません。
実運用で注文処理を追加する場合は、注文前にOrderCheckで証拠金、ロット、価格、ストップ条件などを確認する設計にします。
5.1 コードの重要ポイント
このサンプルでは、CURRENT_CLOSED_BARを確定足の位置として使っています。CURRENT_FORMING_BARは最新足の位置であり、ティック更新で値が変わる可能性があります。
CopyBufferの取得件数が不足する場合、EAは判定を中止します。
不足した値で売買判定を続けると、意図しないエントリー条件になる場合があります。
6. パターン別比較
【結論】
トレンドフィルターは、目的に合わせて選ぶ必要があります。
方向判定、強さ判定、変動幅判定を混同すると、条件が複雑になりすぎます。
| 方法 | メリット | デメリット | 向いている場面 | 実装難易度 | 過剰最適化リスク |
|---|---|---|---|---|---|
| 移動平均線フィルター | 実装しやすく方向を見やすい | レンジでだましが出やすい | 初期設計、方向判定 | 低 | 中 |
| ADXフィルター | トレンドの強さを見やすい | 売買方向は別途必要 | トレンド強度判定 | 中 | 中 |
| ATRフィルター | 変動幅を反映しやすい | 方向は判定できない | 低ボラティリティ回避 | 中 | 中 |
| 上位足フィルター | 大きな方向に合わせやすい | 取引回数が減りやすい | マルチタイムフレーム設計 | 中 | 高 |
| 複合フィルター | 条件を細かく制御できる | 条件過多になりやすい | 中級者以上の検証 | 高 | 高 |
複合フィルターは便利ですが、条件を増やすほどパラメータ依存が強くなります。
バックテストで良い結果が出ても、フォワードテストで崩れる場合があります。
7. 誤作動しやすい場面
【結論】
トレンドフィルターは、レンジ相場、急変動、スプレッド拡大、データ不足で誤作動しやすくなります。
フィルター条件だけでなく、判定を停止する条件も設計する必要があります。
7.1 レンジ相場
レンジ相場では、価格が移動平均線の上下を何度も行き来します。
移動平均線フィルターだけでは、買い許可と売り許可が短時間で切り替わる場合があります。
レンジ回避には、ADX、ATR、直近高値安値の幅などを組み合わせる方法があります。
ただし、条件を追加する場合は、取引回数の減少と過剰最適化に注意します。
7.2 急変動とスプレッド拡大
急変動時は、トレンド方向が明確に見えても、約定価格やスプレッド条件が悪化する場合があります。
EAでは、シグナル判定と注文前チェックを分ける必要があります。
スプレッドが広がっている場面では、期待した価格で約定しない可能性があります。
バックテストと実運用の差は、こうした取引条件でも発生します。
7.3 インジケータデータ不足
起動直後や銘柄切り替え直後は、インジケータ値が十分に計算されていない場合があります。BarsCalculatedとCopyBufferの結果を確認し、値が不足している場合は判定を中止します。
8. バックテストで確認すべき項目
【結論】
バックテストでは、利益だけでなく、ドローダウン、取引回数、期間依存性、パラメータ依存性を確認します。
トレンドフィルターは、検証しやすい単位に分けて評価する必要があります。
バックテストでは、最低でも次の項目を確認します。
| 確認項目 | 見る理由 |
|---|---|
| 総損益 | 全体の傾向を把握するため |
| 最大ドローダウン | 資金減少の大きさを確認するため |
| 勝率 | シグナルの頻度と精度を見るため |
| 損益比 | 1回あたりの損益バランスを見るため |
| 取引回数 | 検証に十分な回数があるかを見るため |
| 連敗数 | 運用停止条件を考えるため |
| スプレッド条件 | 実運用との差を想定するため |
| 期間依存性 | 特定期間だけに合っていないかを見るため |
| パラメータ依存性 | 過剰最適化を避けるため |
バックテスト結果は将来の利益を保証しません。
バックテストは、ロジックの挙動を確認するための検証工程です。
8.1 フィルター単体の確認
トレンドフィルターを追加したら、次のように段階的に確認します。
- フィルターなしの売買ロジックを確認する。
- 移動平均線フィルターだけを追加する。
- ADXまたはATRを追加する。
- 上位足フィルターを追加する。
- 取引回数とドローダウンの変化を見る。
一度に複数の条件を追加すると、どの条件が結果に影響したのか分かりにくくなります。
9. フォワードテストで確認すべき項目
【結論】
フォワードテストでは、バックテストで見えにくい約定差、スプレッド拡大、VPS環境、ブローカー差を確認します。
実運用前には、デモ環境または小さな条件で挙動を観察する必要があります。
フォワードテストでは、次の項目を確認します。
- 約定価格が想定から大きくずれていないか
- スプレッド拡大時に注文を停止できているか
- 取引頻度がバックテストと大きく違わないか
- ドローダウンが想定範囲に収まっているか
- ブローカーの取引条件でロットやストップが拒否されないか
- VPS環境でEAが安定して動くか
- デモ口座とリアル口座の約定条件差を考慮できているか
フォワードテストは、バックテストの結果をそのまま信用するための手続きではありません。
フォワードテストは、実際の取引環境に近い条件でEAの挙動を確認する工程です。
10. 実運用での注意点
【結論】
実運用では、フィルター判定が正しくても、スプレッド、約定、証拠金、口座タイプによって結果が変わります。
EAの設計では、売買ロジックとリスク制御を必ず分けます。
実運用では、次の点に注意します。
- スプレッド拡大で成績が悪化する場合がある
- 約定遅延やスリッページが発生する場合がある
- レバレッジが高いほどドローダウンも大きくなりやすい
- 最小ロット、最大ロット、ロットステップを確認する必要がある
- ストップレベルやフリーズレベルにより注文が通らない場合がある
- netting口座とhedging口座でポジション管理が変わる
- 銘柄の取引時間や取引条件によりEAの挙動が変わる
10.1 ロット計算との接続
トレンドフィルターだけでEAのリスクは管理できません。
実運用では、ロット計算と損切り幅を別に設計します。
| ロット方式 | 特徴 | 注意点 |
|---|---|---|
| 固定ロット | 実装が簡単 | 資金変動に対応しにくい |
| 残高比例 | 資金に応じて調整しやすい | 急な損失後の変化に注意 |
| リスク率ベース | 許容損失から計算しやすい | 損切り幅と銘柄仕様の確認が必要 |
| ボラティリティ調整 | ATRなどを使いやすい | パラメータ依存が強くなりやすい |
ロット計算では、最小ロット、最大ロット、ロットステップ、証拠金、ティックバリュー、ティックサイズを確認します。
11. 改善案と代替手段
【結論】
トレンドフィルターを改善するときは、条件を増やす前に、役割の重複を確認します。
同じ意味の条件を重ねると、見かけ上のバックテスト成績だけが良くなる場合があります。
改善案としては、次の方法があります。
- 移動平均線の期間を固定しすぎず、複数期間で挙動を確認する
- ADXを方向判定ではなく強さ判定として使う
- ATRを低ボラティリティ回避に限定する
- 上位足フィルターの有無で取引回数を比較する
- フィルターごとにログを出して除外理由を確認する
- エントリー条件と決済条件を別々に評価する
代替手段として、トレンド判定を使わず、時間帯フィルター、スプレッドフィルター、ボラティリティフィルターだけで取引環境を制限する方法もあります。
どの方法が適するかは、EAの目的、銘柄、時間足、検証条件によって変わります。
12. まとめ
【結論】
MQL5のトレンドフィルター設計では、方向、強さ、変動幅、時間軸を分けて考えることが重要です。
インジケータ値はハンドルを作成し、CopyBufferで取得し、取得失敗時は判定を止める必要があります。
トレンドフィルターは、EAの売買シグナルを相場環境に合わせて制限するための仕組みです。
移動平均線、ADX、ATR、上位足確認は、それぞれ役割が違います。
実運用では、バックテストとフォワードテストの差、スプレッド、約定条件、ブローカー仕様、口座タイプを考慮します。
バックテスト結果は将来の利益を保証しないため、段階的な検証とリスク管理が必要です。
FAQ
Q1. MQL5のトレンドフィルターとは何ですか?
MQL5のトレンドフィルターとは、EAの売買シグナルを相場の方向性や強さに合わせて制限する仕組みです。
エントリー条件そのものではなく、エントリーしてよい環境かを判定する役割を持ちます。
Q2. 移動平均線だけでトレンドフィルターは作れますか?
移動平均線だけでも基本的な方向判定は作れます。
ただし、レンジ相場ではだましが出やすいため、ADXやATRなどで補助する設計も検討します。
Q3. MQL5でインジケータ値を取得するときの注意点は何ですか?
MQL5では、インジケータハンドルを作成し、CopyBufferでバッファ値を取得する流れになります。
取得件数が不足した場合は、売買判定を中止する設計が必要です。
Q4. トレンドフィルターを増やすほどEAは安定しますか?
フィルターを増やすほど安定するとは限りません。
条件が多すぎると取引回数が減り、過剰最適化の原因になる場合があります。
Q5. バックテストでは何を確認すべきですか?
バックテストでは、総損益だけでなく、最大ドローダウン、取引回数、連敗数、スプレッド条件、パラメータ依存性を確認します。
バックテスト結果は将来の利益を保証しません。
Q6. フォワードテストでは何を確認すべきですか?
フォワードテストでは、約定差、スプレッド拡大、取引頻度、ドローダウン、VPS環境での安定性を確認します。
バックテストと実運用に近い環境では、結果が異なる場合があります。
Q7. トレンドフィルターと注文処理は分けるべきですか?
トレンドフィルターと注文処理は分けるべきです。
フィルターは取引方向の許可を返し、注文処理ではOrderCheck、ロット、証拠金、スプレッドなどを別に確認します。