既刊iBWMFIインジケーターの記事では、
Green/Fade/Fake/Squatという4色で、
値動きと出来高の「伴い」を判定する設計を解説しました。
この記事ではその判定結果を発注の起点には使わず、
移動平均のゴールデンクロス・デッドクロスという別の発注条件に、
Fake・Squat(伴いの無い警戒パターン)のときは、
エントリーを見送るフィルターとして組み込むEAを作ります。
・既刊インジケーターの4色判定をEAのフィルターとして関数化する方法
・移動平均クロスという発注条件とフィルターを組み合わせる設計
・Fake/Squatのときだけエントリーを見送る理由
・実際に動くEAのコード全体
設計思想: なぜクロス判定そのものではなくフィルターに使うのか
まず、既刊インジケーターの4色判定を、そのまま発注条件にしない理由を整理します。
既刊iBWMFIインジケーターのおさらい
既刊インジケーターは、
1本前のバーとのBWMFI・出来高の増減を比較し、
Green(伴いのある上昇)・Fade(伴いのある下降)・
Fake(出来高が減っているのに動いた警戒)・
Squat(出来高が増えているのに動かない拮抗)の4色に分類していました。
4色は方向を示さない、信頼度の指標である
・BWMFIは(High-Low)÷Volumeで、常に正の値になる
・そのため4色は「上がるか下がるか」を示していない
・示しているのは「その動きに参加者の裏付けがあるか」という信頼度
・既刊記事のFAQでも「EAのフィルターに使える」と予告していた
方向を示さない指標を、方向を決める発注条件として単体で使うのは筋が悪く、
既にあるトレンド判定の信頼度を補強するフィルターとして使う方が自然です。
ベースの発注条件に移動平均クロスを選んだ理由
このサイトには既にMACD・ストキャスティクス・ボリンジャーバンドなど、
複数のクロス判定型EAがありますが、
最も基本的な2本の移動平均クロス(ゴールデンクロス・デッドクロス)は、
このiBWMFIフィルターの土台として分かりやすいため採用しました。
移動平均クロス+iBWMFIフィルターの判定ロジック
発注の起点となるクロス判定と、フィルターとなる4色判定を、それぞれ用意します。
ゴールデンクロス・デッドクロスの判定
double fastNow = iMA(_Symbol, 0, InpFastMA, 0, MODE_SMA, PRICE_CLOSE, 1); double slowNow = iMA(_Symbol, 0, InpSlowMA, 0, MODE_SMA, PRICE_CLOSE, 1); double fastPrev = iMA(_Symbol, 0, InpFastMA, 0, MODE_SMA, PRICE_CLOSE, 2); double slowPrev = iMA(_Symbol, 0, InpSlowMA, 0, MODE_SMA, PRICE_CLOSE, 2); bool goldenCross = (fastPrev <= slowPrev && fastNow > slowNow); bool deadCross = (fastPrev >= slowPrev && fastNow < slowNow);
確定済みの1本前・2本前のバーを比較し、
短期線が長期線を上下に抜けた瞬間だけを検知します。
iBWMFIの4色判定を関数化する
既刊インジケーターのOnCalculate内にあった判定部分を、
EA用の関数として切り出します。
enum ENUM_BWMFI_PATTERN
{
BWMFI_GREEN,
BWMFI_FADE,
BWMFI_FAKE,
BWMFI_SQUAT
};
ENUM_BWMFI_PATTERN GetBwmfiPattern(int shift)
{
double curMfi = iBWMFI(NULL, 0, shift);
double prevMfi = iBWMFI(NULL, 0, shift + 1);
double curVol = (double)iVolume(NULL, 0, shift);
double prevVol = (double)iVolume(NULL, 0, shift + 1);
bool mfiUp = (curMfi > prevMfi);
bool volUp = (curVol > prevVol);
if(mfiUp && volUp) return(BWMFI_GREEN);
if(!mfiUp && !volUp) return(BWMFI_FADE);
if(mfiUp && !volUp) return(BWMFI_FAKE);
return(BWMFI_SQUAT);
}
インジケーター版はバッファへ値を書き込んでいましたが、
EA版は4色のうちどれに該当するかをENUM値として返すだけにしています。
Fake/Squatのときはエントリーを見送るフィルター
bool IsReliableMove()
{
ENUM_BWMFI_PATTERN pattern = GetBwmfiPattern(1);
return(pattern == BWMFI_GREEN || pattern == BWMFI_FADE);
}
・GreenとFadeは「出来高の裏付けがある動き」としてエントリーを許可する
・FakeとSquatは「裏付けの無い動き」として、クロスが出てもエントリーを見送る
・4色はあくまで経験則的な分類であり、見送った後に相場が動くこともある
既刊インジケーターのFAQで予告されていた「EAのフィルターに使える」という内容を、
この関数で実装しています。
発注条件・損切り・ポジション重複の防止
クロス判定とフィルターを組み合わせ、安全策も合わせて実装します。
買い・売りの発注条件
bool reliable = IsReliableMove(); bool buySignal = (goldenCross && reliable); bool sellSignal = (deadCross && reliable);
クロスが発生し、かつ4色判定がGreenかFadeのときだけ発注対象にします。
損切り・利確を必ず指定する
`sl`(損切り)・`tp`(利確)は発注時点で必ず計算し、未設定のまま放置しません。
ポジション重複を防ぐチェック
bool HasOpenPosition()
{
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) &&
OrderSymbol() == _Symbol && OrderMagicNumber() == InpMagic)
return(true);
}
return(false);
}
同じマジックナンバー・同じ通貨ペアでポジションが既にあるかを確認し、
あれば新規エントリーをスキップします。
実際に動くコード全体
ここまでの要素をまとめた、EAの全体です。
//+------------------------------------------------------------------+
//| BWMFIFilterEA.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
enum ENUM_BWMFI_PATTERN
{
BWMFI_GREEN,
BWMFI_FADE,
BWMFI_FAKE,
BWMFI_SQUAT
};
input int InpFastMA = 10; //短期移動平均の期間
input int InpSlowMA = 30; //長期移動平均の期間
input double InpLots = 0.1; //発注ロット数
input int InpStopLossPips = 300; //損切り(pips)
input int InpTakeProfitPips = 600; //利確(pips)
input int InpMagic = 20261113; //マジックナンバー
datetime lastBarTime = 0;
ENUM_BWMFI_PATTERN GetBwmfiPattern(int shift)
{
double curMfi = iBWMFI(NULL, 0, shift);
double prevMfi = iBWMFI(NULL, 0, shift + 1);
double curVol = (double)iVolume(NULL, 0, shift);
double prevVol = (double)iVolume(NULL, 0, shift + 1);
bool mfiUp = (curMfi > prevMfi);
bool volUp = (curVol > prevVol);
if(mfiUp && volUp) return(BWMFI_GREEN);
if(!mfiUp && !volUp) return(BWMFI_FADE);
if(mfiUp && !volUp) return(BWMFI_FAKE);
return(BWMFI_SQUAT);
}
bool IsReliableMove()
{
ENUM_BWMFI_PATTERN pattern = GetBwmfiPattern(1);
return(pattern == BWMFI_GREEN || pattern == BWMFI_FADE);
}
bool HasOpenPosition()
{
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) &&
OrderSymbol() == _Symbol && OrderMagicNumber() == InpMagic)
return(true);
}
return(false);
}
void OnTick()
{
if(Time[0] == lastBarTime)
return;
lastBarTime = Time[0];
int needed = MathMax(InpFastMA, InpSlowMA) + 5;
if(Bars < needed)
return;
double fastNow = iMA(_Symbol, 0, InpFastMA, 0, MODE_SMA, PRICE_CLOSE, 1);
double slowNow = iMA(_Symbol, 0, InpSlowMA, 0, MODE_SMA, PRICE_CLOSE, 1);
double fastPrev = iMA(_Symbol, 0, InpFastMA, 0, MODE_SMA, PRICE_CLOSE, 2);
double slowPrev = iMA(_Symbol, 0, InpSlowMA, 0, MODE_SMA, PRICE_CLOSE, 2);
bool goldenCross = (fastPrev <= slowPrev && fastNow > slowNow);
bool deadCross = (fastPrev >= slowPrev && fastNow < slowNow);
bool reliable = IsReliableMove();
bool buySignal = (goldenCross && reliable);
bool sellSignal = (deadCross && reliable);
if(HasOpenPosition())
return;
double point = _Point;
if(_Digits == 3 || _Digits == 5)
point *= 10;
if(buySignal)
{
double sl = Bid - InpStopLossPips * point;
double tp = Ask + InpTakeProfitPips * point;
int ticket = OrderSend(_Symbol, OP_BUY, InpLots, Ask, 3, sl, tp,
"BWMFIFilterEA", InpMagic, 0, clrBlue);
if(ticket < 0)
Print("買い発注に失敗しました。エラーコード: ", GetLastError());
}
else if(sellSignal)
{
double sl = Ask + InpStopLossPips * point;
double tp = Bid - InpTakeProfitPips * point;
int ticket = OrderSend(_Symbol, OP_SELL, InpLots, Bid, 3, sl, tp,
"BWMFIFilterEA", InpMagic, 0, clrRed);
if(ticket < 0)
Print("売り発注に失敗しました。エラーコード: ", GetLastError());
}
}
ゴールデンクロス・デッドクロスが発生し、
かつiBWMFIがGreenかFadeのときだけ、新規エントリーが発生します。
MetaEditorでのコンパイル・バックテスト手順
実際に動かすまでの手順です。
- MetaEditorで新規Expert Advisor「BWMFIFilterEA」を作成し、上のコードを貼り付ける
- F7キー(またはコンパイルボタン)でコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- ストラテジーテスターでこのEAを選択し、任意の通貨ペア・期間でバックテストを実行する
- 「結果」タブで、クロス発生時にFake/Squatだったバーが見送られていることを、既刊iBWMFIインジケーターを同時に表示して目視確認する
よくあるエラーと注意点
実際に運用する前に、確認しておきたい点です。
iVolumeがFXでは実出来高ではない
・MT4のiVolumeはティックボリューム(約定件数相当)であり、実際の売買量ではない
・ブローカーによってティックの刻み方が異なるため、同じ通貨ペアでも値が変わる
・あくまで補助的な参考情報として扱う
短期線・長期線の期間を近づけすぎる
InpFastMAとInpSlowMAの差が小さいと、
クロスの発生頻度が増えすぎて、
フィルターの有無に関わらずノイズの多いエントリーになりがちです。
既刊iGator幅フィルターEAと混同する
既刊igator-width-filter-breakout-ea-mt4.mdは、
価格のブレイクアウトをアリゲーターの幅でフィルターする設計でしたが、
本EAは移動平均クロスをiBWMFIの4色でフィルターする設計であり、
ベースの発注条件・フィルターの指標ともに異なります。
既刊のフィルター系EAとの使い分け
似た「フィルター付きEA」の記事が複数あるため、使い分けを整理します。
| 記事 | ベースの発注条件 | フィルター |
|---|---|---|
| 本記事(iBWMFIフィルターEA) | 移動平均クロス | 出来高の裏付け(4色判定) |
| 既刊iGator幅フィルターEA | 価格のブレイクアウト | アリゲーターの口の広がり |
| 既刊ATRボラティリティフィルターEA | 個別記事のベース条件 | 値動きの大きさ |
よくある質問
iBWMFIフィルターEAについて、よくある疑問に回答します。
Fake/Squatのときに見送るのはなぜですか?
Fakeは出来高が減っているのに値幅が広がっている状態、
Squatは出来高が増えているのに値幅が広がらない状態で、
いずれも「価格の動きに参加者の裏付けが伴っていない」警戒パターンだからです。
GreenとFadeを両方許可するのはなぜですか?
Greenは上昇方向、Fadeは下降方向の「伴いのある動き」を示すため、
クロスの方向を問わず、どちらも裏付けのある状態として許可しています。
フィルターを外した場合との比較はできますか?
IsReliableMove()の呼び出し部分をtrueに置き換えれば、
フィルター無しの単純な移動平均クロスEAとして動作するため、
バックテストで有無の差を比較できます。
【MQL4】iBWMFIの4色判定をEAのフィルターに使う作り方(Fake/Squatのときはエントリーを見送る設計):まとめ
この記事では、既刊iBWMFIインジケーターの4色判定を発注の起点にせず、
移動平均クロスという発注条件に、
出来高の裏付けがあるかどうかのフィルターとして組み込むEAを解説しました。
BWMFIが方向を示さない指標であることを踏まえ、
Green/Fadeのときだけクロスを許可し、
Fake/Squatのときは見送るという設計にしています。
損切り必須・ポジション重複防止という最低限の安全策を備えた上で、
IsReliableMove()の呼び出しを外すだけで、
フィルター無し版との比較もできる構成にしています。
コメント