既刊の損失上限ストップEAは、
1日の含み損が設定した上限額を超えた瞬間に、
全ポジションを自動で決済してくれます。
ただ、このEAは「止める」ことに特化しているため、
今、上限まであとどれくらい余裕があるのかを、
画面でパッと確認することはできません。
この記事では、保有中の全ポジションの含み損を合計し、
1日の損失上限までの残り許容額をチャート上に常時表示する、
インジケーターの作り方を解説します。
・既刊の損失上限ストップEAとの役割の違い
・残り許容額を日次でリセットしながら表示する設計
・3段階の色分けで危険度を一目で伝える方法
・実際に動くコード全体
設計思想: なぜ「自動停止」だけでなく「見るためのインジケーター」も必要か
まず、このインジケーターが既刊の記事とどう役割が違うのかを整理します。
既刊の損失上限ストップEAとの関係
既刊記事のEAは、
含み損の合計が上限を超えた瞬間に全決済しますが、
その判定はEAの内部で行われ、
現在の数値はComment()で簡易的に表示されるのみでした。
この記事では、EAを動かしていないチャートでも確認できるよう、
インジケーターとして独立させます。
ドローダウン率・証拠金維持率インジケーターとの違い
既刊のドローダウン率インジケーターは資産のピークを基準にし、
証拠金維持率インジケーターは必要証拠金を基準にします。
一方、この記事の基準は「1日ごとにリセットされる固定額の上限」です。
| 指標 | 基準 | リセットの有無 |
|---|---|---|
| 証拠金維持率 | 必要証拠金(Margin) | リセットされない |
| ドローダウン率 | ピーク資産(Equity最大値) | リセットされない |
| 本記事(日次損失残り許容額) | 1日あたりの固定上限額 | 日付が変わるとリセットされる |
含み損の合計と日次リセットの考え方
既刊のEA記事と同じロジックを、インジケーター側でも使います。
OrdersTotal/OrderSelectで合計含み損を取得する
double GetTotalFloating()
{
double total = 0.0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
total += OrderProfit() + OrderSwap() + OrderCommission();
}
return(total);
}
既刊のEA記事と全く同じ関数で、
保有中の全ポジションの含み損・スワップ・手数料を合計します。
Day()を使った日次リセット
if(Day() != g_LastCheckedDay)
{
maxFloatingToday = 0; //今日いちばん深かった含み損もリセットする
g_LastCheckedDay = Day();
}
残り許容額そのものは合計含み損から都度計算されるため、
リセットが必要なのは「今日いちばん深かった含み損」という補助的な記録だけです。
・既刊EAは日付が変わるとg_StopTradingTodayフラグをリセットしていた
・このインジケーターはエントリーを止める機能自体がないため
・リセットするのは「今日の最大含み損」の記録だけでよい
OBJ_LABELで常時表示するパネルを作る
既刊の証拠金維持率・ドローダウン率インジケーターと同じ、
OBJ_LABELによる常時表示パネルを使います。
現在の含み損・残り許容額を表示する
double remaining = MaxLossAmount - MathAbs(MathMin(totalFloating, 0));
含み損がマイナスの場合だけ絶対値を取り、
上限額から引くことで「あと使える余裕」を求めます。
含み損がプラス(全体が利益)のときは、
上限額そのものが残り許容額になります。
3段階の色分け
既刊インジケーターと同じ考え方で、
残り許容額の割合に応じて文字色を変えます。
| 残り許容額の割合 | 文字色 | 意味 |
|---|---|---|
| DangerRatio以下 | 赤 | 危険、上限に近い水域 |
| WarningRatio以下 | オレンジ | 注意、推移を見ておきたい水準 |
| それ以外 | 緑 | 安全水域 |
実際に動くコード全体
含み損の合計から日次リセット・パネル表示までを含む、
実際にMetaEditorでコンパイルできるインジケーターです。
//+------------------------------------------------------------------+
//| DailyLossLimitPanel.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 "DailyLossRemainingPanel"
#define LABEL2_NAME "DailyLossRemainingPanelMax"
input double MaxLossAmount = 5000.0; //1日の損失上限額
input double WarningRatio = 0.5; //残り許容額の割合がこれ以下でオレンジ
input double DangerRatio = 0.2; //残り許容額の割合がこれ以下で赤
int g_LastCheckedDay = -1;
double maxFloatingToday = 0;
double GetTotalFloating()
{
double total = 0.0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
total += OrderProfit() + OrderSwap() + OrderCommission();
}
return(total);
}
void UpdatePanel()
{
if(Day() != g_LastCheckedDay)
{
maxFloatingToday = 0;
g_LastCheckedDay = Day();
}
double totalFloating = GetTotalFloating();
if(totalFloating < maxFloatingToday)
maxFloatingToday = totalFloating;
double lossNow = MathAbs(MathMin(totalFloating, 0));
double remaining = MaxLossAmount - lossNow;
double ratio = remaining / MaxLossAmount;
color textColor = clrLime;
if(ratio <= DangerRatio)
textColor = clrRed;
else if(ratio <= WarningRatio)
textColor = clrOrange;
ObjectSetText(LABEL_NAME,
"本日の残り許容額: " + DoubleToString(remaining, 0) + " (上限" + DoubleToString(MaxLossAmount, 0) + ")",
12, "Arial", textColor);
ObjectSetText(LABEL2_NAME,
"本日の最大含み損: " + DoubleToString(maxFloatingToday, 0),
10, "Arial", clrSilver);
}
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);
ObjectCreate(0, LABEL2_NAME, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, LABEL2_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, LABEL2_NAME, OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, LABEL2_NAME, OBJPROP_YDISTANCE, 40);
EventSetTimer(1);
UpdatePanel();
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
EventKillTimer();
ObjectDelete(0, LABEL_NAME);
ObjectDelete(0, LABEL2_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で動かすまでの手順です。
- MetaEditorで新規インジケーター「DailyLossLimitPanel」を作成し、上のコードを貼り付けてコンパイルする
- エラー・警告が0件であることを確認する
- デモ口座のチャートに適用し、左上に2行のパネルが表示されることを確認する
- ポジションを持った状態でMaxLossAmountを一時的に小さくし、文字色がオレンジ・赤に変わることを確認する
- 確認後は想定する運用値に戻す
よくあるエラーと注意点
実装・運用でつまずきやすいポイントをまとめます。
このインジケーターは決済しない
・このインジケーターはあくまで表示専用
・残り許容額が0になっても、自動で決済はしない
・実際に自動停止させたい場合は既刊の損失上限ストップEAを併用する
複数チャートに適用すると口座全体を正しく反映できない
GetTotalFloatingは口座内の全ポジションを合計するため、
どのチャートに適用しても同じ値が表示されます。
ただし、複数のチャートに同時に適用すると、
同じ計算を何度も繰り返す無駄が生じるため、
1つのチャートだけに適用することをおすすめします。
既刊の資金管理系インジケーター・EAとの使い分け
似た目的の記事が複数あるため、使い分けを整理します。
| 記事 | 基準 | 動作 |
|---|---|---|
| 本記事 | 1日の固定上限額 | 表示のみ |
| 損失上限ストップEA(既刊) | 1日の固定上限額 | 全決済+当日のエントリー停止 |
| ドローダウン率インジケーター(既刊) | ピーク資産からの下落率 | 表示のみ |
| 証拠金維持率インジケーター(既刊) | 必要証拠金に対する比率 | 表示のみ |
よくある質問
残り許容額インジケーターについて、よくある疑問に回答します。
既刊の損失上限ストップEAと同時に使えますか?
使えます。
同じMaxLossAmountの値を両方に設定しておけば、
このインジケーターで余裕を確認しながら、
EA側の自動停止を安全網として併用できます。
残り許容額がマイナスになることはありますか?
このインジケーター自体は決済を行わないため、
含み損が上限を超えてもポジションが残り続け、
残り許容額の表示はマイナスになります。
マイナス表示は「既に上限を超えている」という警告として受け止めてください。
通貨ペアごとに残り許容額を分けられますか?
このコードは口座全体の含み損を合計する設計です。
通貨ペアごとに分けたい場合は、
GetTotalFloatingの中でOrderSymbol()を使い、
対象の銘柄だけに絞り込む条件を追加してください。
【MQL4】1日の損失上限までの残り許容額をリアルタイム表示する監視インジケーターの作り方:まとめ
既刊の損失上限ストップEAは、
上限に達した瞬間に全決済してくれますが、
今どれくらい余裕があるのかは画面から分かりませんでした。
保有中の全ポジションの含み損を合計し、
1日の上限額から引いた残り許容額を常時表示することで、
上限に近づいていることを事前に察知できます。
表示専用のインジケーターと、
実際に止めてくれるEAを組み合わせることで、
より安全な運用ができます。
コメント