ブレイクアウトEAの作り方|高値更新ロジックをMQL4で実装【サンプルコード付き】

ブレイクアウトEAのエントリーポイント
EAサンプル・ノウハウ
記事内に商品プロモーションを含む場合があります
スポンサーリンク

「レンジ上限を抜けた瞬間だけ自動で入りたい」
「直近高値・安値のブレイクをEAロジックに落とし込みたい」
そんな方に向けて、本記事では直近高値・安値更新(ブレイクアウト)型EAの作り方を、MQL4サンプルコード付きで解説します。

ブレイクアウトは、相場が停滞(レンジ)から抜けて値動きが加速する初動を狙える一方、ヒゲや一時的な抜けで「ダマシ」が起こりやすいのも特徴です。
そこで今回は、まず「直近N本の高値・安値」を終値で更新したらエントリーという、EA化しやすい王道ロジックをベースに実装していきます。

また、当サイト共通のEAベースソース(00_BASE)にロジックを差し込む形式で作るため、今後の拡張(ATR/ボリンジャー/ADXフィルター追加)も簡単です。
まずは「ブレイク判定をどう書くか」を確実に理解して、自作EAの土台にしてください。

📘 この記事で解説する内容
  • 直近高値・安値の取得方法(iHighest() / iLowest()
  • 終値ベースのブレイク判定ロジック(ダマシ軽減の基本)
  • エントリー条件の実装(BUY/SELL)
  • TP/SLの基本設計(固定pipsの最小構成)
  • フィルター拡張の考え方(ATR・ボリンジャー・ADX・時間帯)

📈 ブレイクアウトとは?

ブレイクアウトとは、重要な高値・安値(レンジ上限・下限)を価格が抜けたタイミングでエントリーし、相場の「加速(勢い)」を狙う手法です。
レンジ相場で溜まったエネルギーが、上抜け・下抜けをきっかけに一方向へ放出される局面を取るイメージになります。

裁量トレードでは「抜けたっぽい」「勢いが出た」といった感覚判断になりがちですが、EAではブレイクを数値条件に落とし込み、検証できる形にできます。
本記事ではその最小構成として、直近N本の高値・安値を“終値”で更新したらエントリーする王道ロジックを採用します。

    ブレイクアウトはシンプルな反面、ヒゲや一時的な抜けによる「ダマシ」が起こりやすいのも事実です。
    そのため本記事では、まず終値ベース(確定足)でブレイクを判定し、基本形として堅めに実装します。
    慣れてきたら、ATR・ボリンジャーバンド・ADX・時間帯などのフィルターを足して、取引環境に合わせて精度を上げていくのが王道です。


    EAの概要とポイント

    • 直近N本の高値・安値を基準にブレイク判定
    • 終値(確定足)での更新のみエントリー
    • ポジションは1つのみ(シンプル構成)
    • TP/SLは固定pips(まずは最小構成)
    • 当サイト共通ベースソース(00_BASE)にロジックを差し込み

    本EAは、最も基本的なブレイクアウト構造を実装したサンプルです。
    まずはロジックを明確に理解することを目的とし、フィルターはあえて入れていません。

    ブレイクアウトは「勢いを取る手法」ですが、同時にダマシも多いため、検証前提で段階的に改良していく設計が重要です。
    本記事ではまず、検証可能な最小構成を作成します。


    エントリーロジック解説

    買いエントリー(ロング)

    • 直近N本の最高値を取得
    • 直近確定足の終値がその最高値を上回った
    • → BUYエントリー

    売りエントリー(ショート)

    • 直近N本の最安値を取得
    • 直近確定足の終値がその最安値を下回った
    • → SELLエントリー

    ポイントは「終値で判定している」点です。
    ヒゲだけの一時的な抜けでエントリーしないようにするため、確定足ベースで条件を固定しています。

    また、ポジションは常に1つのみとし、シンプルな構造にすることで、まずは純粋なブレイクアウトの性質をバックテストで確認できるようにしています。

    買いエントリー(ロング)の実例:

    ブレイクアウトEA ロングエントリー例

    直近レンジ上限を終値で更新したタイミングでBUYエントリーしています。 同一方向の連続エントリーは制限しています。


    ⚠️ 注意点

    • レンジ相場ではダマシが多発します
    • ヒゲだけの一時的な抜けに注意
    • ボラティリティ不足時は伸びにくい
    • 経済指標前後はスリッページに注意
    • 新しいローソク足が形成された際に1回だけ処理を実行する設計です
    • マジックナンバーは考慮していません。(このEA単独で動かしてください)

    ブレイクアウトは「勢い」を取る手法ですが、すべての抜けが伸びるわけではありません
    特にレンジ幅が小さい状態や、相場参加者が少ない時間帯では、抜けてもすぐ戻るケースが多くなります。

    本記事では終値ベース(確定足)でブレイクを判定していますが、それでもダマシは完全には防げません。
    より精度を高めたい場合は、以下のようなフィルター追加を検討してください。

    • ATRで一定以上のボラティリティがあるか確認する
    • ボリンジャーバンドの拡大局面のみエントリーする
    • ADXでトレンド強度を確認する
    • 東京時間を避けるなど時間帯制限を入れる

    ブレイクアウトEAは、「単体で完成」させるよりも、フィルターと組み合わせて進化させる前提のロジックです。
    まずは基本形でバックテストを行い、その後に段階的に条件を追加していくことをおすすめします。


    ダウンロード

    EAファイルのダウンロードはこちら👇

    📥 ブレイクアウトEA をダウンロード

    \ 国内最大級のEAプラットフォーム /
    GogoJungle(ゴゴジャン)でEAの評価・レビューをチェック!

    ▶ GogoJungleでEAを探す ブレイクアウトEAの作り方|高値更新ロジックをMQL4で実装【サンプルコード付き】

    📜 ブレイクアウトEAのサンプルコード

    以下にMQL4サンプルコードを掲載します。
    そのままコピーしてMT4(MetaEditor)に貼り付ければコンパイル可能で、動作確認も済んでいます。

    //+------------------------------------------------------------------+
    //|                                                  32_BreakOut.mq4 |
    //|                                    Copyright © 2020-2026 ぷろぐらむFX |
    //|                                             https://www.mql5.com |
    //+------------------------------------------------------------------+
    #property copyright "Copyright © 2020-2026 ぷろぐらむFX"
    #property link      "https://www.mql5.com"
    #property version   "1.00"
    #property strict
    
    
    input double Lots = 0.01;              //ロット
    input int TP = 30;                    //利確(pips)
    input int SL = 30;                    //損切り(pips)
    //***【パラメータ設定↓】***//
    // ここにパラメータ設定を追加してください
    input int BreakPeriod = 22;               // ブレイク判定本数
    input bool SameDirectionBlock = true;     // 同一方向の再エントリー禁止
    int lastDirection = 0;   // 1=BUY -1=SELL
    //***【パラメータ設定↑】***//
    
    string Ea_Name = WindowExpertName();   //チャート上のEA名称を取得(オーダーコメントに使用)
    
    double PipValue;                       //ブローカー桁数に対応した Point 補正
    datetime prevtime;                     //ローソク足時間保持用
    //+------------------------------------------------------------------+
    //| Expert initialization function                                   |
    //+------------------------------------------------------------------+
    int OnInit(){
    
       //デジットチェック
       if (Digits == 3 || Digits == 5){
          PipValue = Point * 10;   // 例: EURUSD 1.23456 → 1pip = 0.00010
       }else{
          PipValue = Point;        // 例: USDJPY 123.45 → 1pip = 0.01
       }
    
       return(INIT_SUCCEEDED);
    }
    //+------------------------------------------------------------------+
    //| Expert deinitialization function                                 |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason){
    
    }
    //+------------------------------------------------------------------+
    //| Expert tick function                                             |
    //+------------------------------------------------------------------+
    void OnTick(){
    
       int total = OrdersTotal();    //ポジショントータル数をセット  
       int ea_order_Type = -1; //0:OP_BUY  1:OP_SELL
       double ea_order_stop_price = 0; //ストップロスレート
       double ea_order_good_price = 0; //利確レート
    
       //新しい足ができた時だけやる
       if(Time[0] != prevtime){
          prevtime = Time[0];  
       }else{
          return;
       }
    
       //ポジションがない場合はエントリー判定
       if(total == 0){
    
          bool openBuy  = false;    //買い新規注文判断
          bool openSell = false;    //売り新規注文判断
          
    //***【新規注文判断↓】***//
          // 2本前までの最高値を取得
          double highestPrice = High[
             iHighest(NULL, 0, MODE_HIGH, BreakPeriod, 2)
          ];
          
          double lowestPrice = Low[
             iLowest(NULL, 0, MODE_LOW, BreakPeriod, 2)
          ];
          
          // 1本前がブレイクしたか判定
          bool breakUp = (Close[1] > highestPrice);
          bool breakDown = (Close[1] < lowestPrice);
    
          if(SameDirectionBlock)
          {
             // 同一方向禁止
             if(lastDirection == 1)
                breakUp = false;
             
             if(lastDirection == -1)
                breakDown = false;
          }
    //***【新規注文判断↑】***//
    
          //参照するサンプルEAの買いエントリーフラグをセットしてください
          if(breakUp){
             openBuy =true;
             ea_order_Type = OP_BUY;
          //参照するサンプルEAの売りエントリーフラグをセットしてください      
          }else if(breakDown){
             openSell =true;
             ea_order_Type = OP_SELL;
          }
    
    //***【TP/SL判断↓】***//
    // TP/SLを変更したい場合はこの部分を変更してください。
    // 例:移動平均線のTP/SLを使いたい場合は書き換え
          if(openBuy){
             ea_order_stop_price = Ask - SL * PipValue;
             ea_order_good_price = Ask + TP * PipValue;
          }else if(openSell){
             ea_order_stop_price = Bid + SL * PipValue;  
             ea_order_good_price = Bid - TP * PipValue;   
          }
    //***【TP/SL判断↑】***//
    
          if(ea_order_Type > -1){
             bool ok = funcOrder_Send(ea_order_Type, ea_order_stop_price, ea_order_good_price,Lots, Ea_Name, 777, 0);
             
             if(ok){
                lastDirection = (ea_order_Type == OP_BUY ? 1 : -1);
             }  
          }
    
       }
    
       return;
    }
    
    
    //★★★★★★★★★★★★★★★★★★★★ ここから下は共通関数 ★★★★★★★★★★★★★★★★★★★★
    //+------------------------------------------------------------------+
    //|【関数】新規注文関数
    //|
    //|【引数】 orderType:売買(0=BUY, 1=SELL)
    //|【引数】 sl:損切り価格  tp:利確価格
    //|【引数】 lots:取引ロット数
    //|【引数】 orderComment:オーダーコメント
    //|【引数】 magic:マジックNo
    //|【引数】 maxSpreadPips: 許容スプレッド[Point] (0=制限なし)
    //|
    //|【戻値】true=成功 false=失敗
    //+------------------------------------------------------------------+
    bool funcOrder_Send(int orderType, double sl, double tp, double lots,
                        string orderComment, int magic, int maxSpreadPoints){
       int    ticket = -1;
       double price  = 0;
       color  clr    = clrNONE;
       double spread = 0;
    
       // 最大10回リトライ
       for(int retry=0; retry<10; retry++)
       {
          RefreshRates();
          
          // スプレッド取得(MT4表示と同じポイント単位)
          spread = MarketInfo(Symbol(), MODE_SPREAD);
    
          // スプレッドチェック(maxSpreadPoints=0 の場合はスキップ)
          if(maxSpreadPoints > 0 && spread > maxSpreadPoints){
             Print("スプレッド拡大中(", spread,
                   "ポイント) → 待機中 (リトライ=", retry+1, ")");
             Sleep(2000);
             continue;
          }
    
          // エントリー価格と色を決定
          if(orderType == OP_BUY){
             price = Ask;
             clr   = clrBlue;
          }else if(orderType == OP_SELL){
             price = Bid;
             clr   = clrRed;
          }
    
          ticket = OrderSend(Symbol(), orderType, lots, price,
                             20, sl, tp, orderComment, magic, 0, clr);
    
          if(ticket > 0){
             Print("新規注文成功! チケットNo=", ticket,
                   " レート=", price, " Lots=", lots,
                   " スプレッド=", spread, "ポイント");
             return true;
          }else{
             int err = GetLastError();
             Print("新規注文失敗 エラーNo=", err,
                   " リトライ回数=", retry+1);
             Sleep(2000);
          }
       }
    
       return false;
    }
     

    📌 iHighest() / iLowest() 関数の解説

    ブレイクアウトEAでは、直近の高値・安値を取得するために MT4標準関数 iHighest()iLowest() を使用しています。

    これらの関数は「指定本数内で最も高い価格・最も安い価格のバー番号(インデックス)」を取得するための関数です。

    ■ iHighest() の基本構文

    
    int index = iHighest(NULL, 0, MODE_HIGH, 20, 1);
    

    引数の意味

    • 引数1:通貨ペア(NULLで現在チャート)
    • 引数2:時間足(0で現在足)
    • 引数3:価格種別(MODE_HIGH / MODE_LOW など)
    • 引数4:検索本数(例:20本)
    • 引数5:開始シフト(1=確定足から)

    上記コードでは「直近20本の確定足の中で最も高い高値」を持つバー番号を取得しています。


    ■ iLowest() の基本構文

    
    int index = iLowest(NULL, 0, MODE_LOW, 20, 1);
    

    こちらは「直近20本の中で最も安い安値」を取得します。


    ■ インデックスから価格を取得する方法

    iHighest / iLowest が返すのは「価格」ではなく「バー番号」です。 そのため、実際の価格は以下のように取得します。

    
    double highestPrice = High[index];
    double lowestPrice  = Low[index];
    

    この仕組みにより、

    • 過去レンジの上限ライン
    • 過去レンジの下限ライン
    • ボックス相場の上抜け判定

    といったロジックを実装できます。


    ■ ブレイクアウト判定の考え方

    本記事のEAでは、

    
    bool breakUp   = (Close[1] > highestPrice);
    bool breakDown = (Close[1] < lowestPrice);
    

    という形で、直近レンジの高値・安値を終値で更新したかどうかを判定しています。

    より厳密に「抜けた瞬間のみ」を検出したい場合は、 前足との比較条件を追加することで拡張可能です。


    ▶ iHighest / iLowest は、 ブレイクアウトEAだけでなく、 ドンチャンチャネル・レンジ判定・逆張りロジックなど 応用範囲の広い重要関数です。


    パラメータとカスタマイズ

    今回のブレイクアウトEAで使用しているパラメータは以下の通りです。

    • 取引ロット数(Lots):0.01で約1,000通貨相当
    • 利確(TP):固定pips指定
    • 損切り(SL):固定pips指定
    • ブレイク判定本数(BreakPeriod):直近◯本の高値・安値を基準にする
    • 同一方向の再エントリー禁止:同一方向の連続エントリーを禁止する

    ■ BreakPeriod の考え方

    BreakPeriodは「どれくらいのレンジを抜けたらブレイクとみなすか」を決める重要パラメータです。 値を小さくすると短期ブレイク、大きくすると中期レンジブレイクになります。

    • 小さい値(例:10) → 短期ブレイク検出・エントリー頻度増加
    • 大きい値(例:50) → 中期レンジブレイク・エントリー回数減少

    時間足によって最適値は変わります。 M15では20前後、H1では30〜50程度が一般的な検証開始ラインです。


    ■ TP / SL の調整について

    本EAではシンプルな固定pips型を採用しています。

    ブレイクアウトは「伸びる時は伸びる」特性があるため、

    • RR1:1の安定型
    • RR1:2以上のトレンド追随型
    • トレーリングストップ導入型

    など、目的に応じて調整可能です。


    ■ カスタマイズ例

    以下のような拡張も可能です:

    • ATRフィルターでボラティリティ確認
    • 時間帯制限(ロンドン・NYのみ)
    • ダマシ回避のための移動平均フィルター追加
    • ブレイク後の押し目エントリー化

    まずは基本形でバックテストを行い、 挙動を理解してからフィルターを追加することを推奨します。

    EAバックテストレポート

    USDJPY(M15, 2025/01〜2026/01, 初期証拠金50万円, FXTFヒストリカル)での結果:

    通貨ペア・時間足PF勝率最大DD取引回数備考
    USDJPY M151.1152%1.1%1115回シンプルロジックだがしっかりと利益を出せている
    ブレイクアウトEAバックテストレポート

    ※ 本検証は固定TP/SL・フィルター無しの最小構成です。実運用には追加検証を推奨します。

    まとめ

    ブレイクアウトEAは、直近レンジの高値・安値を抜けた瞬間の「勢い」を取りにいく、非常にシンプルで再現性の高いロジックです。

    本記事では、

    • iHighest() / iLowest() を使った高値・安値の取得方法
    • 終値ベースでのブレイク判定ロジック
    • 固定TP/SLによる最小構成
    • 同一方向の連続エントリー禁止設計

    といったEA化の基本構造を、サンプルコード付きで解説しました。


    今回のロジックは、あえてフィルターを入れていない純粋なブレイクアウトの原型です。

    バックテスト結果からも分かる通り、シンプルな構造でも一定の優位性は確認できますが、 ブレイクアウトは「ダマシ」と常に隣り合わせです。

    そのため、

    • ATRによるボラティリティ確認
    • ADXによるトレンド強度フィルター
    • ボリンジャーバンド拡大型のみエントリー
    • 時間帯制限の導入

    などを組み合わせることで、ロジックはさらに進化させることができます。


    EA開発において重要なのは、いきなり複雑にしないことです。

    まずは今回の基本形でバックテストを行い、

    • どの時間足で伸びやすいか
    • どの通貨でダマシが多いか
    • TP/SL比率を変えるとどうなるか

    を確認してから、段階的にフィルターを追加していきましょう。


    ブレイクアウトは、裁量では感覚になりがちな「抜け」を、 数値条件に落とし込み、検証できる形にできる優れたロジックです。

    今回のサンプルEAを土台に、ぜひあなた自身のブレイクアウト戦略へ発展させてみてください。


    コメント

    タイトルとURLをコピーしました