MQL5インジケーター関数辞典|iCustom・CopyBuffer・SetIndexBuffer・OnCalculate一覧
MQL5でインジケーターを開発したり、EAからインジケーター値を取得したりする時は、複数の関数を役割ごとに使い分ける必要があります。
たとえば、カスタムインジケーター側ではOnCalculate、SetIndexBuffer、PlotIndexSetIntegerなどを使い、EA側ではiCustom、CopyBuffer、BarsCalculated、IndicatorReleaseなどを使います。
これらの関数を混同すると、「インジケーターは表示されるのにEAで値が取れない」「buffer番号が分からない」「CopyBufferが失敗する」「iCustomのhandleがINVALID_HANDLEになる」「バックテスト開始直後だけ値が取れない」といった問題が起きやすくなります。
このページでは、MQL5のインジケーター関連関数を、インジケーター開発側、EA連携側、buffer管理、描画設定、ログ確認、解放処理の観点から整理します。
なお、このページはMQL5開発における技術確認を目的とした内容です。売買判断、推奨エントリー、推奨ロット、利益保証、損失回避保証を行うものではありません。
- MQL5インジケーター関数を役割で分ける
- 関数一覧の早見表
- OnInit:初期化処理
- OnInitの基本コード例
- OnCalculate:インジケーター計算の中心
- OnCalculateの簡易コード例
- SetIndexBuffer:配列をインジケーターバッファへ割り当てる
- SetIndexBufferのコード例
- PlotIndexSetInteger:描画タイプや矢印を設定する
- Plot設定のコード例
- iCustom:カスタムインジケーターをEAから呼ぶ
- iCustomのコード例
- CopyBuffer:handleからbuffer値を取得する
- CopyBufferのコード例
- BarsCalculated:計算済みバー数を確認する
- BarsCalculatedのコード例
- IndicatorRelease:不要になったhandleを解放する
- IndicatorReleaseのコード例
- EMPTY_VALUE:値なし・サインなしを表す値
- Buffer・Plot・Handleを混同しない
- インジケーター関数をEA化で使う時の確認順序
- OnCalculateで確認したい実務ポイント
- SetIndexBufferでよくある設計ミス
- Plot設定は表示用、CopyBufferは値取得用
- 辞典記事としての使い方
- 標準インジケーター関数との関係
- インジケーター開発側とEA連携側の違い
- よくあるトラブルと関数の対応
- ログに残すべき項目
- 実務チェックリスト
- 開発・改修依頼前に整理したい情報
- よくある質問
- 関連ページ
- まとめ
MQL5インジケーター関数を役割で分ける
MQL5のインジケーター関連関数は、ひとまとめに覚えるより、役割で分けた方が理解しやすくなります。
| 分類 | 主な関数 | 役割 |
|---|---|---|
| インジケーター本体 | OnInit / OnCalculate / OnDeinit | 初期化、計算、終了処理を担当する |
| buffer管理 | SetIndexBuffer | 配列をインジケーターバッファへ割り当てる |
| 描画設定 | PlotIndexSetInteger / PlotIndexSetDouble / PlotIndexSetString | ライン、矢印、色、表示名などを設定する |
| EAからの呼び出し | iCustom / iMA / iRSI / iATR | インジケーターハンドルを作成する |
| 値取得 | CopyBuffer | handleからbuffer値を取得する |
| 計算状態確認 | BarsCalculated | インジケーターの計算済みバー数を確認する |
| 解放処理 | IndicatorRelease | 不要になったhandleを解放する |
インジケーターを作る側と、EAから読む側では使う関数が異なります。たとえば、SetIndexBufferはインジケーター本体側で使い、CopyBufferはEA側で値を読む時に使います。
関数一覧の早見表
まず、主要なインジケーター関連関数の役割を一覧で確認します。
| 関数 | 使う場所 | 主な用途 |
|---|---|---|
| OnInit | インジ / EA | 初期化、buffer設定、handle生成 |
| OnCalculate | インジ | インジケーター値の計算 |
| OnDeinit | インジ / EA | 終了処理、handle解放、Object整理 |
| SetIndexBuffer | インジ | 描画用・計算用bufferの割り当て |
| PlotIndexSetInteger | インジ | 描画タイプ、矢印コード、線種などの設定 |
| PlotIndexSetString | インジ | Plot名や表示ラベルの設定 |
| iCustom | EA / インジ | カスタムインジケーターhandleの作成 |
| CopyBuffer | EA / インジ | インジケーターbuffer値の取得 |
| BarsCalculated | EA / インジ | 計算済みバー数の確認 |
| IndicatorRelease | EA / インジ | handleの解放 |
この辞典では、個々の関数を単体で説明するだけでなく、「どの場面で使い、何と組み合わせるか」を重視して整理します。
OnInit:初期化処理
OnInitは、インジケーターやEAがチャートへセットされた時、または再初期化された時に呼ばれる初期化処理です。
インジケーター側では、bufferの割り当て、Plot設定、短い初期チェックなどを行います。EA側では、iMA、iRSI、iCustomなどのhandle生成に使うことが多くあります。
| 対象 | OnInitで行うこと | 注意点 |
|---|---|---|
| カスタムインジケーター | SetIndexBuffer、Plot設定、初期状態の確認 | buffer割り当てを忘れない |
| EA | インジケーターhandle生成 | INVALID_HANDLEを確認する |
| EA + iCustom | カスタムインジケーターhandle生成 | インジ名、パス、input順序を確認する |
| 検証用EA | ログ設定、初期チェック | 失敗時の理由をログに残す |
OnInitでは、「何を初期化したか」「失敗時にどの理由で止まったか」がログで分かるようにしておくと、後から確認しやすくなります。
OnInitの基本コード例
int ma_handle = INVALID_HANDLE;
int OnInit()
{
ResetLastError();
ma_handle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
int err = GetLastError();
Print("INIT_HANDLE",
" handle=", ma_handle,
" last_error=", err);
if(ma_handle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}EA側でインジケーターhandleを作る場合は、OnInitで作成し、OnTickで使い回す構成が基本です。OnTickで毎回handleを作り直すと、処理負荷や値取得の不安定化につながります。
OnCalculate:インジケーター計算の中心
OnCalculateは、カスタムインジケーター本体の計算処理を行うイベント関数です。
価格データ、出来高、時刻、既に計算済みのバー数などを使い、インジケーターバッファへ値を入れていきます。
| 引数・概念 | 意味 | 確認ポイント |
|---|---|---|
| rates_total | 利用可能なバー数 | 必要本数以上あるか |
| prev_calculated | 前回までに計算済みのバー数 | 全再計算か差分計算かを判断する |
| time / open / high / low / close | 時系列データ | 参照位置を取り違えない |
| buffer配列 | 描画または計算結果を格納する配列 | SetIndexBuffer済みか確認する |
| return値 | 次回計算時の基準 | 通常はrates_totalを返す |
OnCalculateでは、計算開始位置、初期バーの扱い、EMPTY_VALUE、未確定足の扱いを明確にする必要があります。
OnCalculateの簡易コード例
double LineBuffer[];
int OnInit()
{
SetIndexBuffer(0, LineBuffer, INDICATOR_DATA);
return INIT_SUCCEEDED;
}
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[])
{
int start = prev_calculated;
if(start == 0)
start = 1;
for(int i = start; i != rates_total; i++)
{
LineBuffer[i] = close[i];
}
return rates_total;
}この例は、終値をbufferへ入れるだけの簡易例です。実際のインジケーターでは、必要期間、初期バー、EMPTY_VALUE、未確定足、計算用bufferなどを考慮します。
SetIndexBuffer:配列をインジケーターバッファへ割り当てる
SetIndexBufferは、MQL5の配列をインジケーターバッファとして登録するために使います。
EAからCopyBufferで値を読む場合、どのbuffer番号にどの配列を割り当てたかが非常に重要です。
| 種類 | 用途 | EA連携での注意点 |
|---|---|---|
| INDICATOR_DATA | 描画や外部取得に使うbuffer | EAからCopyBufferで読む対象になりやすい |
| INDICATOR_CALCULATIONS | 内部計算用buffer | 通常はEAから直接読む対象ではない |
| buffer 0 | 1つ目のbuffer | CopyBufferの第2引数で0を指定する |
| buffer 1 | 2つ目のbuffer | BUY / SELLなど複数bufferで使うことが多い |
buffer番号は、見た目の順番だけで判断しない方が安全です。ソースコードがある場合は、SetIndexBufferの順番を確認してください。
SetIndexBufferのコード例
double BuyBuffer[];
double SellBuffer[];
double WorkBuffer[];
int OnInit()
{
SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA);
SetIndexBuffer(1, SellBuffer, INDICATOR_DATA);
SetIndexBuffer(2, WorkBuffer, INDICATOR_CALCULATIONS);
return INIT_SUCCEEDED;
}この例では、BuyBufferがbuffer 0、SellBufferがbuffer 1です。EA側でBUYサインを読みたい場合はCopyBufferでbuffer 0、SELLサインを読みたい場合はbuffer 1を指定します。
PlotIndexSetInteger:描画タイプや矢印を設定する
PlotIndexSetIntegerは、インジケーターのPlotに対して、描画タイプ、線幅、矢印コード、色などの設定を行うために使います。
| 用途 | 例 | 注意点 |
|---|---|---|
| 描画タイプ | DRAW_LINE、DRAW_ARROWなど | bufferの値がどのように表示されるかを決める |
| 矢印コード | PLOT_ARROW | サインインジケーターで使うことが多い |
| 線幅 | PLOT_LINE_WIDTH | 視認性に影響する |
| 表示開始位置 | PLOT_DRAW_BEGIN | 計算期間不足の初期バーを隠す時に使う |
Plot設定は表示に関係しますが、EAがCopyBufferで取得する値はbufferの中身です。表示されているかどうかと、bufferに値が入っているかは分けて確認してください。
Plot設定のコード例
int OnInit()
{
SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA);
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ARROW);
PlotIndexSetInteger(0, PLOT_ARROW, 233);
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 1);
return INIT_SUCCEEDED;
}矢印サイン系インジケーターでは、サインがないバーにEMPTY_VALUEを入れる設計がよくあります。EA側では、CopyBuffer成功とサイン成立を分けて判断します。
iCustom:カスタムインジケーターをEAから呼ぶ
iCustomは、カスタムインジケーターをEAや別のプログラムから呼び出すために使います。
iCustomでhandleを作成し、そのhandleを使ってCopyBufferで値を取得します。インジケーター名、配置パス、input引数、input型、timeframeが一致していないと、handle生成に失敗することがあります。
| 確認項目 | 内容 | よくあるミス |
|---|---|---|
| インジ名 | ファイル名 | スペース、全角半角、拡張子指定の混乱 |
| 配置パス | Indicators配下の場所 | サブフォルダ指定漏れ |
| input順序 | インジ側inputの並び | 途中のinputを省略してズレる |
| input型 | int、double、bool、enumなど | 型違いで想定外の値になる |
| buffer番号 | CopyBufferで読む番号 | 表示ラインとbuffer番号を混同する |
iCustomのhandleがINVALID_HANDLEになる場合は、CopyBufferではなく、iCustomの指定を先に確認します。
iCustomのコード例
int custom_handle = INVALID_HANDLE;
int OnInit()
{
ResetLastError();
custom_handle = iCustom(_Symbol,
PERIOD_CURRENT,
"MyCustomIndicator",
20,
2.0,
true);
int err = GetLastError();
Print("ICUSTOM_HANDLE",
" handle=", custom_handle,
" last_error=", err);
if(custom_handle == INVALID_HANDLE)
return INIT_FAILED;
return INIT_SUCCEEDED;
}この例では、カスタムインジケーターに3つのinput値を渡しています。実際には、対象インジケーター側のinput定義と完全に一致させる必要があります。
CopyBuffer:handleからbuffer値を取得する
CopyBufferは、インジケーターハンドルから指定bufferの値を取得するために使います。
EAから標準インジケーターやカスタムインジケーターの値を利用する場合、CopyBufferの戻り値、buffer番号、shift、取得本数を確認することが重要です。
| 引数 | 意味 | 確認ポイント |
|---|---|---|
| handle | 対象インジケーターhandle | INVALID_HANDLEではないか |
| buffer番号 | 取得するbuffer | SetIndexBufferの番号と一致しているか |
| shift | 取得開始位置 | 現在足か確定足か |
| count | 取得本数 | 必要本数を満たしているか |
| 配列 | 値の格納先 | ArraySetAsSeriesの向きに注意する |
CopyBufferで値が取れない時は、CopyBufferだけでなく、handle生成、BarsCalculated、buffer番号、shift、EMPTY_VALUEを順番に確認してください。
CopyBufferのコード例
void ReadIndicatorValue()
{
double values[];
ArraySetAsSeries(values, true);
ResetLastError();
int copied = CopyBuffer(ma_handle, 0, 0, 3, values);
int err = GetLastError();
Print("COPYBUFFER_TRACE",
" copied=", copied,
" last_error=", err);
if(copied != 3)
return;
Print("VALUE_CURRENT=", DoubleToString(values[0], _Digits));
Print("VALUE_CLOSED=", DoubleToString(values[1], _Digits));
}この例では、現在足の値をvalues[0]、1本前の確定足をvalues[1]として確認しています。EAのENTRY判定でどちらを使うかは、仕様として明確にしてください。
BarsCalculated:計算済みバー数を確認する
BarsCalculatedは、インジケーターがどこまで計算済みかを確認するために使います。
handleが作れていても、インジケーターの計算がまだ完了していない場合、CopyBufferで期待する本数を取得できないことがあります。
| 場面 | 起きやすい問題 | 対応 |
|---|---|---|
| EA起動直後 | 計算済みバー数が不足する | 必要本数まで待つ |
| バックテスト開始直後 | 初期バーで値が取れない | ウォームアップとして扱う |
| 複数時間足 | 上位足のバー数が不足する | 時間足ごとに確認する |
| iCustom | カスタムインジの計算が遅れる | BarsCalculatedとCopyBufferを分けて見る |
BarsCalculated不足は、必ずしも異常ではありません。準備未完了として扱い、ENTRY判定へ進まない設計にすると安全です。
BarsCalculatedのコード例
bool IsIndicatorReady(const int handle,
const int required_bars)
{
if(handle == INVALID_HANDLE)
{
Print("READY_CHECK status=NG reason=INVALID_HANDLE");
return false;
}
int calculated = BarsCalculated(handle);
Print("READY_CHECK",
" calculated=", calculated,
" required=", required_bars);
if(calculated != required_bars)
return false;
return true;
}この例は説明用に単純化しています。実務では、必要本数以上なら許可する設計にすることが多くあります。判定条件はEAやインジケーターの仕様に合わせて調整してください。
IndicatorRelease:不要になったhandleを解放する
IndicatorReleaseは、不要になったインジケーターハンドルを解放するために使います。
EA終了時、インジケーター再生成時、設定変更により古いhandleが不要になった時などに使います。
| 場面 | 使い方 | 注意点 |
|---|---|---|
| EA終了時 | OnDeinitで解放する | INVALID_HANDLEでない時だけ実行する |
| handle再生成時 | 古いhandleを先に解放する | 新旧handleを混同しない |
| OnTick中 | 通常は毎tick解放しない | 値取得のたびに解放する設計は避ける |
| 複数handle | 個別に解放する | どのhandleを解放したかログに残す |
IndicatorRelease後は、handle変数をINVALID_HANDLEへ戻しておくと、古いhandleを誤って使い続けるリスクを下げられます。
IndicatorReleaseのコード例
void OnDeinit(const int reason)
{
if(ma_handle != INVALID_HANDLE)
{
IndicatorRelease(ma_handle);
ma_handle = INVALID_HANDLE;
}
}このように、handleが有効な場合だけ解放します。解放後にINVALID_HANDLEへ戻すことで、以後の誤使用を防ぎやすくなります。
EMPTY_VALUE:値なし・サインなしを表す値
EMPTY_VALUEは、インジケーターで「このバーには値を表示しない」「このバーにはサインがない」といった状態を表すために使われます。
特に、矢印サイン系インジケーターや条件成立時だけ値を出すインジケーターでは、サインがないバーにEMPTY_VALUEが入ることがあります。
| 状態 | 意味 | EA側の扱い |
|---|---|---|
| CopyBuffer失敗 | 値を取得できていない | handle、BarsCalculated、GetLastErrorを確認 |
| CopyBuffer成功 + EMPTY_VALUE | そのバーにサインがない | WAITまたはNO_SIGNALとして扱う |
| CopyBuffer成功 + 有効値 | 判定に使える値がある | signal評価へ進む |
| 0.0 | 有効値か未初期化かは設計次第 | インジ側仕様を確認する |
EMPTY_VALUEをエラーと決めつけると、正常なサインなし状態を異常として扱ってしまいます。値取得の成否と、シグナル成立を分けて確認してください。
Buffer・Plot・Handleを混同しない
MQL5のインジケーター関数で混乱しやすいのが、Buffer、Plot、Handleの違いです。
Bufferはインジケーター内部で値を保持する配列、Plotはその値をチャート上にどう表示するかを決める描画単位、HandleはEAや別プログラム側からインジケーターを参照するための識別子です。
この3つを混同すると、チャートには表示されているのにEAで値が取れない、CopyBufferで別の値を読んでしまう、表示ラインとbuffer番号が一致していると思い込む、といった問題が起きます。
| 用語 | 意味 | よくある誤解 |
|---|---|---|
| Buffer | インジケーター値を格納する配列 | 表示されている線と必ず1対1とは限らない |
| Plot | Bufferをどのように表示するかを決める描画設定 | Plot番号とbuffer番号を同じものとして扱ってしまう |
| Handle | EA側からインジケーターを参照する識別子 | handleが作れれば値も必ず取れると思ってしまう |
| CopyBuffer | Handleとbuffer番号を指定して値を取得する処理 | 表示ラインではなくbuffer番号を読む必要がある |
EA化では、まずインジケーター側でどのbufferにどの値を入れているかを確認し、その後にEA側でCopyBufferのbuffer番号を合わせます。表示名やチャート上の見た目だけで判断すると、誤ったbufferを読んでしまうことがあります。
ソースコードがある場合は、SetIndexBufferの順序を確認します。ソースコードがない場合は、Data Window、開発元の仕様説明、実際のCopyBufferログを使って、どのbufferにどの値が入っているかを確認します。
インジケーター関数をEA化で使う時の確認順序
インジケーター関数をEA化で使う場合、いきなりCopyBufferのコードだけを見るのではなく、確認順序を固定すると原因を切り分けやすくなります。
| 順番 | 確認項目 | 見る内容 |
|---|---|---|
| 1 | インジケーター側のbuffer設計 | SetIndexBufferの番号、描画用buffer、計算用bufferを確認する |
| 2 | Plot設定 | 表示ライン、矢印、描画開始位置、EMPTY_VALUEの扱いを確認する |
| 3 | iCustomまたは標準関数のhandle | INVALID_HANDLEになっていないか確認する |
| 4 | BarsCalculated | 必要本数以上の計算が完了しているか確認する |
| 5 | CopyBuffer | buffer番号、shift、取得本数、戻り値を確認する |
| 6 | 取得値の妥当性 | EMPTY_VALUE、NaN、0.0、有効値を分ける |
| 7 | EA側のsignal変換 | 値取得とエントリー判定を混同していないか確認する |
この順序を使うと、どこで問題が起きているかを段階的に分けられます。
たとえば、iCustomのhandleがINVALID_HANDLEなら、CopyBufferやbuffer番号以前の問題です。BarsCalculatedが不足しているなら、インジケーターの計算準備がまだ終わっていない可能性があります。CopyBufferは成功しているのにEMPTY_VALUEなら、サインなし状態として扱うべきかもしれません。
このように、関数を単体で見るのではなく、インジケーター側の出力、EA側の取得、EA内部のsignal判定を分けることが重要です。
OnCalculateで確認したい実務ポイント
OnCalculateは、カスタムインジケーターの中心となる計算処理です。ただし、OnCalculate内で値を入れているからといって、EA側でその値をそのまま安全に使えるとは限りません。
EA連携を前提にする場合は、OnCalculate内でどのバーに値を入れているか、未確定足の値が変動するか、初期バーにEMPTY_VALUEを入れているか、計算用bufferと描画用bufferを分けているかを確認する必要があります。
| 確認項目 | 内容 | EA連携での影響 |
|---|---|---|
| 計算開始位置 | prev_calculatedをどう使っているか | 過去バー再計算や初期バーの値に影響する |
| 未確定足 | 最新バーの値が変わるか | shift 0を使うEAで判定が変動しやすい |
| 確定足 | 1本前の値が固定されるか | バー確定型EAで使いやすい |
| EMPTY_VALUE | 値なしバーに何を入れているか | サインなしと取得失敗を分ける必要がある |
| 計算用buffer | 内部計算だけに使うbufferがあるか | EAから読む対象にすべきでない場合がある |
サイン系インジケーターでは、条件成立時だけbufferに価格値を入れ、それ以外のバーにはEMPTY_VALUEを入れる設計がよくあります。この場合、EA側で毎バー値が取れることを前提にすると、サインなし状態を不具合と誤認します。
また、未確定足でサインが出たり消えたりするインジケーターでは、チャート上で見えたサインと、EAが確定足で取得する値が一致しないことがあります。EA化する前に、現在足基準で使うのか、確定足基準で使うのかを決める必要があります。
SetIndexBufferでよくある設計ミス
SetIndexBufferは、インジケーター値を格納する配列をbufferへ割り当てる重要な関数です。EA連携で問題が起きる場合、このbuffer設計に原因があることがあります。
| 設計ミス | 起きる問題 | 確認方法 |
|---|---|---|
| 描画用bufferと計算用bufferを混同する | EAが内部計算用の値を読んでしまう | INDICATOR_DATAとINDICATOR_CALCULATIONSを確認する |
| buffer番号を後から変更する | EA側CopyBufferの番号とズレる | SetIndexBufferの順序を再確認する |
| BUY / SELL bufferの意味が曖昧 | EA側で売買方向を取り違える | buffer 0とbuffer 1の役割を明記する |
| EMPTY_VALUEを入れていない | 古い値が残っているように見える | 条件不成立バーの値を確認する |
| Data Window表示名が分かりにくい | 検証時にbufferの意味を確認しにくい | PlotIndexSetStringなどで表示名を整理する |
EAから読むことを前提にするインジケーターでは、buffer番号と意味を開発メモや記事内で明示しておくと安全です。
たとえば、buffer 0はBUYサイン、buffer 1はSELLサイン、buffer 2は内部計算用というように、EA側で読むべきbufferと読まないbufferを分けます。これを曖昧にしたままEA化すると、チャート上の表示とEA判定が合わない原因になります。
Plot設定は表示用、CopyBufferは値取得用
PlotIndexSetIntegerやPlotIndexSetStringは、チャート上でどのように表示するかを決めるための関数です。一方、CopyBufferはbuffer内の値を取得するための関数です。
この違いを混同すると、「矢印が表示されているからEAでも取得できるはず」「表示名がBUYだからbuffer 0のはず」といった推測につながります。
| 項目 | 表示への影響 | EA取得への影響 |
|---|---|---|
| DRAW_LINE | 線として表示される | buffer値そのものはCopyBufferで取得可能 |
| DRAW_ARROW | 矢印として表示される | サインがないバーはEMPTY_VALUEの可能性がある |
| PLOT_DRAW_BEGIN | 初期バーの表示開始位置を調整する | 表示されない初期バーでもbuffer値確認が必要 |
| PLOT_LABEL | Data Windowなどの表示名を整理する | buffer番号そのものを変えるわけではない |
Plot設定は読者や利用者に見える部分の整理に役立ちますが、EA化ではSetIndexBufferとCopyBufferの対応を確認することが本質です。
そのため、インジケーターをEA化する時は、表示設定、buffer番号、CopyBufferで取得する値、EMPTY_VALUEの扱いを分けて確認します。
辞典記事としての使い方
このページは、個別関数の詳細リファレンスというより、MQL5でインジケーター開発やEA連携を行う時に、どの関数をどの責務で見るかを確認するための辞典記事です。
CopyBufferで値が取れない場合はCopyBufferだけを見るのではなく、iCustom、BarsCalculated、SetIndexBuffer、EMPTY_VALUE、shift、buffer番号を合わせて確認します。iCustomでhandleが作れない場合は、CopyBufferではなく、インジケーター名、配置パス、input引数、input型を確認します。
| 知りたいこと | 最初に見る関数 | 次に確認すること |
|---|---|---|
| EAでインジ値を読みたい | iCustom / CopyBuffer | handle、buffer番号、shiftを確認する |
| インジ側のbufferを確認したい | SetIndexBuffer | INDICATOR_DATAか計算用bufferかを確認する |
| チャート表示を調整したい | PlotIndexSetInteger | 描画タイプ、矢印、線幅、表示開始位置を見る |
| 計算処理を確認したい | OnCalculate | rates_total、prev_calculated、EMPTY_VALUEを見る |
| 起動直後に値が取れない | BarsCalculated | 計算済みバー数と必要本数を確認する |
| 終了時の不安定を確認したい | IndicatorRelease | handle解放とINVALID_HANDLE戻しを確認する |
関数を単独で覚えるより、開発中の問題に対して「どの責務の関数を見るべきか」を決める方が実務では重要です。
EAファンクラブでは、インジケーター開発、EA化、CopyBuffer取得、iCustom連携、ログ確認、バックテスト確認を分けて整理することで、静かに壊れる実装や原因不明の値取得失敗を減らす方針で扱います。
標準インジケーター関数との関係
MQL5では、標準インジケーターにも専用関数があります。代表例は、iMA、iRSI、iATR、iBandsなどです。
| 関数 | 対象 | EA連携で見ること |
|---|---|---|
| iMA | 移動平均 | handle作成後にCopyBufferでbuffer 0を読む |
| iRSI | RSI | 期間、適用価格、shiftを確認する |
| iATR | ATR | ボラティリティ確認やSL幅検討に使うことがある |
| iBands | ボリンジャーバンド | 上限、中央、下限のbuffer番号を確認する |
| iCustom | カスタムインジケーター | input引数とbuffer番号の確認が重要 |
標準インジケーターでも、handleを作ってCopyBufferで値を読む流れは同じです。カスタムインジケーターの場合は、さらにiCustomの引数やbuffer仕様の確認が必要になります。
インジケーター開発側とEA連携側の違い
インジケーターを作る側と、EAから読む側では、確認すべきポイントが異なります。
| 立場 | 主に見る関数 | 確認すること |
|---|---|---|
| インジケーター開発者 | OnCalculate / SetIndexBuffer / PlotIndexSetInteger | bufferへ正しい値を入れているか |
| EA開発者 | iCustom / CopyBuffer / BarsCalculated | 正しいbufferを正しいshiftで読んでいるか |
| 検証担当者 | GetLastError / Print / ログ出力 | 値取得失敗の理由を追えるか |
| 運用者 | 設定値 / 確定足 / ログ | 実運用前に検証環境で確認できるか |
インジケーターは表示できていても、EAが読むbuffer番号が違えば、EA側では期待する値を取得できません。EA化する時は、インジ側のbuffer設計とEA側のCopyBuffer指定をセットで確認します。
よくあるトラブルと関数の対応
| 症状 | 確認する関数・項目 | 見るポイント |
|---|---|---|
| iCustomがINVALID_HANDLEになる | iCustom / GetLastError | インジ名、パス、input順序、input型を確認する |
| CopyBufferで値が取れない | CopyBuffer / BarsCalculated | handle、buffer番号、shift、取得本数を確認する |
| サインが出ない | EMPTY_VALUE / SetIndexBuffer | サインなしなのか値取得失敗なのか分ける |
| チャート表示とEA判定が違う | shift / buffer番号 / iCustom | 現在足と確定足、表示ラインとbuffer番号を照合する |
| バックテスト開始直後に失敗する | BarsCalculated / iBars | 計算済みバー数と履歴データを確認する |
| 終了後に不安定になる | IndicatorRelease / OnDeinit | handle解放と再初期化を確認する |
不具合確認では、関数名だけを見て判断せず、handle生成、計算準備、buffer設計、値取得、signal判定を段階的に分けることが重要です。
ログに残すべき項目
インジケーター関数をEA連携で使う場合、ログが不足していると原因を追えません。
| ログ名 | 出す内容 | 目的 |
|---|---|---|
INIT_HANDLE | handle、last_error | handle生成の成否を確認する |
ICUSTOM_HANDLE | インジ名、input、handle、last_error | iCustomの指定ミスを確認する |
READY_CHECK | BarsCalculated、required | 計算準備状態を確認する |
COPYBUFFER_TRACE | buffer、shift、copied、last_error | CopyBufferの取得結果を確認する |
VALUE_VALIDATE | EMPTY_VALUE、有効値、NaN | 取得値の妥当性を確認する |
SIGNAL_EVAL | signal結果、basis、shift | EA内部判定を確認する |
ログ名を固定しておくと、Expertsログで検索しやすくなります。特に、iCustom、CopyBuffer、BarsCalculated、GetLastErrorは同じ流れで確認できるようにしておくと便利です。
実務チェックリスト
- インジケーター側でSetIndexBufferの順序を確認した
- 描画用bufferと計算用bufferを分けて確認した
- OnCalculateで必要なバー数を確認している
- EMPTY_VALUEをサインなしとして扱うか決めた
- EA側でiCustomのインジ名、パス、input順序を確認した
- iCustomのhandleがINVALID_HANDLEではないことを確認した
- BarsCalculatedで計算済みバー数を確認した
- CopyBufferのbuffer番号、shift、取得本数を確認した
- CopyBufferの戻り値copiedを確認した
- GetLastErrorを必要な箇所でログに出した
- 現在足と確定足を分けて確認した
- IndicatorReleaseで不要handleを解放している
- 値取得、妥当性確認、signal判定、entry gateを分けている
開発・改修依頼前に整理したい情報
MQL5のインジケーター関数やEA連携について相談する場合は、事前に以下を整理しておくと確認が進めやすくなります。
| 整理項目 | 記入例 | 確認理由 |
|---|---|---|
| 対象 | インジケーター / EA / 両方 | どちら側の関数を確認するか分けるため |
| 対象関数 | CopyBuffer、iCustom、SetIndexBufferなど | 確認範囲を絞るため |
| 対象ファイル | mq5あり / ex5のみ | bufferやinputを確認できるか判断するため |
| 取得したい値 | MAライン、BUYサイン、SELLサインなど | buffer番号を特定するため |
| 参照shift | 0、1、確定足基準など | 現在足と確定足を分けるため |
| Expertsログ | ICUSTOM_HANDLE、COPYBUFFER_TRACE | 失敗箇所を追うため |
| バックテスト条件 | 期間、銘柄、時間足、モデル | 履歴不足や初期バー問題を確認するため |
| EA化したい動作 | 通知、判定、発注前確認など | signalとexecutionを分けるため |
口座番号、認証情報、Webhook URL、APIキー、個人情報は共有しないでください。ログを共有する場合は、必要な箇所だけを伏せ字にして整理してください。
よくある質問
SetIndexBufferとCopyBufferは何が違いますか?
SetIndexBufferは、インジケーター側で配列をbufferへ割り当てるために使います。CopyBufferは、EA側などからそのbuffer値を取得するために使います。作る側の関数と読む側の関数として分けて考えると理解しやすくなります。
iCustomでhandleがINVALID_HANDLEになる原因は何ですか?
インジケーター名、配置パス、input引数の順序、input型、対象symbol、timeframeが合っていない可能性があります。まずiCustom直後にGetLastErrorとhandleをログへ出してください。
CopyBufferで値が取れない時は何を見ますか?
handle、BarsCalculated、buffer番号、shift、取得本数、CopyBufferの戻り値、GetLastErrorを順番に確認します。値取得失敗とEMPTY_VALUEによるサインなしは分けて扱ってください。
OnCalculateはEAにもありますか?
OnCalculateは主にカスタムインジケーターの計算処理で使います。EAでは通常OnTick、OnInit、OnDeinitなどを使い、インジケーター値を取得する場合はiCustomやCopyBufferを使います。
EMPTY_VALUEはエラーですか?
必ずしもエラーではありません。サイン系インジケーターでは、そのバーにサインがないことをEMPTY_VALUEで表す場合があります。CopyBufferが失敗したのか、値は取れているがサインがないのかを分けて確認してください。
IndicatorReleaseはいつ使いますか?
不要になったインジケーターhandleを解放する時に使います。EA終了時のOnDeinit、handle再生成時、設定変更で古いhandleが不要になった時などに使います。
関連ページ
| 関連テーマ | 確認ページ | 確認できること |
|---|---|---|
| CopyBuffer不具合 | MQL5 CopyBufferで値が取れない原因と確認ポイント | CopyBufferで値が取れない時の原因別確認 |
| iCustom連携 | MQL5 iCustomでインジケーターをEA化する時の注意点 | iCustom、input引数、buffer番号、リペイント確認 |
| handle管理 | MQL5 CopyBufferとインジケーターハンドル管理を実コードで解説 | OnInit、BarsCalculated、IndicatorReleaseの整理 |
| EAへの値取り込み | MQL5でインジケーター値をEAに取り込む方法 | 標準インジケーターやカスタムインジケーター値をEAへ渡す基本 |
| インジ開発とEA連携 | MQL5インジケーター開発・EA連携完全ガイド | OnCalculate、SetIndexBuffer、CopyBuffer、EA連携の全体像 |
| OnInit確認 | MQL5 OnInitの役割と初期化失敗の確認 | handle生成、初期化失敗、INIT_FAILEDの確認 |
| ログ設計 | MQL5デバッグ・ログファースト開発完全ガイド | 関数失敗や判定不成立をログで追う考え方 |
| EAサンプルコード | MQL5 EAサンプルコードの読み方 | OnInit、OnTick、CopyBufferを含むEA構造の読み方 |
| 開発・改修相談 | MT4/MT5の開発・改修相談はこちら | MQL5インジケーター関数やEA連携を相談する前の整理 |
まとめ
MQL5のインジケーター関連関数は、インジケーターを作る側と、EAから値を読む側で役割が分かれます。
インジケーター側では、OnCalculateで値を計算し、SetIndexBufferでbufferを割り当て、PlotIndexSetIntegerなどで表示を設定します。
EA側では、iCustomや標準インジケーター関数でhandleを作成し、BarsCalculatedで準備状況を確認し、CopyBufferで値を取得し、不要になったhandleはIndicatorReleaseで解放します。
CopyBufferで値が取れない、iCustomがINVALID_HANDLEになる、チャート表示とEA判定が合わないといった問題は、関数単体ではなく、handle、buffer番号、shift、EMPTY_VALUE、ログ確認をセットで見ることが重要です。
EA化では、値取得、値の妥当性確認、signal判定、entry gate、executionを分けて設計してください。ログで各段階を追えるようにしておくと、バックテスト、実運用、問い合わせ対応で原因を確認しやすくなります。
