技術辞典

MQL5インジケーター関数辞典|iCustom・CopyBuffer・SetIndexBuffer・OnCalculate一覧

EAファンクラブ

MQL5でインジケーターを開発したり、EAからインジケーター値を取得したりする時は、複数の関数を役割ごとに使い分ける必要があります。

たとえば、カスタムインジケーター側ではOnCalculate、SetIndexBuffer、PlotIndexSetIntegerなどを使い、EA側ではiCustom、CopyBuffer、BarsCalculated、IndicatorReleaseなどを使います。

これらの関数を混同すると、「インジケーターは表示されるのにEAで値が取れない」「buffer番号が分からない」「CopyBufferが失敗する」「iCustomのhandleがINVALID_HANDLEになる」「バックテスト開始直後だけ値が取れない」といった問題が起きやすくなります。

このページでは、MQL5のインジケーター関連関数を、インジケーター開発側、EA連携側、buffer管理、描画設定、ログ確認、解放処理の観点から整理します。

なお、このページはMQL5開発における技術確認を目的とした内容です。売買判断、推奨エントリー、推奨ロット、利益保証、損失回避保証を行うものではありません。

MQL5インジケーター関数を役割で分ける

MQL5のインジケーター関連関数は、ひとまとめに覚えるより、役割で分けた方が理解しやすくなります。

分類主な関数役割
インジケーター本体OnInit / OnCalculate / OnDeinit初期化、計算、終了処理を担当する
buffer管理SetIndexBuffer配列をインジケーターバッファへ割り当てる
描画設定PlotIndexSetInteger / PlotIndexSetDouble / PlotIndexSetStringライン、矢印、色、表示名などを設定する
EAからの呼び出しiCustom / iMA / iRSI / iATRインジケーターハンドルを作成する
値取得CopyBufferhandleからbuffer値を取得する
計算状態確認BarsCalculatedインジケーターの計算済みバー数を確認する
解放処理IndicatorRelease不要になったhandleを解放する

インジケーターを作る側と、EAから読む側では使う関数が異なります。たとえば、SetIndexBufferはインジケーター本体側で使い、CopyBufferはEA側で値を読む時に使います。

関数一覧の早見表

まず、主要なインジケーター関連関数の役割を一覧で確認します。

関数使う場所主な用途
OnInitインジ / EA初期化、buffer設定、handle生成
OnCalculateインジインジケーター値の計算
OnDeinitインジ / EA終了処理、handle解放、Object整理
SetIndexBufferインジ描画用・計算用bufferの割り当て
PlotIndexSetIntegerインジ描画タイプ、矢印コード、線種などの設定
PlotIndexSetStringインジPlot名や表示ラベルの設定
iCustomEA / インジカスタムインジケーターhandleの作成
CopyBufferEA / インジインジケーターbuffer値の取得
BarsCalculatedEA / インジ計算済みバー数の確認
IndicatorReleaseEA / インジ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描画や外部取得に使うbufferEAからCopyBufferで読む対象になりやすい
INDICATOR_CALCULATIONS内部計算用buffer通常はEAから直接読む対象ではない
buffer 01つ目のbufferCopyBufferの第2引数で0を指定する
buffer 12つ目のbufferBUY / 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対象インジケーターhandleINVALID_HANDLEではないか
buffer番号取得するbufferSetIndexBufferの番号と一致しているか
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とは限らない
PlotBufferをどのように表示するかを決める描画設定Plot番号とbuffer番号を同じものとして扱ってしまう
HandleEA側からインジケーターを参照する識別子handleが作れれば値も必ず取れると思ってしまう
CopyBufferHandleとbuffer番号を指定して値を取得する処理表示ラインではなくbuffer番号を読む必要がある

EA化では、まずインジケーター側でどのbufferにどの値を入れているかを確認し、その後にEA側でCopyBufferのbuffer番号を合わせます。表示名やチャート上の見た目だけで判断すると、誤ったbufferを読んでしまうことがあります。

ソースコードがある場合は、SetIndexBufferの順序を確認します。ソースコードがない場合は、Data Window、開発元の仕様説明、実際のCopyBufferログを使って、どのbufferにどの値が入っているかを確認します。

インジケーター関数をEA化で使う時の確認順序

インジケーター関数をEA化で使う場合、いきなりCopyBufferのコードだけを見るのではなく、確認順序を固定すると原因を切り分けやすくなります。

順番確認項目見る内容
1インジケーター側のbuffer設計SetIndexBufferの番号、描画用buffer、計算用bufferを確認する
2Plot設定表示ライン、矢印、描画開始位置、EMPTY_VALUEの扱いを確認する
3iCustomまたは標準関数のhandleINVALID_HANDLEになっていないか確認する
4BarsCalculated必要本数以上の計算が完了しているか確認する
5CopyBufferbuffer番号、shift、取得本数、戻り値を確認する
6取得値の妥当性EMPTY_VALUE、NaN、0.0、有効値を分ける
7EA側の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_LABELData 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 / CopyBufferhandle、buffer番号、shiftを確認する
インジ側のbufferを確認したいSetIndexBufferINDICATOR_DATAか計算用bufferかを確認する
チャート表示を調整したいPlotIndexSetInteger描画タイプ、矢印、線幅、表示開始位置を見る
計算処理を確認したいOnCalculaterates_total、prev_calculated、EMPTY_VALUEを見る
起動直後に値が取れないBarsCalculated計算済みバー数と必要本数を確認する
終了時の不安定を確認したいIndicatorReleasehandle解放とINVALID_HANDLE戻しを確認する

関数を単独で覚えるより、開発中の問題に対して「どの責務の関数を見るべきか」を決める方が実務では重要です。

EAファンクラブでは、インジケーター開発、EA化、CopyBuffer取得、iCustom連携、ログ確認、バックテスト確認を分けて整理することで、静かに壊れる実装や原因不明の値取得失敗を減らす方針で扱います。

標準インジケーター関数との関係

MQL5では、標準インジケーターにも専用関数があります。代表例は、iMA、iRSI、iATR、iBandsなどです。

関数対象EA連携で見ること
iMA移動平均handle作成後にCopyBufferでbuffer 0を読む
iRSIRSI期間、適用価格、shiftを確認する
iATRATRボラティリティ確認やSL幅検討に使うことがある
iBandsボリンジャーバンド上限、中央、下限のbuffer番号を確認する
iCustomカスタムインジケーターinput引数とbuffer番号の確認が重要

標準インジケーターでも、handleを作ってCopyBufferで値を読む流れは同じです。カスタムインジケーターの場合は、さらにiCustomの引数やbuffer仕様の確認が必要になります。

インジケーター開発側とEA連携側の違い

インジケーターを作る側と、EAから読む側では、確認すべきポイントが異なります。

立場主に見る関数確認すること
インジケーター開発者OnCalculate / SetIndexBuffer / PlotIndexSetIntegerbufferへ正しい値を入れているか
EA開発者iCustom / CopyBuffer / BarsCalculated正しいbufferを正しいshiftで読んでいるか
検証担当者GetLastError / Print / ログ出力値取得失敗の理由を追えるか
運用者設定値 / 確定足 / ログ実運用前に検証環境で確認できるか

インジケーターは表示できていても、EAが読むbuffer番号が違えば、EA側では期待する値を取得できません。EA化する時は、インジ側のbuffer設計とEA側のCopyBuffer指定をセットで確認します。

よくあるトラブルと関数の対応

症状確認する関数・項目見るポイント
iCustomがINVALID_HANDLEになるiCustom / GetLastErrorインジ名、パス、input順序、input型を確認する
CopyBufferで値が取れないCopyBuffer / BarsCalculatedhandle、buffer番号、shift、取得本数を確認する
サインが出ないEMPTY_VALUE / SetIndexBufferサインなしなのか値取得失敗なのか分ける
チャート表示とEA判定が違うshift / buffer番号 / iCustom現在足と確定足、表示ラインとbuffer番号を照合する
バックテスト開始直後に失敗するBarsCalculated / iBars計算済みバー数と履歴データを確認する
終了後に不安定になるIndicatorRelease / OnDeinithandle解放と再初期化を確認する

不具合確認では、関数名だけを見て判断せず、handle生成、計算準備、buffer設計、値取得、signal判定を段階的に分けることが重要です。

ログに残すべき項目

インジケーター関数をEA連携で使う場合、ログが不足していると原因を追えません。

ログ名出す内容目的
INIT_HANDLEhandle、last_errorhandle生成の成否を確認する
ICUSTOM_HANDLEインジ名、input、handle、last_erroriCustomの指定ミスを確認する
READY_CHECKBarsCalculated、required計算準備状態を確認する
COPYBUFFER_TRACEbuffer、shift、copied、last_errorCopyBufferの取得結果を確認する
VALUE_VALIDATEEMPTY_VALUE、有効値、NaN取得値の妥当性を確認する
SIGNAL_EVALsignal結果、basis、shiftEA内部判定を確認する

ログ名を固定しておくと、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番号を特定するため
参照shift0、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を分けて設計してください。ログで各段階を追えるようにしておくと、バックテスト、実運用、問い合わせ対応で原因を確認しやすくなります。

ABOUT ME
記事URLをコピーしました