既刊の増し玉EAは、価格が一定幅動いたことと、証拠金維持率が安全な水域にあることを、

両方確認してから自動で発注してくれます。

ただ、「自動化はまだ早い、まず自分の目で確認しながら増やしたい」

という人にとっては、EAに全部任せるのは少し怖いかもしれません。

この記事では、発注を一切行わず、

今何段目にいるのか・次の増し玉ラインがどこにあるのか・

あと1段増やしたら証拠金維持率がどこまで下がるのかを、

チャート上に表示するだけの確認専用インジケーターの作り方を解説します。

この記事で分かること
・既刊の増し玉EAとの役割の違い(自動化vs確認専用)
・現在の段階と次の増し玉ラインの計算方法
・1段増やした場合の証拠金維持率を事前に見積もる方法
・実際に動くコード全体

設計思想: なぜ発注しない「確認専用」ツールが必要か

まず、このインジケーターがどんな場面で役に立つのかを整理します。

既刊の増し玉EAとの違い

既刊の増し玉EAは、価格条件と証拠金維持率の条件がそろった瞬間に、

自動で発注まで行う設計でした。

このインジケーターの位置づけ
・発注は一切行わない
・現在の段階
・次のライン
・見積り維持率を表示するだけ
・最終的に増やすかどうかは自分で判断する

既刊のリスク%ロット計算インジケーターとの関係

既刊のリスク%ロット計算インジケーターも、発注を行わず計算結果だけを表示する「確認専用」

ツールでした。

本記事はこの設計方針の仲間として、増し玉というテーマに当てはめたものです。

現在の段階と次の増し玉ラインの計算

既刊の増し玉EAと同じ判定ロジックを、発注せずに「読む」だけに変えます。

自分のマジックナンバーの注文を数える

int CountMyOrders()
  {
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol() == _Symbol && OrderMagicNumber() == InpMagicNumber)
            count++;
        }
     }
   return(count);
  }

既刊EAと全く同じ関数です。

このインジケーターを既刊EAと組み合わせて使う場合は、

同じInpMagicNumberを指定することで、

EAが数えている段階数と同じ数値を確認できます。

最後に増し玉した価格から次のラインを求める

double nextLine = GetLatestOpenPrice() + InpStepPoints * Point;

GetLatestOpenPriceは既刊EAと同じ関数で、

自分の注文のうち最後に開いた価格を取得します。

そこにInpStepPoints分を足すことで、次に増し玉が許可される価格が分かります。

1段増やした場合の証拠金維持率を見積もる

実際に発注する前に、資金面の余裕がどこまであるかを試算します。

現在の維持率と見積り維持率の違い

double marginPerLot = MarketInfo(_Symbol, MODE_MARGINREQUIRED);
double estimatedMargin = AccountMargin() + marginPerLot * InpLots;
double estimatedLevel  = (estimatedMargin > 0) ? AccountEquity() / estimatedMargin * 100 : 0;

現在の必要証拠金(AccountMargin)に、

1段分の必要証拠金を加えた場合の維持率を概算します。

この見積りの前提
・有効証拠金(AccountEquity)は増し玉の瞬間は変わらないと仮定している
・実際には発注時のスプレッド分だけ一時的に不利な値になる
・価格が動いた後の値ではなく「今増やしたら」の概算値

見積り維持率がInpMinMarginLevelToAddを下回るかを判定する

bool safeToAdd = (estimatedLevel >= InpMinMarginLevelToAdd);

既刊EAが実際に使っている基準と同じInpMinMarginLevelToAddを、

このインジケーターでも入力値として受け取ることで、

EA側の判定と同じ基準で確認できます。

実際に動くコード全体

段階数・次のライン・見積り維持率までを表示する、

実際にMetaEditorでコンパイルできるインジケーターです。

先に注意
・このコードは買い方向のみの実装です
・GetLatestOpenPriceは売買方向を区別せず最後に開いた価格を返すため
・売り方向を混在させると次のラインの計算が合わなくなります
・売り専用に変える方法は8節のFAQで解説します
//+------------------------------------------------------------------+
//|                                   PyramidingLevelIndicator.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
#property indicator_chart_window
#property indicator_buffers 0

#define LABEL_NAME "PyramidingLevelPanel"
#define LINE_NAME  "PyramidingNextLine"

input double InpLots                = 0.01;  //1段あたりの想定ロット数
input int    InpStepPoints          = 150;   //増し玉を判定する価格の刻み幅(ポイント)
input int    InpMaxLevels           = 4;     //最大の増し玉段階数
input double InpMinMarginLevelToAdd = 300.0; //増し玉を安全と判断する維持率(%)の基準
input int    InpMagicNumber         = 20261029;

int CountMyOrders()
  {
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol() == _Symbol && OrderMagicNumber() == InpMagicNumber)
            count++;
        }
     }
   return(count);
  }

double GetLatestOpenPrice()
  {
   datetime latest = 0;
   double   price  = 0;

   for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol() == _Symbol && OrderMagicNumber() == InpMagicNumber)
           {
            if(OrderOpenTime() > latest)
              {
               latest = OrderOpenTime();
               price  = OrderOpenPrice();
              }
           }
        }
     }
   return(price);
  }

void UpdatePanel()
  {
   int level = CountMyOrders();

   if(level == 0)
     {
      ObjectSetText(LABEL_NAME, "増し玉段階: 0 (未保有、次は1段目の新規発注)", 11, "Arial", clrSilver);
      ObjectDelete(0, LINE_NAME);
      return;
     }

   double lastPrice = GetLatestOpenPrice();
   double nextLine   = lastPrice + InpStepPoints * Point;

   double marginPerLot    = MarketInfo(_Symbol, MODE_MARGINREQUIRED);
   double estimatedMargin = AccountMargin() + marginPerLot * InpLots;
   double estimatedLevel  = (estimatedMargin > 0) ? AccountEquity() / estimatedMargin * 100 : 0;
   bool   safeToAdd        = (estimatedLevel >= InpMinMarginLevelToAdd);

   color textColor = safeToAdd ? clrLime : clrOrange;
   if(level >= InpMaxLevels)
      textColor = clrRed;

   string text;
   if(level >= InpMaxLevels)
      text = StringFormat("増し玉段階: %d/%d (最大段階に到達、これ以上は増やさない想定)", level, InpMaxLevels);
   else
      text = StringFormat("増し玉段階: %d/%d  次のライン:%s  増やした場合の見積り維持率:%.0f%%(基準%.0f%%)",
                           level, InpMaxLevels, DoubleToString(nextLine, Digits), estimatedLevel, InpMinMarginLevelToAdd);

   ObjectSetText(LABEL_NAME, text, 11, "Arial", textColor);

   if(level < InpMaxLevels)
     {
      if(ObjectFind(LINE_NAME) < 0)
         ObjectCreate(0, LINE_NAME, OBJ_HLINE, 0, 0, nextLine);
      else
         ObjectSetDouble(0, LINE_NAME, OBJPROP_PRICE, nextLine);
      ObjectSetInteger(0, LINE_NAME, OBJPROP_COLOR, textColor);
      ObjectSetInteger(0, LINE_NAME, OBJPROP_STYLE, STYLE_DASH);
     }
   else
      ObjectDelete(0, LINE_NAME);
  }

int OnInit()
  {
   ObjectCreate(0, LABEL_NAME, OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, LABEL_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, LABEL_NAME, OBJPROP_XDISTANCE, 10);
   ObjectSetInteger(0, LABEL_NAME, OBJPROP_YDISTANCE, 20);
   EventSetTimer(1);
   UpdatePanel();
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
   ObjectDelete(0, LABEL_NAME);
   ObjectDelete(0, LINE_NAME);
  }

void OnTimer()
  {
   UpdatePanel();
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   UpdatePanel();
   return(rates_total);
  }

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

実際にMT4で動かすまでの手順です。

  1. MetaEditorで新規インジケーター「PyramidingLevelIndicator」を作成し、上のコードを貼り付けてコンパイルする
  2. エラー・警告が0件であることを確認する
  3. デモ口座で手動発注を1件行い、パネルに「増し玉段階: 1/4」と表示されることを確認する
  4. 2件目を手動発注し、次のライン(破線)が新しい価格に更新されることを確認する
  5. InpMinMarginLevelToAddを一時的に高い値にし、文字色がオレンジに変わることを確認する

よくあるエラーと注意点

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

このインジケーターは発注しない

注意
・表示されるのは次のラインと見積り維持率だけ
・実際に増し玉するかどうかは自分で判断して手動発注する
・既刊EAのように自動発注はしない

既刊EAと同時運用する場合は入力値をそろえる

InpStepPoints・InpMinMarginLevelToAdd・

InpMagicNumberを、

既刊の増し玉EAと同じ値にそろえておくと、

このインジケーターが示す段階数・ラインが、

EA側の判定と一致します。

値がずれていると、インジケーターの表示とEAの実際の動作が食い違うため、

必ず同じ値を使ってください。

見積り維持率はあくまで概算

実際に発注すると、スプレッド分の損失が一時的に発生するため、

見積り維持率よりわずかに低い値になります。

既刊の資金管理系ツールとの使い分け

似た目的の記事が複数あるため、使い分けを整理します。

記事 発注 表示内容
本記事 しない 段階数・次のライン・見積り維持率
証拠金維持率×増し玉EA(既刊) 自動で行う Commentでの簡易表示のみ
リスク%ロット計算インジケーター(既刊) しない 損切り幅から計算した推奨ロット数

よくある質問

増し玉の確認専用インジケーターについて、よくある疑問に回答します。

このインジケーターだけで増し玉を自動化できますか?

できません。

このインジケーターはあくまで表示専用で、発注は一切行いません。

自動化したい場合は、既刊の証拠金維持率×増し玉EAを使ってください。

売り方向にも対応させられますか?

対応できます。

GetLatestOpenPriceで取得した価格から、

次のラインを引く方向(InpStepPoints分マイナス)に変えれば、

同じ考え方で売り方向を作れます。

複数の通貨ペアで同時に使えますか?

このコードは_Symbol(インジケーターを適用したチャートの通貨ペア)だけを、

対象にしています。

複数ペアで使う場合は、それぞれのチャートに個別に適用してください。

【MQL4】増し玉(ピラミッディング)の現在の段階と次のラインを表示する確認専用インジケーターの作り方:まとめ

既刊の増し玉EAは価格条件と証拠金維持率の条件がそろった瞬間に自動で発注しますが、

自動化する前に自分の目で段階とラインを確認したい場面もあります。

現在の段階・次の増し玉ライン・1段増やした場合の見積り維持率を表示するだけの、

発注しない確認専用インジケーターにすることで、

既刊EAと同じ基準を使いながら、

最終的な判断は自分の手に残せます。

関連記事