iCustom他のインジケーターの値を呼び出す
別のインジケーターが計算した値を、EAや別のインジケーターから読む関数。MQL4とMQL5で「戻ってくるものの意味」が根本から変わるため、書き換えの実務ではこの関数がいちばん詰まりやすい。
1書式
double iCustom( string symbol, int timeframe, string name, // インジケーターのファイル名 ..., // インジケーター側のinput引数 int mode, // バッファ番号 int shift // 足の番号 );
int iCustom(
string symbol, ENUM_TIMEFRAMES period,
string name, ...
);
// 戻り値は値そのものではなく「ハンドル」。値は別途 CopyBuffer で取る
MQL4は値をその場で返す。MQL5はハンドル(番号の切符)を返すだけで、実際の値はCopyBufferで改めて取りに行く2段構えになる。
2引数
| 引数 | 内容 |
|---|---|
| symbol / timeframe | 調べたい銘柄と時間足。NULL・0(またはPERIOD_CURRENT)でいまのチャート |
| name | インジケーターのファイル名(拡張子なし)。サブフォルダに入っている場合は経路も含める |
| …(インジケーター側の引数) | 呼び出す側のinput変数の並びと合わせる。ずれると違う設定で計算されてしまう |
| mode MQL4のみ | 読みたいバッファの番号(0から) |
| shift MQL4のみ | 何本前の足の値か |
3戻り値
MQL4はバッファの値そのもの(double)。値が無ければEMPTY_VALUE。MQL5はインジケーターのハンドル(int)。失敗するとINVALID_HANDLE。値を読むには、このハンドルをCopyBufferに渡す。
4実際に動かした結果
MQL4は値が直接返る。MQL5はハンドル→CopyBufferの2段階
自作インジケーターをEA側から呼んだときの挙動。
| 状況 | 結果 |
|---|---|
| インジ側のOnCalculateが0を返すよう変えた | MQL5側でCopyBufferが値を取れなくなった |
| ハンドルを毎ティック作り直した | 処理が重くなった(ハンドルはOnInitで1回作れば足りる) |
5使用例:MQL5でADX(14)の値を読む
int h = iCustom(_Symbol, PERIOD_CURRENT, "ADX", 14);
double buf[];
ArraySetAsSeries(buf, true);
if(CopyBuffer(h, 0, 0, 3, buf) > 0)
Print("直近の値: ", buf[0]);
MetaEditor(MQL5)でコンパイル0エラー・0警告を確認済み。
6MQL4→MQL5の違い
「値を直接受け取る」から「ハンドルを取ってから値を取りに行く」への転換。MQL4のコードで毎回iCustom(...)を呼んでいた箇所は、MQL5ではハンドルをOnInitで1回だけ作り、以降はCopyBufferだけを呼ぶ形に書き直す。
この転換に気づかず、iCustomを毎ティック呼んでハンドルを作り直すコードは、動きはするが重くなる。
7よくある罠
- 呼ばれる側のインジケーターがOnCalculateで0を返すと、iCustom側は値を読めない(MQL5は戻り値を「計算済みの本数」として扱うため)。詳しくは差分ノートを参照。
- 呼び出す側の引数の並びが、呼ばれる側のinputの並びと1つでもずれると、気づかないまま違う設定で計算された値を受け取ることになる。エラーは出ない。
8関連する関数
今日はどこを見ればいいか。
ドル円とユーロドルの主要ライン・予想高値安値を、平日の朝に図1枚にまとめています。
朝刊を見る→