前回までで、流れに沿ってインジケータを作成できました。
今後自作のインジケータを作成するためには、もう少し内容を理解する必要があります。
まず、インジケータの本体である、OnCalculateについて解説したいと思います。
ウィザードを使ってインジケータを作成すると、次のコードが作成されます。
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
//---
//--- return value of prev_calculated for next call
return(rates_total);
}
[OnInit]は、インジケータの初期化時にMT4から呼び出されます。
インジケータをチャートに挿入したときや、表示時間足を変更した場合に呼び出されます。
[OnCalculate]は、チャート上でTick値が更新されるたびにMT4から呼び出されます。
インジケータを本格的に作成しようとすると、このOnCalculateを詳しく知る必要があります。そこで、今日はOnCalculateを解説したいと思います。
少しわかりやすくするため、日本語のコメントを入れたいと思います。[OnCalculate]が呼び出される際、MT4から10個のデータが渡されます。この10個のデータを使っていろんなインジケータを計算するのが基本です。
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[]) //スプレット
それぞれを解説したいと思います。
・rates_total
これは、インジケータが持っている配列要素数です。チャートに新しいバーが出るたびに、一つ増えます。最初はチャートのバー本数と一致します。
例えば、バー本数を1000本に指定している場合、最初は1000という数字が入ってきますが、バーが一つ更新されると1001になります。
・prev_calculated
[rates_total]にたいして、すでに計算済みの要素数を指定します。
ただし、これは実際には、前回[OnCalculate]を呼び出した際の[return]値が入ってきます。まだ一度も呼び出していない場合は0です。
たとえば、ウィザード初期状態でのプログラムでは[return(rates_total)]と指定されています。この場合、バーの追加がなければrates_totalと同じ値、バーの追加があれば、[rates_total]は一つ増えています。逆に考えるとバーの追加があった場合、[prev_calculated]は[rates_total]に対して一つ少ない値になります。
そのため、[rates_total]と[prev_calculated]の差を見ると、計算していないバーの本数を求めることができる事になります。
私は、[prev_calculated]の最新のバーは常に更新をしてもらうために、
return (rates_total - 1);
という書き方をします。こうすると、Tickの更新があるたびに最新のバーは計算しなさいよという指定になります。
・time open high low close
この5つは実際のチャート上のバーの値が配列として入ってきます。
それぞれ、時間、始値、高値、安値、終値です。
配列として入ってきますが下記の特徴があります。
・要素0が最新の値となる。
・要素数はrates_totalのため、rates_total以上の要素は参照しないようにする事
余談ですがプログラマ的感覚だと、要素があとに行くほど新しい値のイメージがあります。
MT4では逆なので少し戸惑う部分がありますが、0が最新と考えた方がしっくりくる場合も多いです。
ここで改めて、前回作成したTick更新回数インジケータの[OnCalculate]内の[for]部分を見てましょう。
for( int i = rates_total - prev_calculated - 1; i >= 0; i-- )
[i]が[rates_total - prev_calculated - 1]から始まって、0になるまで繰り返しています。
これは古いデータから値を作成していくため、このような書き方をしています。移動平均などは過去データをもとに記述する場合があります。テクニカル値は過去データが計算されていないと現在値が求まらない場合が多いため、このようなループ文にしています。
・tick_volume
Tick更新回数インジケータでも使用しましたTickの更新回数のデータです。
・volume
約定枚数のデータですが、FXでは使用されていません。株とかのデータを受け取った場合には入ってくるようです。
・spread
スプレッドですが、MT4では使用されていません。
OnCalculateにてMT4からどのようなデータがわたってくるかを確認しました。ぜひこれらのデータを使用して自作インジケータを作ってみてくださいね。
次の回へ
ブログランキングにご協力よろしくお願いします。
m(._.)m