MQL5チャートオブジェクト・パネルUI完全ガイド|OBJ_LABEL・BUTTON・OnChartEventの基本
MQL5では、チャート上にラベル、ボタン、背景パネル、ステータス表示、ライン、テキストなどを配置できます。これらは総称してチャートオブジェクトとして扱われ、EA、インジケーター、裁量補助パネル、通知ボタン、確認用ステータス表示などで使われます。
この記事では、MQL5でパネルUIを作る時に特に使うことが多い OBJ_LABEL、OBJ_BUTTON、OBJ_RECTANGLE_LABEL、ObjectCreate、ObjectSetInteger、ObjectSetString、ObjectDelete、ChartRedraw、OnChartEvent の基本を整理します。
目的は、単に画面に文字やボタンを出すことではありません。表示系と判定系を分け、ボタンの見た目と実際のruntime状態を分け、時間足変更・EA削除・再セット・長時間稼働でも確認しやすいパネルUIを設計することです。
なお、本記事はMQL5の技術学習記事です。売買判断、特定銘柄、ロット設定、運用成績に関する助言は扱いません。EAやインジケーターの表示・確認・開発依頼前整理に必要な技術項目に限定して解説します。
- この記事で扱う範囲
- チャートオブジェクトとは
- 主要Object種別の比較
- OBJ_LABELの基本
- OBJ_RECTANGLE_LABELの基本
- OBJ_BUTTONの基本
- ObjectCreateとObjectSetの考え方
- OnChartEventでクリックを受ける
- パネルUIの基本設計
- 表示系と判定系を分ける理由
- button stateとruntime stateの違い
- Object lifecycleとOnDeinitの注意
- 残存オブジェクト・表示崩れ・フリーズ対策
- 差分更新とOnTimerメンテナンス
- ログ・HELP・SNAPをパネルUIに組み込む
- パネルEA開発依頼前に整理すること
- 次に読む技術講座
- 次に確認するページ
- よくある質問
- まとめ
この記事で扱う範囲
この記事では、チャート上に表示するオブジェクトと、クリックイベントを受け取る基本構造を扱います。パネルEA、裁量補助パネル、確認用ステータス表示、ログ提出前の状態表示などに共通する内容です。
この記事で扱う主な対象
| 対象 | この記事での扱い | 確認ポイント |
|---|---|---|
| OBJ_LABEL | 固定位置に文字を表示するラベル | 座標、アンカー、文字サイズ、更新頻度 |
| OBJ_RECTANGLE_LABEL | パネル背景や枠の作成 | 幅、高さ、背景色、重なり順 |
| OBJ_BUTTON | クリック可能なボタン | ボタン名、表示状態、クリックイベント |
| ObjectCreate | オブジェクト作成 | 名前、種類、サブウィンドウ、作成失敗時の扱い |
| ObjectSetInteger / ObjectSetString | プロパティ設定 | 色、位置、サイズ、文字、状態 |
| OnChartEvent | クリックやチャート変更の受信 | イベントID、sparam、処理の分岐 |
| OnDeinit | 終了時処理 | 無理な全削除を避ける、残存objectの扱い |
| OnTimer | 定期メンテナンス | 差分更新、軽量監視、描画負荷の分散 |
この記事で深く扱わないこと
本記事では、注文処理、決済処理、ロット計算、外部API通信、WebRequest、Google Sheets連携、複数銘柄処理は主題にしません。これらは別の技術講座で扱う領域です。
また、パネルに表示されている状態をそのまま売買判定の根拠にする設計も扱いません。表示は確認用、判定は内部runtime stateという分離を基本にします。
チャートオブジェクトとは
チャートオブジェクトとは、MT5のチャート上に配置できる図形、ラベル、ボタン、ライン、テキスト、背景パーツなどの総称です。MQL5では、これらをプログラムから作成・更新・削除できます。
パネルUIで重要なのは、チャートオブジェクトには大きく分けて「価格や時刻に結び付くもの」と「画面上のピクセル位置に結び付くもの」がある点です。
| 分類 | 代表例 | 座標の考え方 | 主な用途 |
|---|---|---|---|
| 価格・時刻系 | OBJ_HLINE、OBJ_TREND、OBJ_TEXT | 時間と価格を基準に配置 | 価格ライン、トレンドライン、チャート上の注記 |
| 画面固定系 | OBJ_LABEL、OBJ_BUTTON、OBJ_RECTANGLE_LABEL | チャートの角からのX/Y距離を基準に配置 | パネル、ボタン、ステータス表示 |
| 画像・編集系 | OBJ_BITMAP_LABEL、OBJ_EDIT | 画面上の固定位置を基準に配置 | 画像表示、入力欄、補助UI |
パネルUIでは、主に画面固定系のオブジェクトを使います。理由は、チャートをスクロールしても、価格が変化しても、画面上の同じ位置に表示し続けたいからです。
パネルUIで画面固定系を使う理由
ステータス表示やボタンは、価格位置に合わせて動く必要がありません。むしろ、チャートを拡大縮小した時や時間足を変更した時でも、同じ位置に残っている方が確認しやすくなります。
そのため、パネル背景は OBJ_RECTANGLE_LABEL、文字は OBJ_LABEL、操作ボタンは OBJ_BUTTON のように役割を分ける構成が扱いやすくなります。
主要Object種別の比較
パネルUIを設計する場合、最初に「どのObjectを何のために使うか」を決めます。ラベル、背景、ボタン、ラインを混同すると、表示崩れやクリック判定の混乱が起きやすくなります。
| Object種別 | 主な役割 | 向いている用途 | 注意点 |
|---|---|---|---|
| OBJ_LABEL | 文字表示 | ステータス、数値、説明文、見出し | 背景や枠は持たせず、文字専用にした方が管理しやすい |
| OBJ_RECTANGLE_LABEL | 矩形背景 | パネル枠、カード背景、セクション背景 | クリック対象と重なる場合はZORDERや前後関係を確認する |
| OBJ_BUTTON | クリック操作 | ON/OFF、APPLY、RESET、SNAP、HELP | 押下状態と実際のruntime状態を混同しない |
| OBJ_EDIT | 入力欄 | 数値入力、文字入力 | 入力値の検証とAPPLY反映を分ける |
| OBJ_HLINE | 水平ライン | 価格ライン、基準ライン、確認用ライン | 価格に結び付くためパネル部品とは分ける |
| OBJ_TEXT | 価格・時刻位置の文字 | ライン付近の注記 | 画面固定ラベルとは座標基準が異なる |
パネルを安定させる基本は、1つのObjectに複数の責務を持たせないことです。背景は背景、文字は文字、ボタンは操作、ラインは価格確認というように分けます。
OBJ_LABELの基本
OBJ_LABEL は、チャート上に固定位置のテキストを表示するために使います。パネルUIでは、タイトル、ステータス、現在モード、最終更新時刻、ブロック理由、HELP文などに向いています。
OBJ_LABELで決める主な項目
| 項目 | 代表プロパティ | 確認内容 |
|---|---|---|
| 表示位置 | OBJPROP_CORNER、OBJPROP_XDISTANCE、OBJPROP_YDISTANCE | どの角から何px離すか |
| 文字 | OBJPROP_TEXT | 表示する文字列 |
| 文字色 | OBJPROP_COLOR | 背景との視認性 |
| フォント | OBJPROP_FONT | 環境差が出にくいフォント |
| 文字サイズ | OBJPROP_FONTSIZE | VPSや高解像度環境で読めるか |
| アンカー | OBJPROP_ANCHOR | どの点を基準に配置するか |
| 選択可否 | OBJPROP_SELECTABLE | 誤ってドラッグされないか |
| 非表示扱い | OBJPROP_HIDDEN | オブジェクト一覧での扱い |
OBJ_LABELの最小例
以下は、左上にステータスラベルを作る最小例です。実務では、同じ名前のObjectが存在する場合は作成せず、文字だけ更新するupsert方式にすると扱いやすくなります。
void UpsertStatusLabel(const string name,const string text)
{
if(ObjectFind(0,name) < 0)
{
ObjectCreate(0,name,OBJ_LABEL,0,0,0);
ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,10);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,20);
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,10);
ObjectSetString(0,name,OBJPROP_FONT,"Arial");
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
}
ObjectSetString(0,name,OBJPROP_TEXT,text);
}この例では、表示と判定を分けるために、ラベルの文字列を内部判定の根拠にはしていません。判定結果を表示へ渡しているだけです。
OBJ_LABELで起きやすい問題
| 症状 | 主な原因 | 確認すること |
|---|---|---|
| 文字が重なる | Y座標、行間、文字サイズが固定されていない | row height、font size、section間隔 |
| 時間足変更で位置がずれる | 座標基準が混在している | CORNER、ANCHOR、XDISTANCE、YDISTANCE |
| 文字が途中で切れる | パネル幅に対して文字が長い | 短い文言、行分割、表示項目の絞り込み |
| 表示更新が重い | 毎tickで全文更新している | 値が変わった時だけ更新する |
| 他のObjectの下に隠れる | 前後関係やZORDERが整理されていない | 背景、文字、ボタンの重なり順 |
OBJ_RECTANGLE_LABELの基本
OBJ_RECTANGLE_LABEL は、画面固定の矩形を作るObjectです。パネル背景、カード背景、セクション枠、ステータスエリアの背景として使いやすいObjectです。
パネルUIでは、文字やボタンをそのままチャート上に置くより、背景矩形を作ってから、その上にラベルやボタンを配置した方が視認性を保ちやすくなります。
背景Objectとして使う時の考え方
背景Objectは、クリック対象ではなく、表示の土台として扱います。ボタンやラベルより背面に置き、選択不可、非表示扱い、必要に応じて背面化を行います。
| 設計項目 | 考え方 | 確認内容 |
|---|---|---|
| サイズ | パネル全体の幅・高さを固定する | XSIZE、YSIZE |
| 配置基準 | 他のUI部品と同じcornerを使う | CORNER、XDISTANCE、YDISTANCE |
| 前後関係 | ラベル・ボタンより背面に置く | BACK、ZORDER |
| 選択可否 | 通常はドラッグ不可にする | SELECTABLE |
| Object名 | prefixと用途を含める | 例:EAF_PANEL_BG_MAIN |
OBJ_RECTANGLE_LABELを使う時の注意
背景Objectを頻繁に削除・再作成すると、ちらつきや前後関係の乱れが起きやすくなります。基本は一度作成し、必要な時だけサイズや色を更新する方式にします。
また、背景Objectがクリック対象の上に乗ると、ボタンが押せない、クリックイベントが届かない、見た目はあるのに反応しないといった問題が起きます。背景、文字、ボタンの順序は設計時点で固定してください。
OBJ_BUTTONの基本
OBJ_BUTTON は、チャート上にクリック可能なボタンを作るObjectです。パネルEAでは、ON/OFF、APPLY、CANCEL、RESET、HELP、SNAP、表示切替などに使われます。
重要なのは、ボタンの押下状態と、EA内部の実行状態を混同しないことです。ボタンはあくまで操作の入口であり、実際に何を有効にするかはruntime state側で管理します。
OBJ_BUTTONで決める主な項目
| 項目 | 代表プロパティ | 確認内容 |
|---|---|---|
| 位置 | OBJPROP_CORNER、OBJPROP_XDISTANCE、OBJPROP_YDISTANCE | パネル内のボタン位置 |
| サイズ | OBJPROP_XSIZE、OBJPROP_YSIZE | クリックしやすい幅と高さ |
| 表示文字 | OBJPROP_TEXT | 短く意味が分かる文言 |
| 状態 | OBJPROP_STATE | 押下状態。ただしruntime stateとは分離 |
| 前後関係 | OBJPROP_ZORDER | 背景より前、不要な重なりなし |
| 選択可否 | OBJPROP_SELECTABLE | 誤操作で移動しないか |
ボタン名の命名ルール
ボタン名は、クリックイベントで識別するための重要なキーです。画面に表示する文字と、内部Object名は分けて考えます。
| 用途 | Object名の例 | 表示文字の例 |
|---|---|---|
| HELP表示 | EAF_UI_BTN_HELP | HELP |
| 状態記録 | EAF_UI_BTN_SNAP | SNAP |
| 設定反映 | EAF_UI_BTN_APPLY | APPLY |
| 編集取消 | EAF_UI_BTN_CANCEL | CANCEL |
| 表示切替 | EAF_UI_BTN_VIEW | VIEW |
Object名には、EA名や機能prefixを付けると、他のEAや手動Objectとの衝突を避けやすくなります。短く、用途が分かり、重複しない名前にします。
ObjectCreateとObjectSetの考え方
ObjectCreate はObjectを作成する関数です。作成後に、ObjectSetInteger、ObjectSetString、ObjectSetDouble などでプロパティを設定します。
実務では、Objectを毎回作り直すのではなく、「なければ作る、あれば必要なプロパティだけ更新する」方式が扱いやすくなります。この考え方をupsertと呼ぶことがあります。
Object操作関数の役割
| 関数 | 役割 | 使う場面 | 注意点 |
|---|---|---|---|
| ObjectCreate | Objectを作成する | 初回表示、再構築 | 作成名、種類、window番号を確認する |
| ObjectFind | Objectの存在を確認する | upsert前、削除前 | 見つからない場合の処理を決める |
| ObjectSetInteger | 整数系プロパティを設定する | 座標、色、サイズ、状態 | プロパティの型を間違えない |
| ObjectSetString | 文字列系プロパティを設定する | 表示文字、フォント、tooltip | 長すぎる文字列に注意する |
| ObjectSetDouble | 数値系プロパティを設定する | 価格、角度など | Object種別ごとの対象を確認する |
| ObjectDelete | Objectを削除する | 明示的な表示解除、不要Object整理 | 全削除ではなくprefix単位で絞る |
| ChartRedraw | チャート再描画を促す | まとめて更新した後 | 毎tick大量呼び出しは避ける |
毎tick作成ではなく差分更新にする
表示を更新するたびにObjectを削除して作り直すと、ちらつき、描画負荷、イベント混乱、前後関係の乱れが起きやすくなります。
実務では、初回だけObjectを作成し、以後は文字・色・位置など必要なプロパティだけを更新します。特にステータス表示は、前回値と同じなら更新しない設計が有効です。
OnChartEventでクリックを受ける
OnChartEvent は、チャート上のクリック、Objectクリック、チャート変更、キー操作などのイベントを受け取るためのイベントハンドラです。
ボタンUIでは、主に CHARTEVENT_OBJECT_CLICK を確認し、sparam に入るObject名を使って、どのボタンが押されたかを判断します。
OnChartEventの基本構造
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id == CHARTEVENT_OBJECT_CLICK)
{
if(sparam == "EAF_UI_BTN_HELP")
{
ShowHelpPanel();
return;
}
if(sparam == "EAF_UI_BTN_SNAP")
{
PrintPanelSnapshot();
return;
}
}
if(id == CHARTEVENT_CHART_CHANGE)
{
RequestPanelRelayout();
return;
}
}この例では、クリックされたObject名で処理を分けています。重要なのは、クリックイベントの中で重い処理を詰め込みすぎないことです。表示更新や再配置は、必要に応じて後続のOnTimerや軽量な再描画要求へ分けます。
クリックイベントで避けたい実装
| 避けたい実装 | 問題 | 代替方針 |
|---|---|---|
| Object名ではなく表示文字で判定する | 表示文言変更で処理が壊れる | 内部Object名で判定する |
| クリック直後に全Objectを再作成する | ちらつきや負荷が出やすい | 必要箇所だけ差分更新する |
| ボタン状態だけで実行可否を判断する | runtime stateとズレる場合がある | 内部状態を主、ボタン表示を従にする |
| 長い処理をOnChartEvent内で実行する | UI反応が重くなる | 状態変更と処理本体を分ける |
| CHART_CHANGEで毎回全再構築する | 時間足変更やリサイズで重くなる | 再配置要求を立てて軽量処理する |
パネルUIの基本設計
パネルUIは、見た目を整えるだけではなく、利用者が現在状態を確認しやすくするための設計です。どの項目を表示するか、どの操作をボタン化するか、どこまでをHELPやSNAPに分けるかを先に決めます。
基本構造はヘッダー・状態・操作・詳細に分ける
| 区画 | 役割 | 表示例 |
|---|---|---|
| ヘッダー | EA名、バージョン、状態の大枠 | Panel UI / v1.00 / READY |
| 状態エリア | 現在のruntime stateを表示 | MODE、AUTH、FILTER、LAST |
| 操作エリア | ボタン操作 | HELP、SNAP、APPLY、RESET |
| 詳細エリア | 補足情報や理由表示 | REASON、CHECK、ERROR |
| ログ連携 | 問い合わせ時の再現情報 | Expertsログ、Journalログ、発生時刻 |
row templateを決めてから配置する
パネルが崩れやすい原因のひとつは、Objectごとに個別のX/Y座標を手で調整し続けることです。最初にrow height、left margin、label width、value width、button widthを決め、各部品を同じ計算式で配置します。
この方式にすると、後から項目を増やす時も、既存の行間や列幅を壊しにくくなります。
パネル部品の責務分離
| 責務 | 担当 | 混同した場合の問題 |
|---|---|---|
| 表示 | OBJ_LABEL、OBJ_RECTANGLE_LABEL | 表示値を判定根拠にしてしまう |
| 操作 | OBJ_BUTTON、OBJ_EDIT | 押下状態と実行状態がずれる |
| 状態管理 | 内部変数、構造体 | 表示変更だけで挙動が変わる |
| 判定 | signal / gate / filter | UIの状態に依存して再現性が下がる |
| ログ | Print、SNAP、INIT | 画面だけでは原因追跡できない |
| メンテナンス | OnTimer、startup audit | 長時間稼働で崩れに気づきにくい |
表示系と判定系を分ける理由
チャート上の表示Objectは、あくまで人が確認するためのものです。EAやインジケーターの判定は、内部変数、構造体、取得済みデータ、runtime stateを基準にする必要があります。
表示Objectの文字や色を読み取って判定すると、文字変更、表示OFF、再描画失敗、時間足変更、再セット時の残存Objectなどで挙動が変わる可能性があります。
表示系と判定系の分離例
| 項目 | 表示系 | 判定系 |
|---|---|---|
| 現在モード | MODE: TREND と表示 | runtime.mode = MODE_TREND |
| ON/OFF | ボタン色やラベル | runtime.enabled = true / false |
| ブロック理由 | LAST: WAIT と表示 | block_reason enum |
| 入力中の値 | edit buffer表示 | applied valueとは分離 |
| エラー状態 | ERRORラベル | error_code、error_reason、last_error_time |
この分離ができていると、パネル表示に一時的な不具合が出ても、内部判定やログ確認で状態を追いやすくなります。
button stateとruntime stateの違い
OBJ_BUTTON には OBJPROP_STATE があります。これはボタンの押下状態を表すプロパティですが、EA内部の機能ON/OFFと必ず一致するとは限りません。
例えば、ボタンを押した直後に設定値の検証でNGになった場合、見た目は押された状態でも、実際の機能は有効化しない方がよい場合があります。そのため、button stateとruntime stateは分けて扱います。
| 状態 | 意味 | 管理場所 | 確認方法 |
|---|---|---|---|
| button state | ボタンの見た目上の押下状態 | OBJPROP_STATE | ObjectGetInteger |
| edit buffer | 画面上で編集中の値 | UI管理変数 | APPLY前の表示 |
| applied value | 実際に処理へ使う確定値 | runtime config | SNAP / INIT / ログ |
| runtime state | 現在の実行状態 | 内部状態管理 | Expertsログ、パネル表示 |
| block reason | 処理しない理由 | enum / string | LAST、SNAP、ログ |
APPLY、CANCEL、RESETのあるUIでは、この分離が特に重要です。編集中の値で即座に挙動が変わると、確認しにくくなります。画面で変更し、APPLYで確定し、ログやSNAPで反映状態を確認できる構造が扱いやすくなります。
Object lifecycleとOnDeinitの注意
Object lifecycleとは、Objectをいつ作り、いつ更新し、いつ削除し、再セット時にどう扱うかという設計です。パネルUIでは、見た目の整理だけでなく、終了時や再起動時の安定性も重要になります。
OnDeinitで全部削除すればよいとは限らない
EAやインジケーターの削除時に、すべてのObjectを広範囲に走査して削除しようとすると、環境やObject数によって終了処理が重くなる場合があります。特に他EA、手動ライン、残しておきたい確認ラインを巻き込まないようにする必要があります。
基本は、OnDeinitでは軽量処理に限定し、再セット時にstartup auditで残存Objectを検出・分類する方針が扱いやすくなります。
| 処理場面 | 行うこと | 避けること |
|---|---|---|
| OnInit | 必要Objectの作成、残存Objectの監査 | 理由なく全削除する |
| 通常更新 | 差分更新、必要箇所だけ再描画 | 毎tick全再作成する |
| OnChartEvent | クリック受付、状態変更要求 | 重い再構築を直接実行する |
| OnTimer | 軽量メンテナンス、再配置、self-check | 無制限にObject走査する |
| OnDeinit | timer停止、Comment解除、最小限の終了処理 | 広範囲Object削除、重いcleanup |
| 再セット時 | prefix、session、用途で分類 | 残存Objectを無条件採用する |
残してよいObjectと残すべきでないObjectを分ける
パネルのボタンや一時ステータスは、EA削除時に消した方が自然です。一方で、検証用ラインや履歴確認用ラインは、残す設計にする場合もあります。重要なのは、残すか消すかをObject種別ごとに仕様化することです。
| Object分類 | 例 | 再セット時の扱い |
|---|---|---|
| panel-control | ボタン、入力欄、タブ | 現在のEAが再作成する |
| status-display | 状態ラベル、HELP、SNAP表示 | 現在のEAが更新する |
| visual-only | 確認用ライン、説明ラベル | 表示専用として監査する |
| logic-reference | 判定に影響し得る管理ライン | 残存Objectを無条件採用しない |
| manual | ユーザーが手動で引いたライン | 原則として削除しない |
| unknown | owner不明Object | 削除せず監査対象にする |
残存オブジェクト・表示崩れ・フリーズ対策
パネルUIの不具合は、単純な座標ミスだけではありません。時間足変更、チャートリサイズ、EA再セット、他インジケーターとの重なり、Object数の増加、ログ過多、毎tick再描画などが組み合わさって起きる場合があります。
表示不具合の切り分け表
| 症状 | 確認する箇所 | 整理方針 |
|---|---|---|
| パネルが表示されない | ObjectCreate結果、prefix、window番号 | INITログとObjectFindで確認する |
| ボタンが押せない | ZORDER、背景Object、Object名 | 背景が前面に出ていないか確認する |
| 時間足変更で崩れる | CHART_CHANGE、座標基準、再配置処理 | row templateで再配置する |
| 文字が縮む・重なる | font size、row height、表示文字長 | 短い文言にし、行を分ける |
| チャートが重くなる | 毎tick Object更新、ChartRedraw回数 | 差分更新とOnTimerへ分離する |
| EA削除後にObjectが残る | OnDeinit方針、残存Object分類 | 残してよいものと消すものを分ける |
| 再セット後に古い表示が混ざる | session、prefix、startup audit | 旧Objectを実ロジックへ使わない |
Object名prefixの重要性
複数のEAやインジケーターを同じチャートで使う場合、Object名が衝突する可能性があります。Object名には、EA名、機能名、用途、必要に応じてMagicやチャートID相当の識別子を含めます。
string ObjName(const string role)
{
return "EAF_LEARN019_" + role;
}このようにprefixを統一すると、作成、更新、監査、削除の対象を絞りやすくなります。手動Objectや他EAのObjectを巻き込まないためにも、prefix設計は最初に決めておきます。
差分更新とOnTimerメンテナンス
チャートObject更新は、毎tickで重くなりやすい処理です。価格が動くたびにパネル全体を再作成するのではなく、必要な時だけ差分更新します。
OnTickとOnTimerの役割分担
| 処理 | 向いているイベント | 理由 |
|---|---|---|
| 価格更新に関係する軽い状態更新 | OnTick | 最新状態を反映しやすい |
| パネルの定期再配置 | OnTimer | 描画負荷を分散できる |
| Object欠損チェック | OnTimer | 毎tick確認する必要が薄い |
| HELP表示更新 | OnChartEvent / OnTimer | クリック契機または定期更新で十分 |
| 重いcleanup | 通常は行わない、必要時のみ | 誤削除や負荷を避ける |
| SNAPログ出力 | OnChartEvent | ユーザー操作で明示的に出す |
OnTimerメンテナンスの最小例
int OnInit()
{
EventSetTimer(1);
BuildPanel();
return INIT_SUCCEEDED;
}
void OnTimer()
{
if(g_panel_relayout_required)
{
RelayoutPanel();
g_panel_relayout_required = false;
}
UpdatePanelIfChanged();
}
void OnDeinit(const int reason)
{
EventKillTimer();
Comment("");
}この例では、OnDeinitで広範囲Object削除を行っていません。実際に削除するかどうかは、Object分類、prefix、EA仕様、残存時の扱いを決めてから実装します。
ログ・HELP・SNAPをパネルUIに組み込む
パネルUIは、画面で見るためだけではなく、問い合わせ前の情報整理にも使えます。HELP、SNAP、INIT/SELFCHECKを用意しておくと、利用者が現在状態を記録しやすくなります。
| 機能 | 役割 | 出力例 |
|---|---|---|
| HELP | 画面項目の意味を説明する | このボタンは表示切替用です |
| SNAP | 現在状態をログへ出す | mode、enabled、last_reason、object_count |
| INIT | 起動時状態を確認する | version、symbol、timeframe、object policy |
| SELFCHECK | 最低限の設定不備を確認する | prefix、timer、panel object、font |
| OBJECT_AUDIT | 残存Objectを整理する | found、ignored、current、unknown |
SNAPログでは、機密情報、口座番号、外部URL、認証トークンなどを出さないようにします。出すのは、状態確認に必要な分類名、ON/OFF、reason、時刻、バージョン、Object数などに限定します。
パネルEA開発依頼前に整理すること
パネルEAやチャートUI付きインジケーターの開発を依頼する場合は、見た目の希望だけでなく、どの情報を表示し、どの操作をボタン化し、どの状態をログへ残すかを整理しておくと仕様化しやすくなります。
依頼前に整理する項目
| 項目 | 整理する内容 | 補足 |
|---|---|---|
| 対象ツール | EA、インジケーター、裁量補助パネルなど | 発注機能の有無も分ける |
| 表示したい情報 | モード、状態、理由、数値、最終更新時刻 | 重要度順に並べる |
| ボタン操作 | HELP、SNAP、表示切替、APPLYなど | 売買系操作がある場合は別途仕様化 |
| 入力欄 | 数値入力、ON/OFF、選択肢 | edit bufferとAPPLYの有無を決める |
| 表示位置 | 左上、右上、左下、サブウィンドウなど | チャートの邪魔にならない位置を検討 |
| 更新頻度 | tickごと、秒ごと、新バーごと | 描画負荷に関係する |
| ログ | INIT、SNAP、CLICK、ERROR、OBJECT_AUDIT | 問い合わせ前整理に役立つ |
| 終了時動作 | Objectを消すか、ラインを残すか | OnDeinit方針を明確にする |
| スクリーンショット | 希望レイアウト、現状不具合画像 | 表示崩れの再現に役立つ |
問い合わせ時にあると確認しやすい情報
パネル表示やObject関連の不具合を相談する場合は、EA名、バージョン、対象チャート、時間足、発生時刻、Expertsログ、Journalログ、スクリーンショット、再現手順を整理してください。
特に、時間足変更時だけ崩れるのか、EA削除時に残るのか、再セット時に混ざるのか、長時間放置で重くなるのかを分けると、原因を切り分けやすくなります。
次に読む技術講座
この講座とあわせて確認すると、MT5・MQL5開発、検証、不具合調査の流れを整理しやすくなります。
| No | 講座 | 確認できること |
|---|---|---|
| LEARN-020 | MQL5イベント処理完全ガイド | OnChartEventなどイベント処理を確認する |
| LEARN-022 | MQL5長時間稼働・安定化完全ガイド | Object管理と長時間稼働を確認する |
| LEARN-012 | MQL5 EA設計パターン完全ガイド | UIと判定系の責務分離を確認する |
| LEARN-015 | MQL5クラス・構造体・配列設計完全ガイド | パネル状態管理のデータ構造を確認する |
次に確認するページ
技術講座を確認した後、導入・商品確認・開発相談・不具合報告へ進む場合は、以下のページも確認してください。
| ページ | 確認できること |
|---|---|
| 技術講座一覧 | MT5・MQL5・EA開発に関する技術講座を順番に確認できます。 |
| 導入ガイド | EA、インジケーター、補助ツールを導入する前の確認事項を整理できます。 |
| 商品一覧 | EAファンクラブで扱う補助ツール、インジケーター、コピーEAなどを確認できます。 |
| 開発代行ページ | EA、インジケーター、補助ツールの新規作成・改修相談を確認できます。 |
| 不具合報告・サポート依頼 | ログ、スクリーンショット、再現手順を整理して相談する場合に確認できます。 |
よくある質問
OBJ_LABELとOBJ_RECTANGLE_LABELは何が違いますか?
OBJ_LABEL は主に文字表示に使います。OBJ_RECTANGLE_LABEL は矩形の背景や枠に使います。パネルUIでは、背景を OBJ_RECTANGLE_LABEL、文字を OBJ_LABEL に分けると管理しやすくなります。
ボタンを押した時の処理はどこで受けますか?
OnChartEvent で受けます。CHARTEVENT_OBJECT_CLICK を確認し、sparam に入るObject名で押されたボタンを判定します。表示文字ではなくObject名で分岐するのが基本です。
OnDeinitで全部削除すればよいですか?
常に全部削除すればよいとは限りません。パネル操作用Objectは削除対象になりやすい一方、検証用ラインや履歴確認用Objectは残す仕様にする場合があります。広範囲削除ではなく、prefix、用途、Object分類で対象を絞ることが重要です。
表示オブジェクトを判定ロジックに使ってよいですか?
基本的には避けます。表示Objectは人が確認するための出力です。判定は内部変数、構造体、取得データ、runtime stateを基準にし、表示はその結果を反映するだけにします。
パネルが重くなる原因は何ですか?
毎tickで大量のObjectを削除・再作成している、ChartRedrawを頻繁に呼んでいる、Object数が増え続けている、ログが多すぎる、時間足変更時に全再構築している、といった原因が考えられます。差分更新とOnTimerメンテナンスで負荷を分散します。
時間足変更で表示が崩れる時は何を確認しますか?
CHARTEVENT_CHART_CHANGE の受け取り、座標基準、row template、Objectの再配置処理、前後関係、font size、パネル幅を確認します。個別のY座標を都度微調整するより、配置ルール全体を見直す方が安定しやすくなります。
EA削除時にラインが残っても問題ですか?
仕様として残すObjectであれば問題とは限りません。ただし、再セット時に古いラインを実ロジックへ無条件で使わない設計が必要です。残すObject、消すObject、監査だけするObjectを分類してください。
パネルEA開発依頼前に何を用意しますか?
希望する表示項目、ボタン操作、入力欄、表示位置、更新頻度、発生している不具合、Expertsログ、Journalログ、スクリーンショット、再現手順を整理してください。既存EAや既存インジがある場合は、対象ファイル名とバージョンも記録してください。
まとめ
MQL5のチャートオブジェクトは、パネルUI、状態表示、ボタン操作、確認用ラインを作るうえで重要な機能です。ただし、Objectを表示できることと、安定して運用・検証・問い合わせ対応できることは別です。
パネルUIでは、OBJ_LABEL、OBJ_RECTANGLE_LABEL、OBJ_BUTTON の役割を分け、OnChartEvent でクリックを受け、Object名prefix、差分更新、OnTimerメンテナンス、Object lifecycle、OnDeinit方針を整理します。
特に重要なのは、表示系と判定系を分けること、button stateとruntime stateを分けること、残存Objectを実ロジックへ無条件で使わないことです。これらを整理しておくと、パネル表示の不具合や再セット時の確認がしやすくなります。
学習内容を確認しても整理が難しい場合は、EA名、バージョン、setファイル、Expertsログ、Journalログ、発生時刻、スクリーンショットを整理したうえで相談してください。

