【MQL5】 MT5のEA作成の勉強 その19 取引時間の設定 TimeCurrent() / CopyTime()

【MQL5】 MT5のEA作成の勉強 その19 取引時間の設定 TimeCurrent() /  CopyTime()

まえがき

 取引時間の設定は、TimeCurrentまたはCopyTimeを使って、現在サーバーの時刻を取得することで行います。取引時間の設定を行う主な目的は、スプレッドの大きい時間に取引を行って、損失を出すのを防ぐためです。特に、ニューヨーク時間21:00(日本時間7:00)は一時的にすべての市場が閉まるため、この周辺はスプレッドが極端に大きくなります。そのため、この時刻に取引を避ける戦略は重要です。他にも、複数の市場が開いている時間帯と、一つの市場だけが開いている時間帯の傾向の差を考慮する場合や、MT5のEA作成の勉強その17で発生していた、 [Market closed] エラーを避けたい場合にも有効です。

取引時間の設定方法 – 取引禁止時刻を入力変数に定義する –

 まずは、一日のうち、取引禁止時刻の開始と終了の時刻を1時間単位で入力します。コメントには、時刻はサーバーの時刻を基準にする旨を明記します。(単に「時刻」だけだと、ユーザー側のPCの時刻なのか、サーバーの時刻なのかわからないため)

input int    InpNotTradableTime_S   =20;  // 取引禁止時間の開始時刻(サーバー時刻)
input int    InpNotTradableTime_E   =22;  // 取引禁止時間の終了時刻(サーバー時刻)

取引時間の設定方法 – サーバーの時刻を取得する TimeCurrent

  TimeCurrentを使用して、サーバーの時刻を取得します。 TimeCurrentには、 datetime型の戻り値を返す使い方と、 MqlDateTime型の引数に値を入力して返す使い方の二種類があります。時刻の比較には後者を用いると良いでしょう。

   //--- datetime型で取得
   datetime nowtime = TimeCurrent();
   //--- MqlDateTime型で取得
   MqlDateTime nowtime_structure ;
   TimeCurrent(nowtime_structure);
サーバーの時刻を取得する -  TimeCurrent  -
実行結果

取引時間の設定方法 – サーバーの時刻を取得する CopyTime -(非推奨)

  CopyTimeを使用した場合、サーバーの時刻はdatetime型の動的配列として取得されます。 動的配列は範囲を自由に指定できるため、最新の時刻から幾つか昔の時刻(幾つかは事前に決まっていない)を取得したい場合には有用ですが、今回の用途には向かないでしょう。しかも、 動的配列は速度的に不利で、CopyTimeのページにも

「複製する必要があるデータの量がわかっている場合は、過剰なメモリの割り当てを防止するために静的に割り当てられたバッファを受け取り側の配列として使用するべきです。」

MQL5 リファレンス :  CopyTime

とあります。 また、取引時間の取得は datetime型でしかできないので、一日の時刻として比較するためには、TimeToStruct関数を使って、MqlDateTime型に変換する必要があります。

   //--- datetime型動的配列として取得
   datetime nowtime2[] ;
   if(CopyTime(_Symbol,_Period,0,1,nowtime2)!=1)
      return(false);
   //--- MqlDateTime型に変換
   MqlDateTime nowtime_structure2
   TimeToStruct(nowtime2[0],nowtime_structure2)
サーバーの時刻を取得する - CopyTime -
実行結果

取引時間の設定方法 – 時刻の比較を行う –

 取得した時刻と、取引禁止時刻を比較して、現在が取引禁止時刻であれば、処理をスキップします。先ほど取得したMqlDateTime型変数には、「hour」のプロパティがあるので、これと、上記で 入力変数に定義した取引禁止時刻を比較すればOKです。ただし、24時をまたぐ場合、単純に両者の間というコードでは対応できないので、その場合の例外処理も入れておきます。

   //--- ポジションオープン可能時間外なら処理を終了
   if (nowtime_structure.hour >= InpNotTradableTime_S && InpNotTradableTime_E > nowtime_structure.hour)
      return(false);   
   //--- 取引禁止時間Start > 取引禁止時間Endの場合(=24時をまたぐ場合)
   else if (InpNotTradableTime_S > InpNotTradableTime_E && (nowtime_structure.hour >= InpNotTradableTime_S || InpNotTradableTime_E > nowtime_structure.hour))   
      return(false);

 ちなみに、この判定処理を入れる場所を、処理の初めにすれば、サーバーに送信済みの指値/逆指値注文以外一切の取引が行われなくなりますが、トレーリングストップの更新処理などの後に置くことで、トレーリングストップの更新のみ行われるようにする、といった事も可能です。上記コードを含めたEAを実行した結果、以下のように、20~22時(22時「台」は取引実行)は取引を行わなくなりました。

取引時間の設定を行った結果
取引時間の設定を行った結果

まとめ

  取引時間の設定を、TimeCurrentまたはCopyTimeを使って行う方法を学びました。その過程で、動的配列についても学びましたが、実はこれ、インジケータの取得に使われています。あらかじめ取得するバーの数が決まっていればこちらも静的配列にできるはずなので、処理高速化のため、いずれ検討してゆきたいと思います。