含み損がじわじわ増えているのに、証拠金維持率が今どれくらいか、

パッと確認できずに不安になった、という経験はないでしょうか。

証拠金維持率は「口座情報」タブを開けば確認できますが、

チャートを見ている間はそのタブは表示されていません。

この記事では、証拠金維持率をチャートの左上に常時表示し、

危険な水域に近づいたら文字色で警告するインジケーターのアイデアを、

実際に動くコードで解説します。

証拠金維持率をAccountInfoDoubleで取得する

証拠金維持率(マージンレベル)は、

「有効証拠金÷必要証拠金×100」で計算される値です。

MQL4では、この計算式を自分で書く必要はありません。

AccountInfoDouble(ACCOUNT_MARGIN_LEVEL)で直接取得する

double level = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);

`AccountInfoDouble`の引数に、

`ACCOUNT_MARGIN_LEVEL`を渡すだけで、

計算済みの維持率(%)がそのまま返ってきます。

補足: 旧来のAPIでは、

`AccountEquity()`と`AccountMargin()`をそれぞれ取得し、

自分で割り算する書き方も使われていました。

`ACCOUNT_MARGIN_LEVEL`はこの計算を、

MQL4側で済ませてくれる新しめの書き方です。

ポジションが無いときの0除算に注意する

必要証拠金(Margin)が0のとき、

割り算の分母が0になるため、維持率の値が不正になります。

ポジションが無いかどうかは、別途チェックしてから表示を切り替える必要があります。

ObjectCreateでチャート上に常時表示するラベルを作る

インジケーターのバッファは使わず、

`OBJ_LABEL`というオブジェクトをチャートに貼り付けて文字を表示します。

OBJ_LABELの位置はXDISTANCE/YDISTANCEで指定する

`OBJ_LABEL`は、時間や価格の座標を使いません。

チャートの四隅を基準にした、ピクセル単位の距離で位置を決めます。

ObjectCreate(0, "MarginLevelPanel", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, "MarginLevelPanel", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, "MarginLevelPanel", OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, "MarginLevelPanel", OBJPROP_YDISTANCE, 20);

維持率に応じて文字色を3段階に変える設計

数値をただ表示するだけでは、

一目で「危険かどうか」が分かりません。

閾値を2つ用意し、色で危険度を直感的に伝える設計にします。

維持率の範囲 文字色 意味
DangerLevel以下 赤 危険、追加入金やポジション整理を検討する水準
WarningLevel以下 オレンジ 注意、含み損の推移を見ておきたい水準
それ以外 緑 安全水域

実際に動くコード全体

チャートの左上に証拠金維持率を常時表示し、

閾値に応じて色を変えるインジケーターです。

//+------------------------------------------------------------------+
//|                                  MarginLevelPanel.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 "MarginLevelPanel"

input int WarningLevel = 200;   //黄色警告ラインになる維持率(%)
input int DangerLevel  = 100;   //赤色危険ラインになる維持率(%)

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);
  }

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);
  }

//+------------------------------------------------------------------+
//| 保有中の市場ポジション数を数える(未決済の成行注文のみ)             |
//+------------------------------------------------------------------+
int CountOpenPositions()
  {
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderType() <= OP_SELL)
         count++;
     }
   return(count);
  }

void UpdatePanel()
  {
   if(CountOpenPositions() == 0)
     {
      ObjectSetText(LABEL_NAME, "証拠金維持率: ポジションなし", 12, "Arial", clrGray);
      return;
     }

   double level = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
   color  c;

   if(level <= DangerLevel)
      c = clrRed;
   else if(level <= WarningLevel)
      c = clrOrange;
   else
      c = clrLime;

   string text = StringFormat("証拠金維持率: %.1f%%", level);
   ObjectSetText(LABEL_NAME, text, 14, "Arial", c);
  }

MetaEditorで実際に動かす手順

  1. MetaEditorで「ファイル」→「新規作成」→「カスタムインジケーター」で「MarginLevelPanel」を作成する
  2. ウィザードの中身を削除し、上のコードを丸ごと貼り付ける
  3. F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
  4. デモ口座のチャートに適用し、左上に維持率が表示され、ポジションを持つと色が変わるか確認する

よくあるエラーと注意点

表示が崩れる・数値がおかしいと感じたときの、確認ポイントをまとめます。

ポジション決済後もラベルが「ポジションなし」に戻らない

`OnCalculate`はレート更新のたびに呼ばれますが、

決済直後にタイミングよく呼ばれない場合があります。

このコードでは`EventSetTimer(1)`で、

1秒ごとにも更新しているため、最大1秒で反映されます。

インジケーターを外してもラベルが残る

`OnDeinit`で`ObjectDelete`を呼び忘れると、

インジケーターを外してもラベルだけがチャートに残り続けます。

このコードのように、`OnDeinit`で必ず削除してください。

注意: WarningLevel・DangerLevelの数値は、

このコードの初期値であり、

適切な水準はブローカーのロスカット基準

(証拠金維持率何%で強制ロスカットになるか)によって変わります。

自分の口座のロスカット水準を確認したうえで、余裕を持った数値に調整してください。

EA(通知)との使い分け

似た目的の記事として、

指定した維持率を下回ったらLINEとアラートで通知するEAが既刊にあります。

どちらか一方ではなく、用途で使い分けるのがおすすめです。

要点: 「今の状態を常に目で確認したい」ならこの記事のインジケーター、

「閾値を超えた瞬間だけ気づきたい、チャートを見ていなくても通知が欲しい」なら、

maginecole-alert-line.mdのEA、という使い分けです。

両方を併用しても問題ありません。

よくある質問

証拠金維持率パネルの実装でよく検索されている疑問を、3つにまとめて回答します。

複数のチャートに適用すると表示は競合しませんか?

この記事のコードはオブジェクト名を固定文字列にしているため、

同じ端末内の複数チャートに適用しても、

それぞれのチャート上に独立したラベルが表示されます

(オブジェクトはチャートごとに管理されるためです)。

MQL5でも同じ書き方ができますか?

`ACCOUNT_MARGIN_LEVEL`・`ObjectCreate`・

`ObjectSetInteger`は、

MQL5にも同名の定数・関数があります。

ただし`ObjectSetText`はMQL5には存在せず、

`ObjectSetString`

(chart_id, name, OBJPROP_TEXT, textの4引数)

に置き換える必要があります。

表示位置を右上や左下に変えられますか?

`OBJPROP_CORNER`に渡す値を、

`CORNER_RIGHT_UPPER`や`CORNER_LEFT_LOWER`に、

変更すれば好きな四隅に配置できます。

【MQL4】証拠金維持率をチャート上に常時表示するインジケーターのアイデア|危険水域を色分けして警告:まとめ

`AccountInfoDouble(ACCOUNT_MARGIN_LEVEL)`で、

取得した証拠金維持率を、

`OBJ_LABEL`でチャート左上に常時表示し、

閾値に応じて色を変えることで、含み損の危険度を一目で確認できるようになります。

閾値を超えた瞬間の通知が欲しい場合は、

既刊のmaginecole-alert-line.md

(EA版)と併用するのがおすすめです。

関連記事