MQL4のオブジェクト関数を体系的にまとめました。ObjectCreate()によるオブジェクト作成、ObjectDelete()・ObjectsDeleteAll()による削除、ObjectSet()/ObjectGet()(旧形式)とObjectSetInteger()等(ビルド600+)によるプロパティ操作、トレンドライン・水平線・垂直線・矩形・ラベル・テキスト・ボタンの各種オブジェクトタイプ、ObjectGetTimeByValue()・ObjectGetValueByTime()による座標変換、SL/TPライン描画の実践まで、MT4開発に必要なオブジェクト操作のすべてをコード付きで解説します。
MQL4とMQL5のオブジェクト関数の違い
| 機能 | MQL4 | MQL5 |
|---|---|---|
| 作成 | ObjectCreate(name, type, …) | ObjectCreate(chart_id, name, type, …) |
| プロパティ設定(旧) | ObjectSet(name, prop, value) | なし(廃止) |
| プロパティ設定(新) | ObjectSetInteger/Double/String() | ObjectSetInteger/Double/String() |
| プロパティ取得(旧) | ObjectGet(name, prop) | なし(廃止) |
| プロパティ取得(新) | ObjectGetInteger/Double/String() | ObjectGetInteger/Double/String() |
| chart_id引数 | ビルド600+で追加(0=現在) | 必須 |
MQL4では旧形式のObjectSet()/ObjectGet()と新形式のObjectSetInteger()等の両方が使えます。新規開発では新形式を推奨します。旧形式はMQL5では完全に廃止されているため、将来の移植性を考えると新形式を使う方が良いでしょう。
ObjectCreate — オブジェクト作成
// 旧形式
bool ObjectCreate(
string name, // オブジェクト名(一意)
int type, // オブジェクトタイプ(OBJ_〇〇)
int window, // ウィンドウ番号(0=メインチャート)
datetime time1, // 第1アンカーの時刻
double price1, // 第1アンカーの価格
datetime time2 = 0, double price2 = 0, // 第2アンカー(任意)
datetime time3 = 0, double price3 = 0 // 第3アンカー(任意)
);
// 新形式(ビルド600+)
bool ObjectCreate(
long chart_id, // チャートID(0=現在)
string name,
ENUM_OBJECT type,
int sub_window,
datetime time1, double price1,
datetime time2 = 0, double price2 = 0,
datetime time3 = 0, double price3 = 0
);主要なオブジェクトタイプ
| 定数 | 説明 | アンカー数 |
|---|---|---|
| OBJ_HLINE | 水平線 | 1(価格のみ) |
| OBJ_VLINE | 垂直線 | 1(時刻のみ) |
| OBJ_TREND | トレンドライン | 2 |
| OBJ_RECTANGLE | 矩形 | 2 |
| OBJ_TRIANGLE | 三角形 | 3 |
| OBJ_LABEL | ラベル(ピクセル座標) | 0(座標で配置) |
| OBJ_TEXT | テキスト(チャート座標) | 1 |
| OBJ_BUTTON | ボタン | 0(座標で配置) |
| OBJ_ARROW | 矢印 | 1 |
| OBJ_FIBO | フィボナッチリトレースメント | 2 |
| OBJ_CHANNEL | 等距離チャネル | 3 |
基本オブジェクトの作成
// 水平線
void DrawHLine(string name, double price, color clr, int width = 1)
{
if(ObjectFind(name) >= 0)
ObjectDelete(name);
ObjectCreate(name, OBJ_HLINE, 0, 0, price);
ObjectSet(name, OBJPROP_COLOR, clr);
ObjectSet(name, OBJPROP_WIDTH, width);
ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID);
}
// 垂直線
void DrawVLine(string name, datetime time, color clr)
{
if(ObjectFind(name) >= 0)
ObjectDelete(name);
ObjectCreate(name, OBJ_VLINE, 0, time, 0);
ObjectSet(name, OBJPROP_COLOR, clr);
ObjectSet(name, OBJPROP_STYLE, STYLE_DOT);
}
// トレンドライン
void DrawTrendLine(string name, datetime t1, double p1,
datetime t2, double p2, color clr)
{
if(ObjectFind(name) >= 0)
ObjectDelete(name);
ObjectCreate(name, OBJ_TREND, 0, t1, p1, t2, p2);
ObjectSet(name, OBJPROP_COLOR, clr);
ObjectSet(name, OBJPROP_WIDTH, 2);
ObjectSet(name, OBJPROP_RAY, false); // 延長しない
}void DrawRectangle(string name, datetime t1, double p1,
datetime t2, double p2, color clr)
{
if(ObjectFind(name) >= 0)
ObjectDelete(name);
ObjectCreate(name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
ObjectSet(name, OBJPROP_COLOR, clr);
ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID);
ObjectSet(name, OBJPROP_BACK, true); // 背景に表示
}ラベル・テキスト・ボタン
void CreateLabel(string name, int x, int y, string text,
color clr, int fontSize = 10)
{
if(ObjectFind(name) >= 0)
ObjectDelete(name);
ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
ObjectSet(name, OBJPROP_XDISTANCE, x);
ObjectSet(name, OBJPROP_YDISTANCE, y);
ObjectSetText(name, text, fontSize, "Arial", clr);
// アンカー位置(CORNER_LEFT_UPPER がデフォルト)
ObjectSet(name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
}
// 情報パネルの例
void CreateInfoPanel()
{
string prefix = "Info_";
int y = 20;
int lineHeight = 18;
CreateLabel(prefix + "Title", 10, y, "=== EA Status ===", clrWhite, 11);
y += lineHeight + 5;
CreateLabel(prefix + "Balance", 10, y,
"残高: " + DoubleToStr(AccountBalance(), 0), clrLime);
y += lineHeight;
CreateLabel(prefix + "Equity", 10, y,
"有効証拠金: " + DoubleToStr(AccountEquity(), 0), clrLime);
y += lineHeight;
CreateLabel(prefix + "Spread", 10, y,
"スプレッド: " + IntegerToString((int)MarketInfo(Symbol(), MODE_SPREAD)), clrYellow);
}void CreateButton(string name, int x, int y, int width, int height,
string text, color textClr, color bgClr)
{
if(ObjectFind(0, name) >= 0)
ObjectDelete(0, name);
ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_COLOR, textClr);
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bgClr);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 10);
}ObjectSet / ObjectGet(旧形式)
| プロパティ定数 | 説明 |
|---|---|
| OBJPROP_COLOR | 色 |
| OBJPROP_STYLE | 線スタイル(STYLE_SOLID/DASH/DOT等) |
| OBJPROP_WIDTH | 線の太さ(1-5) |
| OBJPROP_BACK | 背景表示(true/false) |
| OBJPROP_RAY | トレンドラインの延長 |
| OBJPROP_TIME1/2/3 | アンカー時刻 |
| OBJPROP_PRICE1/2/3 | アンカー価格 |
| OBJPROP_XDISTANCE | X座標(ラベル/ボタン用) |
| OBJPROP_YDISTANCE | Y座標(ラベル/ボタン用) |
| OBJPROP_CORNER | アンカーコーナー |
| OBJPROP_SELECTABLE | 選択可能か |
| OBJPROP_SELECTED | 選択状態 |
| OBJPROP_HIDDEN | オブジェクト一覧に非表示 |
OBJ_LABELとOBJ_TEXTの違いに注意してください。OBJ_LABELはピクセル座標(画面の固定位置)に配置され、チャートをスクロールしても動きません。OBJ_TEXTはチャート座標(価格と時刻)に配置され、チャートと一緒にスクロールします。情報パネルにはOBJ_LABEL、価格注釈にはOBJ_TEXTを使います。
OBJ_LABELとOBJ_TEXTの違いに注意してください。OBJ_LABELはピクセル座標(画面の固定位置)に配置され、チャートをスクロールしても動きません。OBJ_TEXTはチャート座標(価格と時刻)に配置され、チャートと一緒にスクロールします。情報パネルにはOBJ_LABEL、価格注釈にはOBJ_TEXTを使います。
ObjectDelete / ObjectsDeleteAll
// 個別削除
void DeleteObject(string name)
{
if(ObjectFind(name) >= 0)
{
ObjectDelete(name);
Print("オブジェクト削除: ", name);
}
}
// プレフィックスで一括削除
void DeleteAllByPrefix(string prefix)
{
int total = ObjectsTotal();
for(int i = total - 1; i >= 0; i--)
{
string name = ObjectName(i);
if(StringFind(name, prefix) == 0)
ObjectDelete(name);
}
}
// ObjectsDeleteAll(ビルド600+の新形式)
void CleanupAll()
{
// 全オブジェクト削除
ObjectsDeleteAll(0); // chart_id=0(現在のチャート)
// 特定のプレフィックスだけ削除
ObjectsDeleteAll(0, "MyEA_");
// 特定ウィンドウの特定タイプだけ削除
ObjectsDeleteAll(0, "MyEA_", 0, OBJ_HLINE);
}- 大量のオブジェクト(100個以上)を描画するとチャートの描画が重くなる
- OnTick()内でオブジェクトを毎回作り直すのではなく、既存オブジェクトのプロパティを更新する方が効率的
- ObjectFind()で存在確認→ObjectSet()で更新、なければObjectCreate()が基本パターン
- 不要になったオブジェクトは速やかにObjectDelete()で削除する
- 大量のオブジェクト(100個以上)を描画するとチャートの描画が重くなる
- OnTick()内でオブジェクトを毎回作り直すのではなく、既存オブジェクトのプロパティを更新する方が効率的
- ObjectFind()で存在確認→ObjectSet()で更新、なければObjectCreate()が基本パターン
- 不要になったオブジェクトは速やかにObjectDelete()で削除する
ObjectGetTimeByValue / ObjectGetValueByTime
// トレンドラインの特定時刻での価格を取得
void GetTrendLinePrice()
{
string lineName = "TrendLine1";
// トレンドライン上の現在時刻の価格を計算
double price = ObjectGetValueByTime(0, lineName, TimeCurrent());
Print("トレンドライン価格(現在): ", price);
// 特定価格に到達する時刻を取得
datetime time = ObjectGetTimeByValue(0, lineName, Ask);
if(time > 0)
Print("Ask到達予想時刻: ", TimeToStr(time));
}実践: SL/TPライン描画
void DrawSLTPLines(int ticket)
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
return;
string prefix = "SLTP_" + IntegerToString(ticket) + "_";
double sl = OrderStopLoss();
double tp = OrderTakeProfit();
double entry = OrderOpenPrice();
// エントリーライン
DrawHLine(prefix + "Entry", entry, clrWhite, 1);
ObjectSetText(prefix + "Entry",
"Entry: " + DoubleToStr(entry, Digits), 8);
// SLライン
if(sl > 0)
{
DrawHLine(prefix + "SL", sl, clrRed, 2);
double slPips = MathAbs(entry - sl) / Point;
ObjectSetText(prefix + "SL",
"SL: " + DoubleToStr(sl, Digits)
+ " (" + DoubleToStr(slPips, 0) + "pts)", 8);
}
// TPライン
if(tp > 0)
{
DrawHLine(prefix + "TP", tp, clrLime, 2);
double tpPips = MathAbs(tp - entry) / Point;
ObjectSetText(prefix + "TP",
"TP: " + DoubleToStr(tp, Digits)
+ " (" + DoubleToStr(tpPips, 0) + "pts)", 8);
}
}
// SL/TPラインの削除
void RemoveSLTPLines(int ticket)
{
string prefix = "SLTP_" + IntegerToString(ticket) + "_";
DeleteAllByPrefix(prefix);
}オブジェクト関数一覧(MQL5対応表)
| MQL4関数 | MQL5対応 | 説明 |
|---|---|---|
| ObjectCreate() | ObjectCreate(chart_id, …) | オブジェクト作成 |
| ObjectDelete() | ObjectDelete(chart_id, name) | オブジェクト削除 |
| ObjectsDeleteAll() | ObjectsDeleteAll(chart_id) | 一括削除 |
| ObjectFind() | ObjectFind(chart_id, name) | オブジェクト検索 |
| ObjectSet() | 廃止(SetInteger/Double/Stringを使用) | プロパティ設定(旧) |
| ObjectGet() | 廃止(GetInteger/Double/Stringを使用) | プロパティ取得(旧) |
| ObjectSetText() | ObjectSetString(OBJPROP_TEXT) | テキスト設定 |
| ObjectGetText() | ObjectGetString(OBJPROP_TEXT) | テキスト取得 |
| ObjectName(index) | ObjectName(chart_id, index) | インデックスから名前取得 |
| ObjectsTotal() | ObjectsTotal(chart_id) | オブジェクト総数 |
| ObjectType(name) | ObjectGetInteger(OBJPROP_TYPE) | オブジェクトタイプ |
| ObjectGetValueByTime() | ObjectGetValueByTime() | 時刻→価格 |
| ObjectGetTimeByValue() | ObjectGetTimeByValue() | 価格→時刻 |
まとめ
MQL4のオブジェクト関数は、チャート上の視覚的な情報表示とユーザーインタラクションに不可欠です。重要なポイントは以下の通りです。
- ObjectFind()で存在確認してからObjectCreate()する — 同名オブジェクトの重複を防ぐ
- OnDeinitで作成したオブジェクトを削除する — プレフィックスを使った一括削除が便利
- 新形式(ObjectSetInteger等)を使う — MQL5への移植性が高まる
- OBJ_LABELはピクセル座標、OBJ_TEXTはチャート座標 — 用途に応じて使い分ける
次のステップとして、MQLリファレンス総合ガイドでチャート操作関数やイベントハンドラと組み合わせたインタラクティブなEAの開発を学びましょう。





