MT4でパラボリックSAR EAを作成|無料MQL4サンプルコード解説

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

はじめに

「パラボリックSARを使った順張りロジックを、FX自動売買EAとして自動化したい!」という方向けに、この記事では MT4(MQL4)で動作する無料EAサンプルコード を紹介します。初心者でもコピペで動かせるので、学習用や実験用に最適です。

パラボリックSARは、トレンドの転換点を見極める有効なインジケータで、裁量トレードでも人気があります。本記事では、それをEA化して自動エントリーさせる方法を実装していきます。


📈 パラボリックSARとは?

パラボリックSAR(Parabolic Stop and Reverse)は、MT4でも標準搭載されているトレンドフォロー型のインジケーターです。チャート上に点(ドット)を表示し、価格の下に出れば上昇トレンド、上に出れば下降トレンドを示します。

つまり、ドットが 上下で切り替わった瞬間がエントリーサイン になります。ただ、ダマシもある為今回はパラメータ設定で何個目のドットが出てからエントリーという形にしました。


EAの概要とポイント

  • iSAR(MT4標準インジケータ)を使って自動判定
  • パラメータ設定で何個目のドットが出てから売買エントリー
  • 利確・損切は切り替わりタイミング又はTP/SL
  • パラメータ(ステップ・上限)をカスタマイズ可能

エントリーロジック解説

  • 買いエントリー:直近のドットがローソク足の下が続く → 上昇トレンド開始と判断してBUY
  • 売りエントリー:直近のドットがローソク足の上が続く → 下降トレンド開始と判断してSELL

👉 シンプルなので、裁量の補助としても活用可能です。


⚠️ 注意点

  • パラボリックはトレンド相場で有効ですが、レンジ相場ではダマシが多発します。
  • 今回は単独で使用していますが、複数インジケーター(移動平均など)を組み合わせると精度が上がります。
  • 新しいローソク足が出来た際に1度だけ処理を実行する作りになっています。
  • マジックナンバーは考慮していません。(このEA単独で動かしてください)

移動平均線のEAサンプルはこちら


ダウンロード

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

“パラボリックEA” をダウンロード 28_Parabolic-2.ex4 – 1 回のダウンロード – 12.29 KB

📜 パラボリックEAのサンプルコード解説

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

//+------------------------------------------------------------------+
//|                                                 28_Parabolic.mq4 |
//|                                Copyright © 2020-2025 ぷろぐらむFX |
//|                                             https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020-2025 ぷろぐらむFX"
#property link      "https://fx-prog.com/"
#property version   "1.00"
#property strict


input double Lots = 0.01;              //ロット
input int TP = 100;                    //利確(pips)
input int SL = 100;                    //損切り(pips)
//***【パラメータ設定↓】パラボリック***//
input double PARA_STEP = 0.02;         //パラボリックのステップ
input double PARA_UPPER = 0.2;         //パラボリックの上限
input int PARA_ENTRY_DOT_COUNT = 4;    //エントリードット数(1~任意)
input int PARA_CLOSE_DOT_COUNT = 2;    //決済ドット数(1~任意)
//***【パラメータ設定↑】パラボリック***//

string Ea_Name = "Parabolic";          //オーダーコメントに使用

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();    //ポジショントータル数をセット  
double ea_order_stop_price=0; //ストップロスレート
double ea_order_good_price=0; //利確レート

//---
   //新しい足ができた時だけやる
   if(Time[0] != prevtime){
      prevtime = Time[0];
   }else{
      return;
   }

   bool closeBuy  = false;    //買いポジション決済判断
   bool closeSell = false;    //売りポジション決済判断
//***【決済注文判断↓】***//

   bool isBullSAR_C = true;
   bool isBearSAR_C = true;

   //決済注文チェック
   for (int i = 0; i < PARA_CLOSE_DOT_COUNT; i++)
   {
      double sarVal   = iSAR(NULL, 0, PARA_STEP, PARA_UPPER, i);
      double priceVal = iClose(NULL, 0, i);
   
      if (priceVal <= sarVal) isBullSAR_C = false; // SARより下に行ったら買い否定
      if (priceVal >= sarVal) isBearSAR_C = false; // SARより上に行ったら売り否定
   }

//***【決済注文判断↑】***//
   
   //参照するサンプルEAの買いポジション決済フラグをセットしてください
   if(isBearSAR_C){
      closeBuy =true;
      
   //参照するサンプルEAの売りポジション決済フラグをセットしてください
   }else if(isBullSAR_C){
      closeSell =true;
   }

   if(total > 0){
      if(closeBuy){
         //決済(買いポジション)
         funcOrder_CloseAll(OP_BUY, -1, 0);
      }else if(closeSell){
         //決済(売りポジション)
         funcOrder_CloseAll(OP_SELL, -1, 0);
      }
   }


   bool openBuy  = false;    //買い新規注文判断
   bool openSell = false;    //売り新規注文判断
//***【新規注文判断↓】***//

   bool isBullSAR_S = true;
   bool isBearSAR_S = true;
   
   //新規注文チェック
   for (int i = 0; i < PARA_ENTRY_DOT_COUNT; i++)
   {
      double sarVal   = iSAR(NULL, 0, PARA_STEP, PARA_UPPER, i);
      double priceVal = iClose(NULL, 0, i);
   
      if (priceVal <= sarVal) isBullSAR_S = false; // SARより下に行ったら買い否定
      if (priceVal >= sarVal) isBearSAR_S = false; // SARより上に行ったら売り否定
   }

//***【新規注文判断↑】***//

   //参照するサンプルEAの買いエントリーフラグをセットしてください
   if(isBullSAR_S){
      openBuy =true;
      
   //参照するサンプルEAの売りエントリーフラグをセットしてください      
   }else if(isBearSAR_S){
      openSell =true;
   }


   total=OrdersTotal();
   
   if(total == 0){
      if(openBuy){
         ea_order_stop_price = Ask - SL * PipValue;
         ea_order_good_price = Ask + TP * PipValue;
         
         //新規注文(買い)
         funcOrder_Send(OP_BUY,ea_order_stop_price,ea_order_good_price,Lots,Ea_Name,777,0);
      }else if(openSell){
         ea_order_stop_price = Bid + SL * PipValue;  
         ea_order_good_price = Bid - TP * PipValue;
         
         //新規注文(売り)
         funcOrder_Send(OP_SELL,ea_order_stop_price,ea_order_good_price,Lots,Ea_Name,777,0);
      }      
   }

   
   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;
}
     
//+------------------------------------------------------------------+
//|【関数】全決済関数                                                 |
//|                                                                  |
//|【引数】 orderType : -1=すべて  0=BUYのみ  1=SELLのみ             |
//|【引数】 magic: 対象マジック番号 (-1=全マジック対象)               |
//|【引数】 maxSpreadPoints: 許容スプレッド[Point] (0=制限なし)       |
//|                                                                  |
//|【戻値】true=全成功 false=一部失敗あり                             |
//+------------------------------------------------------------------+
bool funcOrder_CloseAll(int orderType, int magic, int maxSpreadPoints)
{
   bool allSuccess = true;
   int totalOrders = OrdersTotal();
   double spread, closePrice, lots;
   int type, ticket;
   color  clr    = clrNONE;

   for(int i = totalOrders-1; i >= 0; i--)
   {
      //オーダーセレクト失敗でスキップ
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      
      // 同一シンボル以外はスキップ
      if(OrderSymbol() != Symbol()) continue;

      // マジック番号指定がある場合は一致しないものをスキップ
      if(magic != -1 && OrderMagicNumber() != magic) continue;

      type   = OrderType();
      ticket = OrderTicket();
      lots   = OrderLots();

      // orderType指定でフィルタ
      if(orderType == 0 && type != OP_BUY) continue;
      if(orderType == 1 && type != OP_SELL) continue;

      // 最大10回リトライ
      bool result = false;
      for(int retry=0; retry<10; retry++)
      {
         RefreshRates();

         // スプレッド取得
         spread = MarketInfo(Symbol(), MODE_SPREAD);

         if(maxSpreadPoints > 0 && spread > maxSpreadPoints)
         {
            Print("スプレッド拡大中(", spread,
                  "ポイント) → クローズ待機中 ticket=", ticket,
                  " リトライ=", retry+1);
            Sleep(2000);
            continue;
         }

         // クローズ価格決定
         if(type == OP_BUY){
            closePrice = Bid;
            clr   = clrBlue;
         }else if(type == OP_SELL){
            closePrice = Ask;
            clr   = clrRed;
         }

         result = OrderClose(ticket, lots, closePrice, 20, clr);

         if(result){
            Print("クローズ成功! チケットNo=", ticket,
                  " ロット=", lots, " クローズ価格=", closePrice,
                  " スプレッド=", spread, "ポイント");
            break;
         }else{
            int err = GetLastError();
            Print("クローズ失敗 ticket=", ticket,
                  " エラーNo=", err,
                  " リトライ=", retry+1);
            Sleep(2000);
         }
      }

      if(!result) allSuccess = false;
   }

   return allSuccess;
}

iSAR() 関数の解説

今回のEAでは、MT4標準インジケータであるパラボリックSARを取得するために
iSAR() 関数を使っています。

【使用例】
double dSAR = iSAR(NULL, 0, 0.02, 0.2, 0);

引数の意味

  • 引数1 … 通貨ペア(NULLで現在のチャート)
  • 引数2 … 時間軸(0で現在の時間足)
  • 引数3 … ステップ(加速因子、例: 0.02)
  • 引数4 … 上限(最大値、例: 0.2)
  • 引数5 … バーシフト(0で最新の足、1で1本前の足)

パラボリック利用箇所

  • 75〜82行目 … 決済処理でパラボリック値をチェック
  • 114〜121行目 … 新規注文処理でパラボリック値をチェック

👉 「新規注文のみ」処理したい場合は、決済注文判断(71〜93行目)を削除してください。

パラボリックの売買判定について

パラボリック値がローソク足のクローズ値より上か下かで、売買の判定をしています。

パラボリックEAのトレードイメージ画像
      if (priceVal <= sarVal) isBullSAR_S = false; // SARより下に行ったら買い否定
      if (priceVal >= sarVal) isBearSAR_S = false; // SARより上に行ったら売り否定

この処理を、現在ローソク足から過去ローソク足までパラメータ設定分さかのぼりチェックをしています。さかのぼってfalseにならなければ売り又は買い注文といった感じです。

新規、決済注文について

「新規注文処理」「決済処理」の関数については当サイトの共通関数となっています。どのEAでも使えますのでそのままコピペでお使いください。
👉 EAで使う新規・変更・決済注文関数の解説はこちら


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

今回のパラメータ設定は以下の通りです:

  • 取引ロット数(0.01で1000通貨)
  • パラボリックのステップ(Step/加速因子)
  • パラボリックの上限(Maximum/最大値)
  • エントリードット数(何本連続でSARが出たらエントリーするか)
  • 決済ドット数(何本連続でSARが出たら決済するか)
  • 利確(pips)
  • 損切り(pips)
パラボリックEAのパラメータ設定画像

👉 Stepを小さくすると反応が遅くなり、大きくするとダマシが増えるため調整がポイントです。


EAバックテストレポート

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

通貨ペア・時間足PF勝率最大DD取引回数備考
USDJPY M151.3144%0.85%816回特に2024年10月から好調
パラボリックEAのバックテストレポート画像


まとめ

パラボリックSAR EAはシンプルな順張りロジックで、初心者でも理解しやすい設計です。

  • トレンド相場で強みを発揮
  • 中期足~長期足向け
  • フィルタを追加するとさらに実用的

まずはサンプルコードを試してみて、自分の環境でバックテストを行ってみましょう。フィルタ追加やロジック改良次第で、実用的なEAへと進化させることが可能です。


✅ 他にも多数のEAサンプルを公開中!

今回紹介した内容以外にも、当サイトではさまざまなFX自動売買EAのサンプルコードを提供しています。

自分に合った戦略のEAを見つけたい方は、ぜひチェックしてみてください。


EA開発初心者向けに、今後も実践的なMQL4関数を紹介していきます。
気になる機能やロジックがあれば、ぜひ他の記事もあわせてご覧ください!

コメント