MQL5インジケーターEA化実務ノート|サイン取得・確定足・リペイント確認の考え方
MQL5でサインインジケーターをEA化する時、単に「矢印が出たらエントリー」と考えると、実装後に問題が出やすくなります。
インジケーターのサインは、表示されている見た目だけで判断できるとは限りません。どのbufferにサイン値が入るのか、shift=0を見るのかshift=1を見るのか、未確定足で値が変わるのか、過去サインがリペイントするのか、CopyBufferが失敗した時にどう扱うのかを整理する必要があります。
インジケーターEA化で重要なのは、表示サイン、取得値、確定足、Signal Snapshot、Entry判断を分けることです。
この記事では、MQL5でインジケーターサインをEA化する時の設計判断を、開発実務ノートとして整理します。完成EAソース全文、独自インジケーターの中核条件、外部シート制御ロジック、認証ロジック、endpoint、token、URL実値、実運用set値、中核Entry条件は公開しません。
本記事は、投資判断や売買指示ではなく、MQL5のインジケーターEA化を設計・検証・サポートしやすくするための技術記事です。
- この記事で扱う実務課題
- なぜインジケーターEA化では設計整理が必要なのか
- インジケーターEA化で分けるべき責務
- iCustomとインジケーターハンドルの考え方
- CopyBufferで見るべきポイント
- shift=0とshift=1の違い
- リペイント確認が必要な理由
- サイン表示とbuffer値は同じとは限らない
- 実コード例1:インジケーターハンドルを管理する
- 実コード例2:CopyBuffer取得結果を分ける
- 実コード例3:Signal Snapshotとして固定する
- 実コード例4:確定足で判定する
- ログで確認するポイント
- バックテストとリアルで確認すること
- よくある失敗例
- 導入前・開発依頼前に整理する情報
- 関連する技術講座・確認ページ
- FAQ
- 関連する開発実務ノート
- まとめ
この記事で扱う実務課題
| 項目 | この記事で扱う内容 | 扱わない内容 |
|---|---|---|
| 目的 | インジケーターサインをEA化する時の値取得・確定足・リペイント確認 | 利益を狙う売買ロジック、具体的なEntry条件 |
| 主な対象 | iCustom、CopyBuffer、buffer番号、shift、確定足、Signal Snapshot | 完成EAソース全文、実運用コード全文 |
| 設計観点 | サイン取得失敗、未確定足変動、リペイント、ログ追跡、検証再現性 | 独自インジケーターの中核ロジック、実運用set値 |
| コード例 | 一般化したhandle管理、CopyBuffer取得、Snapshot化、確定足判定 | 実サイン条件、独自優位性のある判定式 |
| 読者 | MQL5開発者、サインインジをEA化したい人、検証担当者 | 売買判断や推奨設定を知りたい人 |
なぜインジケーターEA化では設計整理が必要なのか
チャート上で矢印やサインが見えていても、EA側で同じタイミング・同じ値を取得できるとは限りません。
インジケーターEA化でよく起きる問題は次の通りです。
| 現象 | 原因の例 | 確認すべき責務 |
|---|---|---|
| サインが見えるのにEAが入らない | buffer番号違い、shift違い、CopyBuffer失敗 | indicator read / signal snapshot |
| EAが早すぎる場所で入る | 未確定足shift=0を使っている | confirmed bar / signal timing |
| 過去検証とリアルが違う | リペイント、未確定足変動、計算タイミング差 | repaint check / validation |
| サインが消えたのにEntryしている | 一時的な値をSnapshotとして固定している | snapshot policy / gate |
| EAを再起動すると挙動が変わる | handle再作成、初期バー不足、履歴読み込み不足 | OnInit / handle / bars ready |
| バックテストとリアルで一致しない | tick model、未確定足、インジ内部仕様の差 | BT condition / realtime validation |
インジケーターEA化では、表示されているサインとEAが取得する値を切り分けて確認する必要があります。
インジケーターEA化で分けるべき責務
サインインジケーターをEA化する時は、次の責務を分けます。
| 責務 | 役割 | 混同すると起きる問題 |
|---|---|---|
| indicator handle | iCustomなどでインジケーターハンドルを作る | handle不正、再初期化不備、解放漏れが起きる |
| buffer read | CopyBufferで値を取得する | 取得失敗とサインなしを混同する |
| signal snapshot | 取得した値を判定用に固定する | 未確定足の変動に振り回される |
| confirmed bar | 確定足で判定するかを決める | リアルで早すぎるEntryになる |
| repaint check | 過去サインが変わるか確認する | バックテスト上だけ良く見える可能性がある |
| entry gate | サインがあってもEntryしてよいか確認する | riskやduplicate gateを飛ばす |
| log | 取得値、shift、buffer、reasonを記録する | サイン不一致の原因を追えない |
特に重要なのは、CopyBufferで値が取れなかった状態と、サインがない状態を混同しないことです。
iCustomとインジケーターハンドルの考え方
MQL5でカスタムインジケーターをEAから使う場合、iCustomなどでインジケーターハンドルを作成します。
ハンドルが正しく作成できていない場合、CopyBufferで値を取得できません。また、EA終了時や再初期化時には、必要に応じてIndicatorReleaseで解放する設計も必要です。
| 確認項目 | 確認する理由 |
|---|---|
| handleがINVALID_HANDLEではないか | インジケーターが作成できているか確認するため |
| インジケーター名が正しいか | ファイル名、パス、拡張子の扱いを確認するため |
| input引数が一致しているか | チャート表示時とEA呼び出し時の条件差を防ぐため |
| 必要バー数が揃っているか | 計算前の値を使わないため |
| OnDeinitで解放するか | handle管理を明確にするため |
ハンドル作成失敗は、サインなしではありません。ログ上もHANDLE_FAILやINVALID_HANDLEとして分ける必要があります。
CopyBufferで見るべきポイント
CopyBufferは、インジケーターのbuffer値をEA側で取得するために使います。
CopyBufferで重要なのは、どのbuffer番号から、どのshiftの値を、何本取得するかです。
| 項目 | 意味 | 確認すること |
|---|---|---|
| buffer index | どのbufferを見るか | BUYサイン、SELLサイン、補助値がどのbufferか |
| shift | どの足を見るか | 0は未確定足、1は直近確定足として扱うことが多い |
| count | 何本取得するか | 1本だけで足りるか、過去比較が必要か |
| 戻り値 | 取得できた本数 | 取得失敗と値なしを分ける |
| EMPTY_VALUE | サインなし表現の候補 | インジ仕様により0やEMPTY_VALUEの扱いが違う |
CopyBufferが失敗した場合は、サインなしではなく、値取得失敗です。ENTRY判定へ進める前に、取得結果を検証します。
shift=0とshift=1の違い
インジケーターEA化で重要なのが、shiftの扱いです。
一般的に、shift=0は現在形成中の足、shift=1は直近の確定足を意味します。未確定足のサインは、足が確定するまで変わる場合があります。
| shift | 意味 | 注意点 |
|---|---|---|
| shift=0 | 現在足 | リアルタイムで値が変わる可能性がある |
| shift=1 | 直近確定足 | 確定後の値として扱いやすい |
| shift=2以降 | 過去足 | リペイント確認や過去比較に使う場合がある |
EA化では、サインを早く拾いたいのか、確定後に安定して拾いたいのかを仕様として決める必要があります。
未確定足で動くEAは、早く反応できる一方で、サインが消えたり変わったりする可能性を受け入れる必要があります。確定足で動くEAは、反応は遅くなりますが、検証再現性は高めやすくなります。
リペイント確認が必要な理由
リペイントとは、過去に出ていたサインや値が後から変わることです。
リペイントするインジケーターをEA化する場合、バックテスト上ではきれいに見えても、リアルタイムでは同じように動かない可能性があります。
| 確認項目 | 理由 |
|---|---|
| 過去の矢印が変わるか | サイン履歴が後から変わる可能性を確認するため |
| shift=0だけ変わるのか | 未確定足だけの変動か確認するため |
| shift=1以降も変わるのか | 確定足後も変わるならEA化リスクが高いため |
| バックテストとリアルで差があるか | 検証再現性を確認するため |
| buffer値と表示Objectが一致するか | 見た目とEA取得値の差を確認するため |
リペイント自体が必ず悪いわけではありません。ただし、EA化する場合は、どのタイミングの値を使うのか、過去サインの変化をどう扱うのかを明確にする必要があります。
サイン表示とbuffer値は同じとは限らない
チャート上に矢印が表示されていても、その矢印がEAから直接読めるbuffer値とは限りません。
インジケーターによっては、矢印Objectをチャート上に描画しているだけで、bufferには値を出していない場合があります。また、BUYサインとSELLサインが別bufferで管理されている場合もあります。
| 確認対象 | 注意点 |
|---|---|
| bufferサイン | CopyBufferで取得しやすい |
| Objectサイン | Object名や座標から判断する必要があり、EA化では慎重に扱う |
| コメント表示 | 画面表示であり、判定の真実にしない方が安全 |
| 色変化 | buffer構造やDRAW設定により読み方が変わる |
| アラートだけのサイン | EA側で同じ条件を再現できるか確認が必要 |
EA化前には、サインがbufferで取れるのか、Objectでしか出ていないのか、アラートだけなのかを確認します。
実コード例1:インジケーターハンドルを管理する
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したインジケーターハンドル管理例です。
// 実運用EAの完成ソースではありません。
int g_indicatorHandle = INVALID_HANDLE;
bool CreateIndicatorHandle()
{
// 実際のEAでは、インジケーター名やinput引数を仕様に合わせて設定します。
// この記事では実インジケーター名や中核条件は扱いません。
g_indicatorHandle = iCustom(_Symbol, PERIOD_CURRENT, "SampleIndicator");
if(g_indicatorHandle == INVALID_HANDLE)
{
Print("DIAG/INDICATOR: event=HANDLE_FAIL",
" reason=INVALID_HANDLE",
" symbol=", _Symbol);
return false;
}
Print("DIAG/INDICATOR: event=HANDLE_OK",
" reason=ICUSTOM_CREATED",
" symbol=", _Symbol);
return true;
}
void ReleaseIndicatorHandle()
{
if(g_indicatorHandle == INVALID_HANDLE)
return;
IndicatorRelease(g_indicatorHandle);
g_indicatorHandle = INVALID_HANDLE;
Print("DIAG/INDICATOR: event=HANDLE_RELEASE",
" reason=INDICATOR_RELEASE_DONE");
}この例では、iCustomでインジケーターハンドルを作り、失敗時はHANDLE_FAILとしてログに残します。handle作成失敗は、サインなしとは別の状態です。
実コード例2:CopyBuffer取得結果を分ける
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したCopyBuffer取得例です。
// 実運用EAの完成ソースではありません。
struct BufferReadResult
{
bool ok;
double value;
int copied;
int bufferIndex;
int shift;
string reason;
};
BufferReadResult ReadIndicatorBuffer(int bufferIndex, int shift)
{
BufferReadResult result;
result.ok = false;
result.value = EMPTY_VALUE;
result.copied = 0;
result.bufferIndex = bufferIndex;
result.shift = shift;
result.reason = "INIT";
if(g_indicatorHandle == INVALID_HANDLE)
{
result.reason = "INVALID_HANDLE";
return result;
}
double values[1];
ArraySetAsSeries(values, true);
ResetLastError();
int copied = CopyBuffer(g_indicatorHandle, bufferIndex, shift, 1, values);
result.copied = copied;
if(copied != 1)
{
result.reason = "COPYBUFFER_FAIL";
return result;
}
result.ok = true;
result.value = values[0];
result.reason = "COPYBUFFER_OK";
return result;
}この例では、CopyBufferの取得失敗と、取得できた値を分けています。copiedが1ではない場合は、サインなしではなく、取得失敗として扱います。
実コード例3:Signal Snapshotとして固定する
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化したSignal Snapshot例です。
// 実運用EAの完成ソースではありません。
enum IndicatorSignalSide
{
IND_SIGNAL_NONE = 0,
IND_SIGNAL_BUY,
IND_SIGNAL_SELL
};
struct IndicatorSignalSnapshot
{
bool valid;
IndicatorSignalSide side;
int shift;
datetime barTime;
double rawValue;
string reason;
};
IndicatorSignalSnapshot BuildSignalSnapshot(int shift)
{
IndicatorSignalSnapshot snap;
snap.valid = false;
snap.side = IND_SIGNAL_NONE;
snap.shift = shift;
snap.barTime = iTime(_Symbol, PERIOD_CURRENT, shift);
snap.rawValue = EMPTY_VALUE;
snap.reason = "INIT";
BufferReadResult buyBuffer = ReadIndicatorBuffer(0, shift);
BufferReadResult sellBuffer = ReadIndicatorBuffer(1, shift);
if(!buyBuffer.ok && !sellBuffer.ok)
{
snap.reason = "BUFFER_READ_FAIL";
return snap;
}
if(buyBuffer.ok && buyBuffer.value != EMPTY_VALUE)
{
snap.valid = true;
snap.side = IND_SIGNAL_BUY;
snap.rawValue = buyBuffer.value;
snap.reason = "BUY_SIGNAL";
return snap;
}
if(sellBuffer.ok && sellBuffer.value != EMPTY_VALUE)
{
snap.valid = true;
snap.side = IND_SIGNAL_SELL;
snap.rawValue = sellBuffer.value;
snap.reason = "SELL_SIGNAL";
return snap;
}
snap.reason = "NO_SIGNAL";
return snap;
}この例では、取得値をその場で直接Entryへ使わず、IndicatorSignalSnapshotとして固定しています。
実際のEAでは、このSnapshotをGATE、risk、duplicate controlへ渡し、最終的にexecution層へ進むかを判断します。
実コード例4:確定足で判定する
以下は、設計判断を理解するために一般化した学習用コード例です。完成EAのソース全文ではありません。
// 学習用に一般化した確定足判定例です。
// 実運用EAの完成ソースではありません。
int SignalShiftForConfirmedBar()
{
return 1;
}
void EvaluateConfirmedBarSignal()
{
int shift = SignalShiftForConfirmedBar();
IndicatorSignalSnapshot snap = BuildSignalSnapshot(shift);
Print("DIAG/INDICATOR_SIGNAL: event=SNAPSHOT",
" valid=", snap.valid,
" shift=", snap.shift,
" bar_time=", TimeToString(snap.barTime, TIME_DATE | TIME_MINUTES),
" reason=", snap.reason);
if(!snap.valid)
{
Print("DIAG/ENTRY: event=SKIP",
" reason=", snap.reason);
return;
}
Print("DIAG/ENTRY: event=CANDIDATE",
" reason=CONFIRMED_BAR_SIGNAL",
" side=", (int)snap.side);
// 実際のEAでは、この後にGATE / risk / executionへ分けて渡します。
// この記事では実Entry条件やOrderSend処理は扱いません。
}この例では、shift=1を使って確定足のサインを評価しています。未確定足を使う場合は、サイン変動やリペイントの扱いを別途仕様化する必要があります。
ログで確認するポイント
インジケーターEA化では、サインが出たかどうかだけでなく、どのbuffer、どのshift、どのbar timeを見たかが重要です。
| ログ区分 | 確認できること | 例 |
|---|---|---|
| INDICATOR | handle作成・解放 | HANDLE_OK、HANDLE_FAIL、HANDLE_RELEASE |
| BUFFER_READ | CopyBuffer取得結果 | COPYBUFFER_OK、COPYBUFFER_FAIL |
| INDICATOR_SIGNAL | サインSnapshot | BUY_SIGNAL、SELL_SIGNAL、NO_SIGNAL |
| SHIFT | どの足を見たか | shift=0、shift=1 |
| BAR_TIME | 対象バー時刻 | bar_time |
| REPAINT_CHECK | 過去サイン変化の確認 | VALUE_CHANGED、VALUE_STABLE |
| ENTRY | Entry候補へ渡したか | CANDIDATE、SKIP |
「サインが出ているのにEAが入らない」という相談では、まず表示サインとEA取得値が一致しているかを確認します。
バックテストとリアルで確認すること
インジケーターEA化では、バックテストだけでなく、リアルタイムでの挙動確認も重要です。
| 確認項目 | バックテスト | リアルタイム確認 |
|---|---|---|
| サイン発生位置 | 履歴上のサイン位置を確認 | リアルで同じタイミングに出るか確認 |
| shift | shift=0 / shift=1の違いを確認 | 未確定足で変動するか確認 |
| リペイント | 履歴だけでは見えにくい場合がある | 発生後にサインが変わるか観察 |
| CopyBuffer値 | ログで値取得を確認 | チャート表示とログ値を比較 |
| Entry候補 | 候補発生時刻を確認 | リアルで候補が固定されるか確認 |
バックテスト上で見えるサインが、リアルタイムで同じように使えるとは限りません。特に、未確定足サインやリペイント型インジケーターでは、リアルタイム確認が重要です。
よくある失敗例
失敗1:チャート上の矢印だけを見てEA化する
表示されている矢印と、EAがCopyBufferで取得できる値は同じとは限りません。buffer番号、shift、EMPTY_VALUE、Object表示かどうかを確認する必要があります。
失敗2:CopyBuffer失敗をサインなしとして扱う
CopyBufferが失敗した状態と、サインがない状態は違います。COPYBUFFER_FAILとNO_SIGNALはログ上も分けるべきです。
失敗3:shift=0を確定サインとして扱う
shift=0は現在足であり、値が変わる可能性があります。確定足で判断したい場合は、shift=1を使う方針を検討します。
失敗4:リペイント確認をしない
過去サインが変わるインジケーターをそのままEA化すると、バックテストとリアル稼働で差が出る可能性があります。
失敗5:handle作成失敗を見逃す
iCustomでhandleが作成できていない場合、EAは値を取得できません。INVALID_HANDLEを起動時に確認し、ログに残す必要があります。
失敗6:インジケーターinput条件がチャート表示とEA呼び出しで違う
チャートに表示したインジケーターとEAから呼び出したインジケーターでinputが違うと、サイン位置が変わる場合があります。
失敗7:サイン取得とEntry実行を直接つなぐ
サインがあっても、GATE、risk、duplicate control、execution precheckを通す必要があります。サイン取得はEntry候補の一部として扱います。
導入前・開発依頼前に整理する情報
インジケーターEA化を依頼する場合、次の情報を整理しておくと仕様確認がスムーズになります。
- 対象インジケーター名
- インジケーターのinput設定
- BUYサインとSELLサインの見た目
- BUY / SELLのbuffer番号
- サインなしの値が0か、EMPTY_VALUEか、別の値か
- shift=0で使うのか、shift=1で使うのか
- 確定足でEntryするのか、未確定足でEntryするのか
- リペイントするかどうか
- サイン発生後に消えることがあるか
- チャート表示とCopyBuffer値が一致するか
- Entryを1回だけにするか、同一方向の再Entryを許可するか
- サイン取得後に通すGATE / risk条件
- ログに出すbuffer、shift、bar time、reason
- バックテストとリアル確認の手順
インジケーターEA化では、見た目のサインだけでなく、EAが取得できる値、確定タイミング、リペイントの有無を整理することが重要です。
関連する技術講座・確認ページ
| ページ | 確認できること |
|---|---|
| 技術講座ハブ | MQL5やMT5開発に関する講座一覧 |
| MQL5 CopyBufferとインジケーターハンドル管理を実コードで解説 | CopyBuffer、インジケーターハンドル、値取得の考え方 |
| MQL5ログファースト設計を実コードで解説 | 取得失敗や見送り理由をログで追う考え方 |
| MQL5デバッグ・ログファースト開発完全ガイド | ログ確認、デバッグ、原因調査の基本 |
| MT5開発依頼前に用意する資料まとめ | 仕様書、setファイル、ログ、スクリーンショットの整理 |
| 不具合報告・調査依頼について | 不具合相談前に送る情報 |
| 免責事項・リスク説明 | 投資判断、損益、利用上の注意に関する確認 |
FAQ
チャートに矢印が出ていればEAからも同じように読めますか?
必ずしもそうではありません。矢印がbufferに出ているのか、Objectとして描画されているのか、アラートだけなのかを確認する必要があります。
CopyBufferで値が取れない場合はサインなしですか?
違います。CopyBuffer失敗とサインなしは別です。取得失敗はCOPYBUFFER_FAIL、サインなしはNO_SIGNALとして分けるべきです。
shift=0とshift=1はどちらを使うべきですか?
仕様によります。早く反応したいならshift=0を使う場合がありますが、値が変わる可能性があります。確定足で安定して判定したい場合はshift=1を使う方針を検討します。
リペイントするインジケーターはEA化できませんか?
EA化自体は可能な場合があります。ただし、過去サインが変わる前提で、どのタイミングの値を使うか、検証とリアルの差をどう扱うかを明確にする必要があります。
インジケーターinputはEA側でも同じにする必要がありますか?
基本的には同じ条件で確認する必要があります。チャート表示時とEA呼び出し時でinputが違うと、サイン位置や値が変わる可能性があります。
サインが出たらすぐOrderSendしてよいですか?
避けた方が安全です。サインはEntry候補の一部です。GATE、risk、duplicate control、execution precheckを通してから実行する設計が必要です。
バックテストで良ければリアルでも同じになりますか?
必ずしも同じにはなりません。未確定足、リペイント、tick model、履歴計算、リアルタイム更新の違いにより差が出る場合があります。
実装コードがなくてもインジケーターEA化の相談はできますか?
可能です。インジケーター名、input設定、サイン表示、buffer番号、shift方針、リペイント有無、ログ確認項目が整理されていれば、相談を進めやすくなります。
関連する開発実務ノート
インジケーターをEA化する場合は、サイン取得だけでなく、EA全体の責務分離、ログ設計、バックテスト条件、MT4資産のMT5再設計も関係します。
- MQL5 EA設計実務ノート|signal・execution・risk・exitを分ける理由
- MQL5ログファースト開発実務ノート|不具合調査しやすいEA・インジの作り方
- MQL5バックテスト実務ノート|検証条件・最適化・リアル差分を記録する考え方
- MT4資産をMT5へ作り直す実務ノート|移植ではなく再設計で考える理由
まとめ
MQL5でインジケーターサインをEA化する時は、チャート上の見た目だけで判断せず、EAが取得できる値、buffer番号、shift、確定足、リペイントの有無を整理することが重要です。
特に、次の4点を分けると、サイン不一致、早すぎるEntry、バックテストとリアルの差、CopyBuffer失敗の原因を切り分けやすくなります。
- indicator handle:iCustomなどでインジケーターを正しく呼び出す
- buffer read:CopyBufferでどのbuffer・shiftの値を取得したか確認する
- Signal Snapshot:取得値を判定用に固定し、reason付きで残す
- confirmed bar / repaint check:確定足で使うか、未確定足やリペイントを許容するか決める
また、CopyBuffer失敗とNO_SIGNALを混同しないこと、サイン取得とOrderSendを直接つなげないことも重要です。
完成EAの中核Entry条件や独自インジケーターの内部ロジックを公開しなくても、iCustom、CopyBuffer、buffer番号、shift、確定足、リペイント確認の考え方を理解しておくことで、開発依頼、既存インジケーターのEA化、検証、不具合調査、販売後サポートの品質を上げやすくなります。

