【移植#81】iCustomの入力を省略すると何が返る? — 6通りの呼出しと3バッファを照合¶

この記事の3行まとめ
- MT5の
iCustom()は値そのものではなくハンドルを返し、CopyBuffer()で各バッファを読みます - 省略・明示・異なる入力を、終値×係数という答えの分かる指標で比較します
- 値の一致だけでは内部の計算共有や高速化を証明できません。今回測るのは取得値と入力の対応です
今回の原典は「同じ指標を何回呼んでいるのか」¶
投稿日順で先にある4月11日は、旧MT4のオフラインチャートでバックテスト中の複数時間足を表示する内容です。時間足をそろえる話は移植#45、チャートの連動操作は移植#54、時間足の再集計は移植#76で扱っています。今回は独立した検証課題を追加せず、番号を使わずに進みました。
4月12日のDLLと内部ウィンドウメッセージによるscript起動も見送ります。別の常駐EAへイベントを送る方法と、任意のscriptを起動する方法は同じではないからです。
採用したのは、4月13日の記事です。
原典は、指標の呼出し時にオブジェクトまで作られるのか、入力を省略できるのか、バッファごとに呼ぶと全計算が繰り返されるのか、という疑問を実験しています。さらに、当時のMT4で入力を省略した際の予想外の結果を報告し、引数を全部書く方針を示しています。
このMT4での観測を、そのままMT5の不具合として紹介することはできません。 MT5の公式説明と実測を分けて確かめます。
MT5はハンドル作成と値の読出しを分ける¶
iCustom()の公式説明では、戻り値はカスタム指標のハンドルです。入力は型と順序を合わせ、指定しなければ既定値を使います。
int handle = iCustom(_Symbol, PERIOD_H1,
"81_iCustom_Input_Probe_v1_00", 5, 10, 15);
if(handle == INVALID_HANDLE)
return;
double values[];
if(CopyBuffer(handle, 0, 1, 100, values) != 100)
return; // データ不足なら、後のイベントで再試行する
これは読出し部分の抜粋です。実際のEAではハンドルを初期化時に保持し、終了時に解放します。作成の直後に全データがそろうとは限らないため、取得件数を確認します。
バッファ番号0・1・2を読むために、iCustom()を3回呼ぶ必要はありません。同じハンドルに対し、CopyBuffer(handle, 0, ...)、CopyBuffer(handle, 1, ...)、CopyBuffer(handle, 2, ...)と番号を変えます。入力値は特定バッファだけへの引数ではなく、指標全体の入力です。
答えが分かる指標で入力を見分ける¶
配布指標には、a=5、b=10、c=15という3つの整数入力があります。
| バッファ | 表示色 | 計算 |
|---|---|---|
| 0 | 水色 | その足の終値 × a |
| 1 | 金色 | その足の終値 × b |
| 2 | 緑色 | その足の終値 × c |
複雑な指標にすると、入力の問題と計算式の問題が混ざります。この指標はあえて単純な式にして、EAが別途取得した終値から正解を計算できるようにしています。価格を係数倍した検証用の線であり、売買指標ではありません。
| ケース | 渡す入力 | 照合する係数 |
|---|---|---|
| 全省略 | なし | 5 / 10 / 15 |
| 先頭だけ | 5 | 5 / 10 / 15 |
| 先頭2つ | 5, 10 | 5 / 10 / 15 |
| 全明示 | 5, 10, 15 | 5 / 10 / 15 |
| 別の入力組 | 3, 9, 18 | 3 / 9 / 18 |
| 別の入力組の後で再作成 | 5, 10, 15 | 5 / 10 / 15 |
部分省略は今回の実験対象です。入力の途中を飛ばして後ろだけ指定する意味ではありません。実用コードでは全入力を明示すると、指標側の既定値変更による影響を把握しやすくなります。
実機で確認すること¶
検証EAは確定100本を使い、6ケース×3バッファを別のタイマーイベントで3回読みます。読出し前後に時刻と終値が変わっていないことを確認してから、独立計算と比較します。形成中の現在足は対象にしません。
正常値が一致するだけでなく、その値へ1.0を足した負の対照を同じ比較関数へ通し、不一致を拒否できることも確認します。データ不足による待機と、安定したデータの数値不一致を区別します。
専用MT5 Build 6182、EURUSD H1での結果です。対象は端末履歴にある2026年9月18日01:00〜9月24日04:00の確定100本です(端末のバー時刻)。3回とも同じ100本を再読しており、300本の独立サンプルという意味ではありません。
| 検査 | 結果 |
|---|---|
| 配布指標・検証EAのコンパイル | 各0エラー・0警告 |
| 入力の呼出しケース | 6 / 6 |
| バッファ | 各3本 |
| 照合 | 6 × 3 × 100 × 3 = 5,400件 |
| 独立計算との不一致 | 0件 |
| 正常値へ1.0を足した負の対照 | 5,400件を拒否 |
| 別入力と明示既定値の差 | 全3バッファ・100本で確認 |
| 読出し前後の時刻・終値 | 3回とも一致 |
| サブウィンドウへの指標装着 | 確認済み |
| 結果ラベル | 7 / 7 |
| 注文数・ポジション数 | 開始前後で変化なし |
全省略・部分省略・明示既定値は、それぞれ5 / 10 / 15の係数と一致しました。別の入力組は3 / 9 / 18と一致し、その後の既定値の再作成も影響を受けませんでした。この観測では、原典が報告したMT4の挙動は再現されていません。
掲載画像はこの検査後に取得した1200×630の実画面です。別の指標や入力型、将来の端末ビルドまで同じ結果を保証する検査ではありません。
値が同じでも、内部の共有までは分からない¶
同じ入力で値が一致することと、内部で同じ計算ブロックを共有していることは別です。ハンドル番号の一致・不一致も、この実験だけで内部構造を断定する根拠にはしません。
IndicatorRelease()の説明でも、ハンドルの解放と計算ブロックの削除は区別されています。また、ストラテジーテスターではこの関数は実行されません。今回の通常端末での検証を、テスターの寿命管理や性能測定へ広げて解釈しないでください。
原典にあるオブジェクトの副作用は、呼ばれる指標のコード次第です。今回の配布指標はオブジェクトを作らず、検証結果の文字表示は検証EAが担当します。iCustom()で作成しただけの指標をチャート表示と取り違えず、撮影時にはChartIndicatorAdd()で明示的に装着します。
ダウンロードと使い方¶
81_iCustom_Input_Probe_v1_00.mq5 をダウンロード
- MT5のデータフォルダー内の
MQL5/Indicatorsへ置き、MetaEditorでコンパイルします。 - チャートに追加すると、サブウィンドウに3本の係数倍の線が表示されます。
a・b・cを1〜100で変更し、各線との対応を確認します。- 自作EAから読む場合は、実際の配置先に合わせた指標名と全入力を指定します。
画像の合否パネルは検証EAの表示で、配布指標単体には出ません。配布指標は注文、通知、DLL、外部通信、ファイル書込みを行いません。
まとめ¶
MT5では、入力組を指定してハンドルを作り、そのハンドルから複数バッファを読みます。既定値を使う経路も、異なる入力を使う経路も、答えの分かる式と取得件数で確かめられます。内部の計算共有や速度を推測する前に、まずどの入力から、どの値が返ったかを検証するための小さな実験です。
あわせて読みたい記事¶
- 【移植#50】12通貨の指標値を1枚へ — 確定足を揃えるトレンド・コンセンサス
- 【検証#06-2】トレンド/レンジ・レジーム判定インジ P0 — バッファ契約と MQL5 実装
- 【検証#09】MQL5のiCustomで引数を省略すると危険 ー CopyBufferまでの正しい書き方
前後の記事¶
前: 【移植#80】通貨強弱は何本のペアで決まるか — xMeterの構成バイアスを可視化
次: 【移植#82】平滑平均足を方向バーにする — 赤と白に残す情報、捨てる情報