スポンサーリンク
ホーム » MQL5でEA作ろう講座 » 【超入門】MQL5 EA講座 第115回「チャート上に新しいバーが生成される瞬間にのみ注文できるクラスを作る」【EAの作り方】
a

【超入門】MQL5 EA講座 第115回「チャート上に新しいバーが生成される瞬間にのみ注文できるクラスを作る」【EAの作り方】

MQL5でEA作ろう講座
スポンサーリンク

【広告】

前回インジケータによるトレードシグナルに、ON/OFF機能を実装する方法について解説しました。

まずはそもそも「トレードシグナルに、ON/OFF機能を実装する」とはどういうことか?

についての簡単な解説を行いました。

※詳しくは前回の↓

インジケータによるトレードシグナルのON/OFFとは?-はじめに-」セクションをご覧ください。

その上で、具体的なON/OFF機能実装方法のロードマップを示しました。

※詳しくは前回の↓

インジケータOn/OFF機能実装の為のロードマップ」セクションをご覧ください。

その後、具体的なON/OFF機能実装方法のステップ1として、On/OFFを制御するinput変数の宣言について解説を行いました。

※詳しくは前回の↓

インジケータOn/OFFを制御するinput変数の宣言」セクションをご覧ください。

そして最後に、ON/OFF機能実装方法のステップ2として、インジケータOn/OFFを制御する為のエントリー条件を記述する方法を解説しました。

※詳しくは前回の↓

インジケータOn/OFFを制御する為のエントリー条件をメインプログラム内で記述する」セクションをご覧ください。

今回からしばらくは、MQL5で時間及び日付を扱う方法を学んでいきます。

その第一弾としてチャート上に新しいバーが生成される瞬間にのみ、EAが注文を実行できるような処理を簡単に行える、専用クラスを作っていきます。

クラスについての概要は以下のリンクから確認・復習をお願いします。

スポンサーリンク
  1. はじめに:時間及び日付データに関して
  2. 確定足についてのおさらい
  3. 新しいバーオープンでの取引についての前提
  4. 「新しいバーのオープンのみに注文を発注できるクラス」実装の為のロードマップ
  5. オリジナルのクラスを作るためのインクルードファイルを生成する
  6. 「新しいバーのオープンのみに注文を発注できる」クラスを宣言する
  7. アクセスレベル=privateのメンバを追加する
  8. アクセスレベル=publicのメンバを追加する
  9. メンバ関数の処理実装記述をしていく
    1. OriginalCNewBar関数について
    2. CheckNewBar関数について
      1. CheckNewBar関数の引数について
      2. CheckNewBar関数の処理実装記述について
        1. 処理実装記述1:フラグ判定を行う為のbool型変数を宣言する
          1. フラグとは?
        2. 処理実装記述2:CopyTime関数を使い、「TimeArray」にバーの時間情報をコピーする
        3. 処理実装記述3:EAが初回実行かどうかの判断をする記述を行う
        4. 処理実装記述4:配列「TimeArray」の値と変数「LastTimeVar」の値を比較する条件文を記述する
          1. if(TimeArray[0] > LastTimeVar)の条件記述について
          2. if(TimeArray[0] > LastTimeVar)の条件を満たしている場合の{}内記述について
        5. 処理実装記述5:newBarOpenに格納されている値を戻り値として返す
  10. メインプログラムで今回作ったクラス・関数をどのように使っていくかを確認する
    1. OriginalTimer.mqhファイルをインクルードする
    2. 新しいバーに基づいて処理を行うかの設定を行うinput変数を設定する
    3. OnTick関数内の記述を行う
      1. OnTick関数内の記述:ローカル変数を定義する
      2. BasedOnNewBarがtrueの場合に行う処理を記述する。
      3. newBarがtrueの場合の記述を行う
  11. まとめ

はじめに:時間及び日付データに関して

新しいクラスを作成する前に、まず日時データについてのおさらいをしておきましょう。

時間及び日付データに関しては主にdatetime型として扱われます。

datetime型については以前MQL5 EA講座 第16回「データ型その6 datetime型」にて基本的な解説を行っていますので参照ください↓

スポンサーリンク

確定足についてのおさらい

チャート上に新しいバーが生成される瞬間にのみ、EAが注文を実行できるような処理を簡単に行える、専用クラスを作る上では、以前講座記事第107回で解説した確定足という概念についても押さえておく必要があります↓

そしてもこれも、講座記事第107回の「確定足と相場原則の関係性について」セクションで言及している事ですが、

相場にはいくつかの原理原則(とされるもの)があります。

そのうちの1つに

確定足の終値には相場における一定の合意形成がある

という考え方があります。

例えば、

日足チャートにおける直近高値をリアルタイム値で一時的に上抜けても、その後価格が押し戻されて直近高値を下回る価格で終値を迎えた場合、「直近高値を上抜けた」という合意形成の度合いは薄い→上昇トレンドはまだ開始していない。

一方で、

日足チャートにおける直近高値をリアルタイム値で一時的に上抜けて、そのまま直近高値を上回る価格で終値を迎えた場合、「直近高値を上抜けた」という合意形成の度合いは濃い→上昇トレンドの開始である。

という相場観です。

上記のような、確定足を理由とした相場観に基づき、エントリーを新しいバーの開始にのみ焦点を当てることで、市場でのノイズを減らし、より明確なエントリーとエグジットポイントを定義する事が可能となります。

この後作っていくオリジナルクラスはそれを簡単に実行できるようにするためのものです。

スポンサーリンク

新しいバーオープンでの取引についての前提

これもおさらい的な内容になりますが、まず大前提として、エキスパートアドバイザーは、基本的には市場の価格が少しでも動くたびに作動するようになっています。

これは、価格が上下に動くことを「ティック」と呼び、新しいティックが来るたびにエキスパートアドバイザーイベントハンドラーであるOnTick関数が反応して動作するのが基本仕様になっている為です。

従って、「新しいバーが生成される瞬間のみにトレードする」という挙動を実現させようとする時には、価格の変動に対して常に反応するのではなく、特定のタイミング、例えば新しい価格バーが始まる時だけ取引を行うようにするには特別な記述を施す必要がある、という事をまず覚えておいてください。

その状態から、新しいバーがオープンした瞬間にのみ取引を行うようにするためには、バーのタイムスタンプを保存し、把握できるところから始まります。

タイムスタンプというのは、特定の瞬間の日時情報を表す値、及びその値を格納している変数等の事を指します。詳しくは↓の記事をご参照ください

スポンサーリンク

「新しいバーのオープンのみに注文を発注できるクラス」実装の為のロードマップ

新しいバーのオープンのみに注文を発注できるクラス」は以下のプロセスで実装していきます。

オリジナルのクラスを作るためのインクルードファイルを生成する

「新しいバーのオープンのみに注文を発注できる」クラスを宣言する

アクセスレベル=privateのメンバを追加する

アクセスレベル=publicのメンバを追加する

メンバ関数の処理実装記述をしていく。

順を追って見ていきましょう。

スポンサーリンク

オリジナルのクラスを作るためのインクルードファイルを生成する

まずはオリジナルのクラスを作るためのインクルードファイルを生成します。

includeファイルの作り方 の手順に従ってMQLウィザードを進めていきます。ファイル名は「OriginalTimer.mqh」としました。

//+------------------------------------------------------------------+
//|                                                OriginalTimer.mqh |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+

中身が空の「OriginalTimer.mqh」ファイルが「include」フォルダ内にできました。

これをたたき台にして、クラス関数を宣言・定義していきます。

MQLウィザードについては↓の記事をご覧ください。

MQL5 EA講座 第2回「メタエディターの使い方」

スポンサーリンク

「新しいバーのオープンのみに注文を発注できる」クラスを宣言する

まず最初に、作成した「OriginalTimer.mqh」ファイル内に「新しいバーのオープンのみに注文を発注できる」クラスの宣言を行います

class OriginalCNewBar
{
	
};

クラス名を「OriginalCNewBarクラス」としました。

スポンサーリンク

アクセスレベル=privateのメンバを追加する

続いてアクセスレベルprivateメンバを2つ追加します

class OriginalCNewBar
{
	private:
		datetime TimeArray[], //現在のバーの時間が時系列で格納される配列
		LastTimeVar;//直近にチェックした時間が格納される
};

配列「TimeArray」は現在のバーの時間が時系列で格納される事を想定した配列です

変数「LastTimeVar」は直近にチェックした時間が格納される事を想定した変数となります。

細かいプログラミングの挙動は後程解説しますが、基本的にこの配列「TimeArray」、変数「LastTimeVar」2つの値を確認して、新しいバーがオープンしたかどうかの確認を行います。

スポンサーリンク

アクセスレベル=publicのメンバを追加する

アクセスレベル=publicには2つのメンバを追加します。

class OriginalCNewBar
  {
         private:
            datetime TimeArray[], //現在の時間を格納
                     LastTimeVar;//直近にチェックした時間
         
         public:
         
            void OriginalCNewBar();//配列「TimeArray」に時系列セットを施すコンストラクタ
            //新しいバーがオープンした瞬間かどうかをチェックする
            bool CheckNewBar(string pSarymbol, ENUM_TIMEFRAMES parTimeframe);
  };

void型関数「OriginalCNewBar」はコンストラクタです。

後程処理実装記述のセクションで解説しますが、配列「TimeArray」に時系列セットを施す処理を行います。

コンストラクタについては↓の記事をご参照ください

もう一つのメンバ関数「CheckNewBar」は、新しいバーがオープンした瞬間かどうかをチェックする処理を担います。

新しいバーがオープンした瞬間かどうかを結果として返すので、必然的にデータ型bool型になります。

スポンサーリンク

メンバ関数の処理実装記述をしていく

privatepublic、それぞれのアクセスレベルにおける必要なメンバの追加が終わったので、今度はメンバ関数に処理実装記述を施していきます。

まずはコンストラクタでもあるOriginalCNewBar関数からです

OriginalCNewBar関数について

OriginalCNewBar関数には引数をとりません

OriginalCNewBar関数の処理実装記述は以下の通りです。

/コンストラクタOriginalCNewBarの処理実装記述
void OriginalCNewBar::OriginalCNewBar(void)
{
	ArraySetAsSeries(TimeArray,true);//配列「TimeArray」を時系列にセットする
}

OriginalCNewBar関数の処理はシンプルでArraySetAsSeries関数を使い、配列「TimeArray」に時系列セット(=最新の時間情報→古い時間情報、という順番で配列にデータが格納されていく)を施すだけです。

ArraySetAsSeries関数については↓の記事をご参照ください

これでメインプログラムにて、OriginalCNewBarクラスインスタンスを生成した際に、自動的に

配列「TimeArray」への時系列セットが完了します。

インスタンスについては↓の記事をご参照ください

CheckNewBar関数について

続いてはCheckNewBar関数についてです。

CheckNewBar関数の引数について

まずは引数についてですが、

//新しいバーがオープンした瞬間かどうかをチェックする
            bool CheckNewBar(string parSymbol, ENUM_TIMEFRAMES parTimeframe);

CheckNewBar関数は2つの引数をとります。

第1引数のparSymbolはメインプログラムにて銘柄情報が記述される想定です。

(_SymbolあるいはSymbol関数を記述すれば、チャートにEAが挿入された銘柄情報が取得されます)

第2引数のparTimeframeにはメインプログラムでチャートの時間軸情報が記述される想定です。

(0、もしくはPERIOD_CURRENTと記述すると現在のチャートの時間軸が適用されます)

データ型であるENUM_TIMEFRAMESについての詳細は↓の記事をご参照ください

CheckNewBar関数の処理実装記述について

続いてCheckNewBar関数の処理実装記述についてです

// 新しいバーがオープンしたかどうかをチェックするメンバ関数の実装
bool OriginalCNewBar::CheckNewBar(string parSymbol, ENUM_TIMEFRAMES parTimeframe)
{
    // 初回実行かどうかを判定するフラグ
    bool firstExe = false;
    // 新しいバーがオープンしたかどうかを示すフラグ
    bool newBarOpen = false;

    // 指定されたシンボルと時間枠の現在と一つ前のバーの時間をTimeArrayにコピー
    CopyTime(parSymbol, parTimeframe, 0, 2, TimeArray);

    // LastTimeVarが0の場合、これが初回実行と判断
    if(LastTimeVar == 0) firstExe = true;

    // TimeArrayの最新の時間がLastTimeVarより大きい場合、新しいバーと判断
    if(TimeArray[0] > LastTimeVar)
    {
        // 初回実行ではない場合、newBarフラグをtrueに設定
        if(firstExe == false) newBarOpen = true;
        // 最後にチェックしたバーのオープン時間を更新
        LastTimeVar = TimeArray[0];
    }

    // 新しいバーの有無を返す
    return(newBarOpen);
}

上記が全体の処理実装記述になります。順を追って1つ1つ見ていきましょう

処理実装記述1:フラグ判定を行う為のbool型変数を宣言する

CheckNewBar関数の{}内冒頭には、2つbool型ローカル変数を宣言します

// 初回実行かどうかを判定するフラグ
    bool firstExe = false;
    // 新しいバーがオープンしたかどうかを示すフラグ
    bool newBarOpen = false;

変数「firstExe」はメインプログラムとなるエキスパートアドバイザーEA)がMT5のチャートに最初にセッティングされた直後かどうかを判定するフラグとなるものです。

初期値はfalseに設定します。

変数「newBarOpen」は新しいバーがオープンしたかどうかを示すフラグとなるものです。

こちらも初期値はfalseに設定しておきます。

2つの変数がどのように使われるのかこの後解説するので、今はわからなくても大丈夫です。

フラグとは?

ここで一応野暮かもしれませんが、「フラグ」という言葉についても説明しておきます。

フラグ」は、ある条件が真(はい)か偽(いいえ)かを示すために使われるプログラム内の信号や印のようなものです。

分かりやすく言い換えるなら、「目印」や「チェックマーク」と考えることができます。プログラムが進むにつれて、特定の状態が発生したかどうかをこの目印を見て判断します。

例えば、お店が開いているかどうかを示す「OPEN」の看板があるとします。

この看板が出ているときはお店が「開店」しているという「目印」として機能し、看板がなければ「閉店」しているとわかります。

プログラミングにおける「フラグ」も同じように、何かの状態を示すために使われる目印です。

処理実装記述2:CopyTime関数を使い、「TimeArray」にバーの時間情報をコピーする
// 指定されたシンボルと時間枠の現在と一つ前のバーの時間をTimeArrayにコピー
    CopyTime(parSymbol, parTimeframe, 0, 2, TimeArray);

続いてCopyTime関数を使い、「TimeArray」にバーの時間情報をコピーします。

CopyTime関数の第3引数には、コピー開始位置、第4引数には、コピーする要素数、第5引数にはコピー先の配列名を記述します。

CopyTime関数についての詳細は↓のリンクをご参照ください

処理実装記述3:EAが初回実行かどうかの判断をする記述を行う

続いて、EAが初回実行かどうか、すなわちEAがチャートにセッティングされた直後かどうかのの判断をする記述を行います。記述は以下のようになります。

 // LastTimeVarが0の場合、これが初回実行と判断
    if(LastTimeVar == 0) firstExe = true;

アクセスレベル=privateに作ったメンバ「LastTimeVar」は直近の時間情報を格納する事を目的としたdatetime型変数です。

この値が0であるという事は、LastTimeVarに時間情報を代入する処理が一切行われていない、という事を意味します

従ってこのif文条件がtrueの時、初回実行フラグの役割を担う変数「firstExe」にtrueを代入します。

新しいバーが生成される瞬間以外にはトレードをしないよう制御するためのクラスなので、EAをチャートに挿入した直後も、新しいバーが生成された時以外は誤って発注をしないようにするための記述となります。

処理実装記述4:配列「TimeArray」の値と変数「LastTimeVar」の値を比較する条件文を記述する

続いて配列「TimeArray」の値と変数「LastTimeVar」の値を比較する条件文を記述します。

  // TimeArrayの最新の時間がLastTimeVarより大きい場合、新しいバーと判断
    if(TimeArray[0] > LastTimeVar)
    {
        // 初回実行ではない場合、newBarフラグをtrueに設定
        if(firstExe == false) newBarOpen = true;
        // 最後にチェックしたバーのオープン時間を更新
        LastTimeVar = TimeArray[0];
    }
if(TimeArray[0] > LastTimeVar)の条件記述について

最初に記載されているif文の記述

if(TimeArray[0] > LastTimeVar)

についてですが、TimeArray[0]というのは、一番直近のバーのオープン時間を格納しています。

一方変数「LastTimeVar」は{}内最後の記述を見てもらうとわかるように

LastTimeVar = TimeArray[0];

とTimeArray[0]のオープン時間情報を代入しているので、基本的にはTimeArray[0]と「LastTimeVar」の値は等しくなっている筈です。

ただし2つ例外があって、それが

1:EAが最初に挿入された時(「LastTimeVar」の値は0になっています)

2:新しいバーが出来た瞬間

の2つのケースです。

1の場合は、「LastTimeVar」の初期値が0になっているのですから、例えばTimeArray[0]の値が「2024.3.12 10:00」だった場合、TimeArray[0]の方が大きくなるのは明らかだとわかります

2の「新しいバーが出来た瞬間」になぜTimeArray[0] > LastTimeVarが成立するのかについてはもう少し説明が必要です。

繰り返しになりますが、基本的にEAは、OnTick関数という値動きがある度に動作する関数内に殆どの記述がされています。

つまり値動きがある度にif(TimeArray[0] > LastTimeVar)という値の比較検討をして、2つの値が同じだった場合は{}内の処理は実行せず、TimeArray[0] > LastTimeVarの条件を満たす時だけ、TimeArray[0]の値を代入する訳です。

従って、例えば「2024.3.12 10:00」に、MT5の1時間足にEAを挿入した場合、挿入後最初の値動き(=TICK)があった時に、「2024.3.12 10:00」というTimeArray[0]に格納されている値がLastTimeVarにも代入されるので、その後値動きがあっても基本TimeArray[0] と LastTimeVarは同じであり、if(TimeArray[0] > LastTimeVar)を満たさないので作動しません。

ところが、時間が進み「2024.3.12 11:00」になって、まだ値動きがない状態のほんの一瞬、

TimeArray[0]=「2024.3.12 11:00」

LastTimeVar=「2024.3.12 10:00」

というif(TimeArray[0] > LastTimeVar)の条件を満たす瞬間がやってきます。

この時晴れて再び{}内の処理が実行され、TimeArray[0]に格納されている値がLastTimeVarにも代入されるので再び

TimeArray[0]=「2024.3.12 11:00」

LastTimeVar=「2024.3.12 11:00」

となり、「2024.3.12 12:00」となるまで処理が実行されなくなる、という仕組みです。

if(TimeArray[0] > LastTimeVar)の条件を満たしている場合の{}内記述について

次は、if(TimeArray[0] > LastTimeVar)の条件を満たしている場合の{}内記述についてです。

if(firstExe == false)

という条件を満たしている時というのは、変数LastTimeVar」に0以外の値、つまり、なんらかの時間情報が入っている=「EAをチャートに挿入した直後ではない」という事を意味しますから、

TimeArray[0] > LastTimeVar

がまぎれもなく新しいバーが生成される瞬間であることを意味します。そこで

if(firstExe == false) newBarOpen = true;

という形で、新しいフラグ用に準備したbool型変数「newBarOpen」をtrueに切り替えます

あとはもう既に説明済みですが↓

// 最後にチェックしたバーのオープン時間を更新
        LastTimeVar = TimeArray[0];
   

TimeArray[0]に格納されている値をLastTimeVarに代入します。

if(TimeArray[0] > LastTimeVar) に対応した{}内の処理は以上になります。

↑の条件を満たしている時は、新しいバーが生成された瞬間であるという判断ができるという事になります。

処理実装記述5:newBarOpenに格納されている値を戻り値として返す

最後に変数「newBarOpen」に格納されている値をreturnを使い、戻り値として返してCheckNewBar関数の処理実装記述は終了です。

 // 新しいバーの有無を返す
    return(newBarOpen);

CheckNewBar関数の処理実装記述を見てもらうとわかる通り、MT5EAを挿入するチャート時間軸にもよりますが、変数「newBarOpen」が返す値は殆どの場合がfalseで、新しいバーが生成される瞬間だけtrueが返ってくるような仕様になっています。

スポンサーリンク

メインプログラムで今回作ったクラス・関数をどのように使っていくかを確認する

最後に今回作ったOriginalCNewBarクラスCheckNewBar関数をメインプログラムでどのように使っていくか?という部分を簡単に解説したいと思います。

使い方の1例となるサンプルコードは以下の通りです。

#include<OriginalTimer.mqh> // OriginalTimer.mqhファイルをインクルード

// NewBarOpenのインスタンスを生成
OriginalCNewBar NewBarOpen;

// input変数
input bool BasedOnNewBar=true; // 新しいバーに基づいて処理を行うかの設定

// OnTick関数は、価格のティックごとに呼ばれる
void OnTick()
  {
   // ローカル変数の定義
   bool newBar = true; // 新しいバーがオープンしたかどうかのフラグ
   int barShift = 0; // バーシフト値

   // BasedOnNewBarがtrueの場合のみ、新しいバーがオープンしたかをチェック
   if(BasedOnNewBar == true)
     {
      // 新しいバーのチェック。戻り値は新しいバーがオープンしたかどうか
      newBar = NewBarOpen.CheckNewBar(_Symbol, _Period);
      // バーシフトを1に設定する
      barShift = 1;
     }

   // 新しいバーがオープンした場合
   if(newBar == true)
     {
      // ここに発注の記述を行う
     }
  }

1つ1つの要素はこれまでの講座記事で既出のものばかりですが、復習も兼ねて順を追って見ていきます

OriginalTimer.mqhファイルをインクルードする

まずはメインプログラムで今回作ったクラスを使えるようにするためにinclude命令OriginalTimer.mqhファイルを読み込みます。

#include<OriginalTimer.mqh> // OriginalTimer.mqhファイルをインクルード

include命令については↓の記事をご参照ください

MQL5 EA講座 第56回「#include命令(#include directive)」

新しいバーに基づいて処理を行うかの設定を行うinput変数を設定する

続いて、新しいバーに基づいて処理を行うかの設定を行います

グロバール領域にinput変数を1つ作ります↓

// input変数
input bool BasedOnNewBar=true; // 新しいバーに基づいて処理を行うかの設定

変数名を仮に「BasedOnNewBar」としました。初期値はtrueとします。

この「BasedOnNewBar」がtrueの時のみ、新バー出現時に基づいた取引を行うようにメインプログラムで記述していきます。

言い換えれば、「BasedOnNewBar」がfalseの時は、新しいバーが出現する前の段階でも、トレード条件を満たせば発注できる状態に切り替えられる、という事です。

input変数についての詳細は↓の記事をご参照ください

MQL5 EA講座 第24回「Input変数」

OnTick関数内の記述を行う

グロバール領域内の記述が終わったので、OnTick関数内の記述をしていきます。

OnTick関数内の記述:ローカル変数を定義する

まずは必要なローカル変数を2つ定義します

// ローカル変数の定義
   bool newBar = true; // 新しいバーがオープンしたかどうかのフラグ
   int barShift = 0; // バーシフト値

bool型ローカル変数「newBar」は新しいバーがオープンしたかどうかのフラグ判定に使います。

初期値はtrueとしておきます。

int型ローカル変数「barShift」はバーシフト値、すなわち直近のバーを0としたとき、そこからどれくらい過去の足にずらしたバーを指定するか?という情報を格納します。

1なら直近のバーから1つ前の足のインデックスを意味します。

初期値は0としておきます。

BasedOnNewBarがtrueの場合に行う処理を記述する。

続いて、

新しいバーに基づいて処理を行うかの設定を行うinput変数を設定する」セクションで宣言したinput変数「BasedOnNewBar」がtrueだった場合の処理記述を行います。

// BasedOnNewBarがtrueの場合のみ、新しいバーがオープンしたかをチェック
   if(BasedOnNewBar == true)
     {
      // 新しいバーのチェック。戻り値は新しいバーがオープンしたかどうか
      newBar = NewBarOpen.CheckNewBar(_Symbol, _Period);
      // バーシフトを1に設定する
      barShift = 1;
     }

input変数「BasedOnNewBar」がtrueという事は、新しいバーが生成される瞬間にのみ発注を行うことを意味します。

その為に行う処理は↓

// 新しいバーのチェック。戻り値は新しいバーがオープンしたかどうか
      newBar = NewBarOpen.CheckNewBar(_Symbol, _Period);

OriginalCNewBarクラスメンバ関数であるCheckNewBar関数戻り値ローカル変数「newBar」に代入することになります。

CheckNewBar関数は、新しいバーが生成される瞬間だけtrueを返しそれ以外の時はfalseを返す仕様になっているので、必然的にローカル変数「newBar」に格納される値もそれに準ずる形になります。

その下の

   // バーシフトを1に設定する
      barShift = 1;

ローカル変数「barShift」に1を代入している記述についてですが、この変数

OnTick関数内の記述:ローカル変数を定義する」セクションで書いたように、直近のバーを0としたとき、そこからどれくらい過去の足にずらしたバーを指定するか?という情報を格納します。

新しいバーが生成される瞬間にトレードをする、ということは必然的にトレード条件を構成するインジケータや終値情報などの配列にアクセスする際のインデックスは直近の足から一つ前のもの、すなわち「1」にすることが妥当です。

例えば下記の例にように↓

double close =Price.Close(barShift);

double ma =MA.Main(barShift);

これまでに作ったクラスインスタンスから移動平均線等のインジケータ値や終値情報を取得する際の引数としてローカル変数「barShift」を使う事を想定しています。

ローカル変数「barShift」の初期値は0に設定されているので、裏を返せば「BasedOnNewBar」がfalseの場合は、トレード条件を構成する材料となるインジケータ値や終値情報のインデックスも0,すなわち現在足の情報となります。

newBarがtrueの場合の記述を行う

最後にローカル変数「newBar」がtrueの場合における記述を行います。

  // 新しいバーがオープンした場合
   if(newBar == true)
     {
      // ここに発注の記述を行う
     }

ローカル変数「newBar」は初期値をtrueに設定していますので、input変数「BasedOnNewBar」がfalseだった場合、すなわち新しいバーが生成される瞬間以外にも発注をOKにしている場合は、ローカル変数「newBar」は常にtrueとなっています。

反対にinput変数「BasedOnNewBar」がtrueだった場合、すなわち新しいバーが生成されるだけに発注をOKにしている場合は、ローカル変数「newBar」の値はしいバーが生成される時だけtrueとなります。

発注の細かい記述は省略させて頂きますが、講座記事71回73回で作ったトレード用のオリジナルクラス内のメンバ関数であるBuy関数Sell関数等を使っていく事になります。

スポンサーリンク

まとめ

今回の記事では「新しいバーのオープンのみに注文を発注できるクラス」の実装について解説しました。

まず今回のクラスを作るにあたり、「そもそも日時データとは何?」「確定足って何?」という部分のおさらいをしました。

※詳しくは当記事の「はじめに:時間及び日付データに関して」セクション及び「確定足についてのおさらい」「新しいバーオープンでの取引についての前提」セクションをご覧ください。

そして、「新しいバーのオープンのみに注文を発注できるクラス」すなわち、OriginalCNewBarクラスの実装手順を解説していきました。

※実装手順については当記事の『「新しいバーのオープンのみに注文を発注できるクラス」実装の為のロードマップ』セクションをご覧ください。

各工程への内部リンクを貼っているのでそこから見たい手順を辿る事ができます。

今回OriginalCNewBarクラスに追加したメンバは以下の通りです。

アクセスレベル=private

配列「TimeArray」:現在のバーの時間が時系列で格納される事を想定した配列

変数「LastTimeVar」:直近にチェックした時間が格納される事を想定した変数

アクセスレベル=public

OriginalCNewBar関数配列「TimeArray」に時系列セットを施すコンストラクタ

CheckNewBar関数:新しいバーがオープンした瞬間かどうかをチェックする処理を担う関数

CheckNewBar関数の処理実装記述については「CheckNewBar関数の処理実装記述について」セクションをご覧ください。

そして最後に、今回作ったOriginalCNewBarクラスをメインプログラムでどのように使っていくか?という簡単な一例を紹介しました。

※詳細は当記事の「メインプログラムで今回作ったクラス・関数をどのように使っていくかを確認する」セクションをご覧ください。

今回は以上となります。次回の講座も引き続き日時データの取り扱いについて解説予定です。

最後までお読みいただきありがとうございました。


第114回「インジケータによるトレードシグナルにON/OFF機能をつける」

   → 第116回「DateTime型を使って、日時データを操作する時の基本的な考え方」

【広告】

<参照>

TimeCurrent関数/TimeToString関数/UNIXタイム/タイムスタンプ/datetime型/iTime関数/StringToTime関数/ENUM_TIMEFRAMES/TimeToStruct関数/GetTickCount関数/MqlDateTime構造体/タイムゾーン/TimeDaylightSavings関数/TimeGMT関数/TimeGMTOffset関数/TimeLocal関数/夏時間


関連用語リンク集

MQL5FX関連の用語リンク集です。
当サイトでは、元々わからない言葉や概念に出くわしたら、すぐその言葉に立ち戻れるよう、かなり細かく内部リンクを張り巡らせており、多様な用語を網羅しています。

興味のある内容に直接アクセスし、疑問の解決にお役立ていただければと思います。

スポンサーリンク
MQL5でEA作ろう講座
スポンサーリンク
シェアする
エムキューエルをフォローする
スポンサーリンク
【超入門】MQL5 でEAを作ろうブログ
タイトルとURLをコピーしました