(‘both’, ‘MQL4 / MQL5 両対応’)イベントハンドラインジケーター専用
目次
OnCalculateインジケーターの値を計算する専用ハンドラ
新しい値が来て、インジケーターの再計算が必要になるたびに呼ばれる。インジケーターの計算処理は、EAのOnTickにあたる位置としてここに書く。
1書式
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[] );
書式はMQL4・MQL5で同じ。
2引数
| 引数 | 内容 |
|---|---|
| rates_total | いま読み込まれている足の総本数 |
| prev_calculated | 前回のOnCalculateで計算し終わった本数。差分だけ計算する省力化に使う |
| time / open / high / low / close / tick_volume / volume / spread | 四本値等の配列。添字0が最古(時系列の逆)で渡される点に注意(下記) |
3戻り値
次回prev_calculatedとして渡される値を返す。ふつうはrates_totalをそのまま返す。
4使用例
double MyBuffer[];
#property indicator_chart_window
#property indicator_buffers 1
int OnInit()
{
SetIndexBuffer(0, MyBuffer);
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 > 0) ? prev_calculated - 1 : 0;
for(int i = start; i < rates_total; i++)
MyBuffer[i] = (high[i] + low[i]) / 2;
return(rates_total);
}
MetaEditorでコンパイル0エラー・0警告を確認済み。
5MQL4→MQL5の違い
🔁 差分
MQL4は歴史的に古いバージョンではstart()という別の仕組みだったが、現在(ビルド600以降・現行のMetaEditor)はMQL5と同じOnCalculateに統一されている。書式上の大きな違いはほぼ無い。ただしOnCalculateが渡す配列は添字0が最古(時系列の逆順)で渡される点は、iOpen等の「添字0が最新」の並び(時系列順)とまったく逆なので、混同しやすい。
6よくある罠
⚠ 実務で踏んだもの
prev_calculatedを使わず毎回全部を計算し直すと、足数が増えるほど重くなる。差分だけ計算するのが定石(使用例のstartの作り方)。- 配列の並び順(添字0が最古か最新か)を勘違いすると、値がずれたインジケーターになる。
iOpen系の時系列順と混同しないよう注意。
7関連する関数
MORNING BRIEF平日 毎朝7時までに更新
今日はどこを見ればいいか。
ドル円とユーロドルの主要ライン・予想高値安値を、平日の朝に図1枚にまとめています。
朝刊を見る→9/25 8:27 時点ドル円158.78▼-7 pipsドル円 予想レンジ158.41 〜 159.23ドル円 上の節目158.90▲ドル円 下の節目157.80▼ユーロドル1.1378▼-2 pipsユーロドル 予想レンジ1.1351 〜 1.1408ユーロドル 上の節目1.1403▲ユーロドル 下の節目1.1359▼きょうの指標重要指標なし