2016年1月12日火曜日

[MQL超入門] その010 本格的にインジケータを作ってみよう。その2 TICKの更新回数を描画する。

前回の続きです。

[MQL超入門] その009 本格的にインジケータを作ってみよう。その1 セパレート型インジケータ作成
http://mt4program.blogspot.com/2016/01/mql-009.html

前回、チャートとは別に表示するセパレート型インジケータの基本形ができました。
そこに実際の処理を埋め込みしていきたいと思います。

今回はすでに処理を組み入れたプログラムを見ながら解説します。ですので、先に結果から。このようなチャートが描画されます。なんとなく、価格が大きく動いているときに飛び出ている感じですよね。

・図010.01 価格の更新回数を描画する。


//+------------------------------------------------------------------+
//|                                                   TickVolume.mq4 |
//|                                         Copyright 2016, Daisuke. |
//|                                   http://mt4program.blogspot.jp/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict
#property indicator_separate_window

//インジケータで使用するバッファの数を指定する。
#property indicator_buffers 1

//描画する線の情報を指定する。
#property indicator_label1  "TickVolume"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrAqua
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

// 表示バッファ
double tickVolume[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,tickVolume);
//---
   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[])
  {
//---
   for( int i = rates_total - prev_calculated - 1; i >= 0; i-- )
   {
      tickVolume[i] = (double)tick_volume[i];
   }
//--- return value of prev_calculated for next call
   return(rates_total - 1);
  }
//+------------------------------------------------------------------+

赤字の部分が、今回追加した部分です。一つずつ説明したいと思います。
#property indicator_buffers 1
まず、この一文です。これは、インジケータ内で使用するバッファと呼ばれる物の数を指定しています。ここでは、インジケータ内で描画したい線の数を指定します。
(※正確ではありませんが、超入門ということで、まずは、線の数を指定するということで理解していただければと思います。)
#property indicator_label1  "TickVolume"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrAqua
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
ここは、インジケータ内で描画する線の形式を指定しています。

indicator_label1の1の部分は1番目の・・という意味を示しています。もし線が二つ以上ある場合は、ここが2,3...と番号を指定した分だけ増えた内容を定義します。それぞれの意味は次の通りです。
[indicator_label?]は、線の名前を指定します。自由な文字列を入力可能です。
[indicator_type?]は、線の種別を指定します。DRAW_LINEは直線という意味です。
[indicator_color?]は、線の色を指定ます。clrAquaは水色です。
[indicator_style?]は、線の見た目を指定します。STYLE_SOLIDは実線という意味です。
[indicator_width?]は、線の太さを指定します。整数値を指定可能です。

どのような値が指定可能かは、別の機会にということで、次に移ります。
double tickVolume[];
ここで、double型の配列を定義します。このように{}で囲われていない場所に書かれた変数をグローバル変数と呼びます。
インジケータでは、最低線の数分だけ、このdoubleで定義したグローバル変数を定義する必要があります。それぞれ違う名前を付ける必要があります。
ここでは、Tickの更新回数を表示する変数としてtickVolumeという名前のdouble配列を定義しました。
   SetIndexBuffer(0,tickVolume);
OnInit()と書かれた{}内に記載されている上記の文ですが、これは、「このdoubleの配列をチャートの描画に使いますよ」という宣言になります。先ほど定義した[tickVolume]を指定します。初めに0という数字も一緒に記載されていますが、「1番目に描画する線として指定します。」という意味になります。ここで0と指定したものが、[indicator_type1]と指定したものと一致します。
OnInit()は、インジケータが起動する最初に呼び出される処理を記載する場所です。

少々面倒な話になるのですが、MQLの元となっているC言語では配列の一番最初の要素は0と指定します。MQLもこのルールに従ってプログラム内では1番目の要素のことを0と指定します。
   for( int i = rates_total - prev_calculated - 1; i >= 0; i-- )
   {
      tickVolume[i] = (double)tick_volume[i];
   }
さて、次の部分は、実際の処理です。[OnCalculate]という{}の中に含まれています。[OnCalculate]はTickの更新があるたび呼び出される処理です。ここに具体的にチャートを描画する処理を記述していくことになります。

for文の内容を、もう少し詳しく、解説します。
まず[rates_total]という変数には、バーの本数が入っています。[prev_calculated]という変数には、すでに処理済みのバー本数が入っています。(※こちらも、この説明ではあまり正確ではありませんが、超入門ということでお許しを・・・・。)
つまり[rates_total - prev_calculated]は未処理のバー本数を示しています。
先ほど説明した通り、C言語の流儀に従って、配列の指定は0から始まりますので、-1として数字調整をしています。例えば、全部でバーの数が10本あるとすると、配列で指定する数字は0~9までとなります。そのため最大値-1を初期値としています。

あと、今回[i--]という文が出てきます。これは[i=i-1]と同じ意味です。省略形です。

もう一点、インジケータのデフォルトでは、配列の0番目の要素が、チャート右端のデータ(最新のデータ)になります。このforループでは、過去のデータから先に値を生成するために、大きい数字から小さい数字へループさせながら計算しています。

forの中ではグローバル変数として定義した[tickVolume]のi番目に[tick_volume]のi番目の値を入れています。[tick_volume]はMT4が自動的にバーごとの更新回数を入れてくれる変数としてとりあえず覚えておきましょう。
   return(rates_total - 1);
[return]を話そうと思うと、今まで避けていた関数という考え方を学習する必要が出てきます。ここではとりあえず、このように書くということだけで、次に進みましょう。

さて、実行してみましょう!図010.01のようなチャートが表示された成功です。

うーん。これだけだと、基準値が無いため活発なのかどうか判別がつきませんよね。そこで、基準値として平均値を表示するように変更したいと思います。
続きはまた明日!

次の回へ


ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログへ