1日の損失額だけを監視するEAを作っていても、1日ごとの損失は上限内に収まっているのに、

その負けが数日続いて資産が気づかないうちに大きく減っていた、

という経験はないでしょうか。

これは「1日単位」の監視だけでは、

複数日にわたって積み重なる下落(ドローダウン)を、

捉えられないために起こります。

この記事では、資産の最高値(ピーク)からどれだけ下落したかを%で常に監視し、

一定の割合を超えたら新規エントリーだけを自動で止めるEAの作り方を解説します。

この記事で分かること
・ドローダウンを「ピーク比の%」で考える理由
・GlobalVariableでピーク資産を記憶する設計
・既刊の1日単位の損失上限EAとの違い
・端末再起動後もピークを引き継ぐ注意点

なぜ「1日の損失額」だけでは資産を守れないのか

まず、このEAが解決する問題を確認します。

1日単位の監視は「日をまたぐ連敗」に弱い

1日の損失が上限未満でも、その負けが3日、5日と連続すれば、

資産全体は着実に減っていきます。

既刊daily-loss-limit-close-all-ea-mt4.mdとの違い

既刊記事は「1日の含み損の合計額」が固定の金額を超えたら全決済する設計でしたが、

本記事は「資産の最高値からの下落率」という、日をまたいで累積する指標を使います。

本記事は強制決済しない設計である

既刊記事とは異なり、本記事は既存ポジションを強制的に決済しません。

新規エントリーだけを止め、今あるポジションの管理はトレーダー自身の判断に委ねる設計です。

ドローダウンを「ピーク比の%」で考える

ドローダウンの考え方を確認します。

固定金額ではなく比率で見る理由

用語補足
・ドローダウン=ピーク資産からの下落額
・ピーク比の%なら口座残高が増減しても
・同じ設定を使い回せる

ピーク資産はAccountEquity()の最大値

ピーク資産は、口座残高(Balance)ではなく、

未決済の損益を含む有効証拠金(Equity)の、

これまでの最大値として追跡します。

ドローダウン率の計算式

ドローダウン率(%) = (ピーク資産 - 現在のEquity) / ピーク資産 * 100

この値が入力パラメーターの上限を超えたときに、新規エントリーを止める判定を行います。

GlobalVariableでピーク資産を記憶する設計

端末再起動後もピークを引き継ぐための設計を確認します。

なぜ変数ではなくGlobalVariableを使うのか

通常の変数はEAの再起動やMT4の終了でリセットされますが、

GlobalVariableは端末を閉じても一定期間値が保持されます。

GlobalVariableSet/GlobalVariableGetの書式

double GlobalVariableSet(string name, double value);
double GlobalVariableGet(string name);
bool   GlobalVariableCheck(string name);

GlobalVariableCheckで変数が既に存在するか確認し、

無ければAccountEquity()の現在値で初期化します。

変数名の衝突に注意する

注意
・GlobalVariableは端末内の全EAで共有される
・名前にSymbol()等を含めて他EAと衝突を避ける
・既刊globalvariableset-get-mt4.mdも参照

EA全体の設計

実際にピーク追跡とエントリー停止判定を組み立てます。

OnInitでピーク変数を準備する

gvKey = "DD_Peak_" + Symbol();
if(!GlobalVariableCheck(gvKey))
   GlobalVariableSet(gvKey, AccountEquity());

初回起動時だけ、現在のEquityをピークの初期値として記録します。

OnTickでピークの更新と判定を行う

double peak = GlobalVariableGet(gvKey);
double equity = AccountEquity();

if(equity > peak)
  {
   peak = equity;
   GlobalVariableSet(gvKey, peak);
  }

double ddPercent = (peak - equity) / peak * 100.0;

Equityがピークを更新したら、その都度GlobalVariableも書き換えます。

新規エントリーだけを止める

ddPercentが入力パラメーターの上限以上なら、Comment()で状態を表示し、

エントリー処理に進まずreturnします。

既存ポジションにはいっさい触れません。

実際に動くコード全体

ここまでの要素をまとめた、実際に動くEAです。

//+------------------------------------------------------------------+
//|                                   DrawdownLimitStopEA.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

input double DrawdownLimitPercent = 20.0;   //ピーク比でこの%を超えたら新規停止
input int    FastMAPeriod         = 5;
input int    SlowMAPeriod         = 20;
input double FixedLots            = 0.1;
input int    StopLossPips         = 300;
input int    MagicNumber          = 20261006;

string gvKey;

int OnInit()
  {
   gvKey = "DD_Peak_" + Symbol();
   if(!GlobalVariableCheck(gvKey))
      GlobalVariableSet(gvKey, AccountEquity());
   return(INIT_SUCCEEDED);
  }

double UpdatePeakAndGetDrawdown()
  {
   double peak = GlobalVariableGet(gvKey);
   double equity = AccountEquity();

   if(equity > peak)
     {
      peak = equity;
      GlobalVariableSet(gvKey, peak);
     }

   if(peak <= 0)
      return(0);

   return((peak - equity) / peak * 100.0);
  }

bool HasOpenPosition()
  {
   for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol() == _Symbol && OrderMagicNumber() == MagicNumber)
            return(true);
        }
     }
   return(false);
  }

void OnTick()
  {
   double ddPercent = UpdatePeakAndGetDrawdown();

   if(ddPercent >= DrawdownLimitPercent)
     {
      Comment("ドローダウン上限に到達: ", DoubleToString(ddPercent, 1),
              "% (新規エントリー停止中、既存ポジションは対象外)");
      return;
     }

   Comment("現在のドローダウン: ", DoubleToString(ddPercent, 1), "%");

   if(HasOpenPosition())
      return;

   double fastMA     = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double slowMA      = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double fastMAPrev  = iMA(_Symbol, PERIOD_CURRENT, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
   double slowMAPrev  = iMA(_Symbol, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);

   double sl = 0;

   if(fastMAPrev <= slowMAPrev && fastMA > slowMA)
     {
      sl = Ask - StopLossPips * Point;
      OrderSend(_Symbol, OP_BUY, FixedLots, Ask, 3, sl, 0, "DrawdownLimitStopEA", MagicNumber, 0, clrBlue);
     }
   else if(fastMAPrev >= slowMAPrev && fastMA < slowMA)
     {
      sl = Bid + StopLossPips * Point;
      OrderSend(_Symbol, OP_SELL, FixedLots, Bid, 3, sl, 0, "DrawdownLimitStopEA", MagicNumber, 0, clrRed);
     }
  }

MetaEditorでのコンパイル・実行手順

実際にMT4で動かすまでの手順を確認します。

  1. MetaEditorで新規EA「DrawdownLimitStopEA」を作成し、上のコードを貼り付けてコンパイルする
  2. エラー・警告が0件であることを確認する
  3. デモ口座でチャートに適用し、コメント欄にドローダウン率が表示されることを確認する
  4. DrawdownLimitPercentを一時的に低い値(例: 1.0)にして、エントリー停止が実際に発生することを確認する
  5. 確認後は想定する運用値(例: 20.0)に戻す

よくあるエラーと注意点

実装でつまずきやすいポイントをまとめます。

ピークの初期化タイミングを誤解する

EAを後から取り付けた場合、ピークはその時点のEquityから始まります。

それより前に発生していた下落は、このEAのドローダウン率に反映されません。

バックテストと実運用でGlobalVariableの挙動が違う

ストラテジーテスター内のGlobalVariableは実運用の値と分離されているため、

バックテストのたびにピークがリセットされた状態から始まります。

MQL4とMQL5の違い

このコードはMQL4のAccountEquity()を使った書き方です。

MQL5ではAccountInfoDouble(ACCOUNT_EQUITY)という、

引数指定の関数に置き換える必要があります。

よくある質問

ドローダウン制限EAについて、よくある疑問に回答します。

既存ポジションも強制的に決済すべきですか?

本記事ではあえて強制決済しない設計にしています。

既存ポジションの損切り・保有判断は手法ごとに異なるため、

新規停止と決済は別の機能として分けるべきだと考えたためです。

必要であれば、既刊の1日の損失上限EAの、

全決済処理を組み合わせることもできます。

DrawdownLimitPercentはいくつに設定すればいいですか?

一般的には10〜25%程度が目安とされますが、

手法の最大想定ドローダウンや資金の余裕度によって、

適切な値は変わります。

バックテストで自分の手法の最大ドローダウンを確認した上で、

その値より少し手前に設定することをおすすめします。

複数の通貨ペアで同じEAを動かす場合はどうなりますか?

本記事のgvKeyはSymbol()を含めているため、

通貨ペアごとに別のピークが記録されます。

口座全体のドローダウンを1つの基準で監視したい場合は、

gvKeyを固定文字列にして全ペア共通のピークにする必要があります。

【MQL4】資産のピーク(最高値)からの下落率でドローダウンを監視し、新規エントリーを自動停止するEAの作り方について解説してみた:まとめ

1日単位の損失額の監視だけでは、日をまたいで積み重なるドローダウンを捉えられません。

資産のピークからの下落率を%で常に監視し、

一定の割合を超えたら新規エントリーだけを自動で止める設計にすることで、

既存ポジションの判断は手法に委ねたまま、

累積的なリスクだけを機械的に制限できます。

GlobalVariableでピークを永続化しておくことで、

端末の再起動を挟んでも監視を継続できる設計にしています。

関連記事