見出し画像

チュートリアルやってみる(2)

昨日書いたコードを解読しながらわからないところを確認する。

配列の定義

datetime New_Time[1];

datetime 型の配列を作るのはわかったけど、[1] の部分がわからなかったのでドキュメントを見る。

double Variable[3];
次のエレメントを持ちます。:Variable[0]、Variable[1]、Variable[2]。

単純に要素数1のdatetime型の配列を宣言していた。

要素数1の配列ってなんのために作るのかわからなかったから納得できなかった。CopyTime()の引数に渡すときに配列でないと行けないから配列を使用していた。

静的変数

static datetime Old_Time;

静的変数はわかるけど、初期化されていないので意味がわからないのでドキュメントを読む。

初期値が指定されていない場合は、静的ストレージクラスの変数の初期値はゼロとなります。

なるほど、初期値は0になるみたい。datetime型についてのドキュメントには以下の通りに書かれている。

日付時刻型は日付と時刻を 1970 年 1 月 1 日からの経過秒数として格納するために意図されています。

つまり最初のコードは、1970年1月1日0時0分0秒を意味してる。

CopyTime()

最後のバー(ローソク足)の時間をコピーしてる

// copying the last bar time to the element New_Time[0]
int copied=CopyTime(_Symbol,_Period,0,1,New_Time);

ローソク足の時間(bar time)ってそもそも何なのか?ってなったけど、そのチャートで最新のローソク足の時刻ということやと思う。

_Symbol と _Period については以下の通り

_Symbol は現在のチャートの銘柄名を含みます。
_Period 関数は現在のチャートの時間軸を含みます。

CopyTime() の定義は以下の通りやけど、ENUM_TIMEFRAMES がわからない。

int  CopyTime(
 string          symbol_name,    // 銘柄名
 ENUM_TIMEFRAMES  timeframe,      // 期間
 int              start_pos,      // 開始位置
 int              count,          // 複製するデータ数
 datetime        time_array[]     // 開始時刻を複製する受け取り側の配列
 );
 

ここでいう期間はおそらく、何分足のチャートを見ているのかを指定してるんやと思う。(ということにしとく)

上の通り、開始位置と複製するデータ数を指定する場合は start_pos が 0 の場合は最新のローソク足を指定する。

画像1

なので、最初の一行は「最新のローソク足を1本だけコピーする」の意味。(そうやってコメントに書いてるねんけど納得できへんかったんや。)

ココまでのコードについて

   if(Bars(_Symbol,_Period)<60) // if total bars is less than 60 bars
    {
     Alert("We have less than 60 bars, EA will now exit!!");
     return;
    }
// We will use the static Old_Time variable to serve the bar time.
// At each OnTick execution we will check the current bar time with the saved one.
// If the bar time isn't equal to the saved time, it indicates that we have a new tick.
  static datetime Old_Time;
  datetime New_Time[1];
  bool IsNewBar=false;
// copying the last bar time to the element New_Time[0]
  int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
  if(copied>0) // ok, the data has been copied successfully
    {
     if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
       {
        IsNewBar=true;   // if it isn't a first call, the new bar has appeared
        if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
        Old_Time=New_Time[0];            // saving bar time
       }
    }
  else
    {
     Alert("Error in copying historical times data, error =",GetLastError());
     ResetLastError();
     return;
    }
//--- EA should only check for new trade if we have a new bar
  if(IsNewBar==false)
    {
     return;
    }
//--- Do we have enough bars to work with
  int Mybars=Bars(_Symbol,_Period);
  if(Mybars<60) // if total bars is less than 60 bars
    {
     Alert("We have less than 60 bars, EA will now exit!!");
     return;
    }

ココまでのコードでしていることの大きくは処理を実行するかどうかの判定でその内部では以下の2つをしている。
・十分なローソク足が存在するかのチェック
・新しいローソク足が存在するのかのチェック
の2つだから、スッキリ書くとしたら...

// 変数定義
static datetime Old_Time;
datetime New_Time[1];

// 十分なローソク足が存在するかを確認
if(Bars(_Symbol,_Period)<60) {
 Alert("We have less than 60 bars, EA will now exit!!");
 return;
}

int copied=CopyTime(_Symbol,_Period,0,1,New_Time);

// ローソク足のコピーの成功を確認
if(copied==-1) {
 Alert("Error in copying historical times data, error =",GetLastError());
 ResetLastError();
 return;
}

// 新しいローソク足がない場合は終了
if(Old_Time==New_Time[0]) return;

if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);

Old_Time=New_Time[0];

こんな感じになると思う。static を OnTick 内で宣言するのはよくない気はするけど MQL5 のお作法だとこれで問題なのかもしれない。

まとめ

最初は慎重すぎると思うけど、このくらいの感じで関数やデータ型をリファレンスみながら確認しつつどういうことを気をつけて行かないといけないのか、引数の順序とかコードの書き方を通して、MQL5やC++の作法を学んでいけたら良いなと思う。

この記事が気に入ったらサポートをしてみませんか?