本記事では、MT4(MQL4)でEAのモードや内部状態を 背景色・縦ライン・帯表示で可視化する方法を解説します。
EA開発をしていると、こんな疑問が出てきます。
- 今はレンジ?トレンド?
- なぜこの場面でエントリーした?
- モード切替はどこで起きた?
ロジックは正しく動いていても、
状態が見えないと検証効率は上がりません。
そこで本記事では、
EAのモードを背景色・縦ライン・下段帯で可視化するライブラリ VisualMode.mqh を公開します。
単なる装飾ではありません。
これは「ロジックと描画を分離する設計」の実装例です。
include して 3行追加するだけで簡単に導入できます。
なぜ状態を可視化するのか?
EAはブラックボックスになりやすいです。
・条件は満たしているはずなのに入らない
・思っていない方向にドテンした
・フィルターが効いているのか分からない
可視化を入れるだけで、
- デバッグ速度が上がる
- ロジック理解が深まる
- パラメータ調整が楽になる
つまり、
開発・検証効率が劇的に上がるのです。
VisualMode.mqhの機能

- ①モード変更時に背景を塗る(履歴が残る)
- ②切替ポイントに縦ライン表示
- ③現在モードを下段帯で常時表示
- EA削除時に自動クリーンアップ
しかも、
EAロジックと完全分離されています。
VisualMode.mqh(公開コード)
以下が VisualMode.mqh の全コードです。
そのまま include して使える形で整形しています。
//+------------------------------------------------------------------+
//| VisualMode.mqh |
//| 公開用・最終完成版(3状態 + 可変帯長対応) |
//| |
//| 対応状態: |
//| -1 = 表示なし |
//| 0 = モードA |
//| 1 = モードB |
//| |
//+------------------------------------------------------------------+
#property strict
//==================================================
// ■ 内部管理変数
//==================================================
int vm_currentMode = -1;
datetime vm_lastModeTime = 0;
string VM_PREFIX = "VM_";
string VM_BAR = "VM_MODE_BAR";
//+------------------------------------------------------------------+
//| 初期化 |
//+------------------------------------------------------------------+
void VisualMode_Init(int initMode)
{
vm_currentMode = initMode;
vm_lastModeTime = Time[1];
}
//+------------------------------------------------------------------+
//| 状態更新 |
//+------------------------------------------------------------------+
void VisualMode_Update(int newMode,
color modeAColor,
color modeBColor)
{
datetime nowTime = Time[1];
// モードが変わったときだけ背景確定&縦ライン
if(newMode != vm_currentMode)
{
if(vm_currentMode == 0 || vm_currentMode == 1)
{
VisualMode_DrawBackground(
vm_lastModeTime,
nowTime,
vm_currentMode,
modeAColor,
modeBColor
);
}
VisualMode_DrawChangeLine(newMode, modeAColor, modeBColor);
vm_lastModeTime = nowTime;
vm_currentMode = newMode;
}
// モードが同じでも毎バー帯は更新する
VisualMode_DrawBar(modeAColor, modeBColor);
}
//+------------------------------------------------------------------+
//| 背景描画 |
//+------------------------------------------------------------------+
void VisualMode_DrawBackground(datetime fromTime,
datetime toTime,
int mode,
color modeAColor,
color modeBColor)
{
string name = VM_PREFIX + "BG_" + IntegerToString(fromTime);
double top = ChartGetDouble(0, CHART_PRICE_MAX);
double bottom = ChartGetDouble(0, CHART_PRICE_MIN);
color bgColor = (mode == 0 ? modeAColor : modeBColor);
ObjectCreate(0,name,OBJ_RECTANGLE,0,
fromTime, top,
toTime, bottom);
ObjectSetInteger(0,name,OBJPROP_COLOR,bgColor);
ObjectSetInteger(0,name,OBJPROP_BACK,true);
ObjectSetInteger(0,name,OBJPROP_FILL,true);
}
//+------------------------------------------------------------------+
//| モード切替縦ライン |
//+------------------------------------------------------------------+
void VisualMode_DrawChangeLine(int mode,
color modeAColor,
color modeBColor)
{
string name = VM_PREFIX + "LINE_" +
TimeToString(Time[1], TIME_DATE|TIME_MINUTES);
if(ObjectFind(0,name) >= 0)
return;
ObjectCreate(0,name,OBJ_VLINE,0,Time[1],0);
color lineColor;
if(mode == 0)
lineColor = modeAColor;
else if(mode == 1)
lineColor = modeBColor;
else
lineColor = clrSilver; // ★ -1用グレー
ObjectSetInteger(0,name,OBJPROP_COLOR,lineColor);
ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DOT);
ObjectSetInteger(0,name,OBJPROP_WIDTH,1);
}
//+------------------------------------------------------------------+
//| 下段帯描画(可変長対応) |
//+------------------------------------------------------------------+
void VisualMode_DrawBar(color modeAColor, color modeBColor)
{
string name = VM_BAR;
// 表示対象外なら削除
if(vm_currentMode != 0 && vm_currentMode != 1)
{
ObjectDelete(0,name);
return;
}
color barColor = (vm_currentMode == 0 ? modeAColor : modeBColor);
double low = WindowPriceMin();
double high = WindowPriceMax();
double height = (high-low) * 0.03;
datetime left = vm_lastModeTime; // ★ここがポイント
datetime right = Time[0];
if(ObjectFind(0,name) < 0)
{
ObjectCreate(0,name,OBJ_RECTANGLE,0,
left,low,
right,low+height);
ObjectSetInteger(0,name,OBJPROP_BACK,true);
}
ObjectSetInteger(0,name,OBJPROP_COLOR,barColor);
ObjectMove(0,name,0,left,low);
ObjectMove(0,name,1,right,low+height);
}
//+------------------------------------------------------------------+
//| クリーンアップ |
//+------------------------------------------------------------------+
void VisualMode_Deinit()
{
int total = ObjectsTotal();
for(int i=total-1; i>=0; i--)
{
string name = ObjectName(i);
if(StringFind(name,VM_PREFIX) == 0)
ObjectDelete(0,name);
}
ObjectDelete(0,VM_BAR);
}使い方
① include を追加
まず、VisualMode.mqh を MQL4 / Include フォルダに保存します。
その上で、EAファイルの先頭に以下を追加します。
#include <VisualMode.mqh>
コンパイル後、MetaEditorの「詳細」タブに 'VisualMode.mqh' と表示されていれば、 正しく読み込まれています。

⚠️ エラーが出る場合は、保存場所が
MQL4 / Includeになっているか確認してください。
② OnInit() で初期化
VisualMode.mqh は 3状態対応の表示ライブラリです。
- -1 = 表示なし(中立)
- 0 = モードA
- 1 = モードB
// 初期状態(例:中立)
VisualMode_Init(-1);
ここで指定する値は「表示の初期状態」です。
EA内部のロジック状態とは独立しています。
例えばEA側が
- 1 = アップトレンド
- 2 = ダウントレンド
- 0 = どちらでもない
のような複数状態を持っていても、
表示時に -1 / 0 / 1 に変換して渡せば問題ありません。
③ モード変更時に Update を呼ぶ
状態が切り替わったタイミングで呼び出します。
第2引数は「0 のときの色」、
第3引数は「1 のときの色」です。
// 例:モードA=青、モードB=赤
int visualState = 0; // -1 / 0 / 1
VisualMode_Update(
visualState,
clrDodgerBlue, // 0 のときの色
clrIndianRed // 1 のときの色
);
-1 を渡した場合は背景も帯も表示されません。
0 または 1 のときのみ描画されます。
④ OnDeinit() でクリーンアップ
VisualMode_Deinit();
設計思想:ロジックと描画を分離する
このライブラリの本質は「色分け」ではありません。
ロジックと描画を分離する設計
これにより、
- ロジックを変更しても描画は壊れない
- 他EAへ流用できる
- 機能追加しても保守しやすい
- 外注時の仕様説明が明確になる
この考え方(mqh化・インクルード管理)の基本は、以下の記事で詳しく解説しています。
【MT4/MQL4】EAソースコードを整理する方法|mqh化・インクルード管理で見やすく効率化
補足:相場判定ロジックと組み合わせると強い
VisualMode.mqh は「状態を表示する」ための部品です。
判定ロジックはすべてEA側で自由に定義できます。
例:
- ADXでトレンド/レンジ判定
- 一目均衡表の三役好転/逆転
- 移動平均線より上/下
- 売買許可/停止モード
- ナンピン段階表示
特に、ADXを使ったレンジ・トレンド判定を組み込むことで、 EAの相場モード管理がより明確になります。
👉 MT4でレンジ相場を自動判定する方法|ADXでトレンド判定する実装例
まずは相場環境の判定ロジックを設計し、 その状態を VisualMode.mqh で可視化する、 という流れが最も実務的です。
使用例:移動平均線より上なら青、下なら赤
double ma = iMA(NULL,0,50,0,MODE_SMA,PRICE_CLOSE,0);
double price = Close[0];
int state = -1; // 初期は表示なし
if(price > ma)
state = 1; // モードB
else if(price < ma)
state = 0; // モードA
VisualMode_Update(
state,
clrRed, // 0 のときの色
clrBlue // 1 のときの色
);
表示用に -1 / 0 / 1 に変換して渡すだけです。
VisualMode.mqh 側を変更する必要はありません。
ロジックの意味づけはすべてEA側で自由に定義できます。
まとめ
EA開発は、ロジックだけでなく「状態管理」まで含めて完成します。
VisualMode.mqh は、状態を視覚化するための基盤ライブラリです。
まずは1つのEAに組み込み、
「どのタイミングで、どの状態になっているか?」を見える化してみてください。
検証効率が一段上がります。








コメント