時間や曜日やバーの経過で注文判断をしたい場合の処理

記事内に商品プロモーションを含む場合があります
スポンサーリンク

今回は、MT4のEAサンプルソース(FX用)で時間関連の処理を公開します。

はじめに

EAで時間の経過によって(エントリーやら決済やらの)アクションを起こしたい場合のサンプルです。

  • エントリー後、10時間経過していたら決済する
  • エントリー後、バーが10本分を超え&損失中で決済する
  • バーが新たに出来た時だけ処理を行いたい場合
  • 1時間毎に新規注文を行いたい場合
  • 週末(金曜日)のクローズ前に決済したい場合

それでは、1つずつ解説していきます。

サンプルソース

エントリー後、10時間経過していたら決済する

if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){
   //オーダー後10時間を超えた場合(60秒*600分で10時間)
   if(TimeCurrent() - OrderOpenTime() > 60*600 ){
      OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);
   }
}

解説

まず最新のポジションのエントリー時間を取得するために、最新のポジションを選択(OrderSelect)しています。次に、


サーバー側の現在時間(TimeCurrent) – エントリー時間(OrderOpenTime) > 36000秒(10時間分の秒)

とし、現在時間からエントリー時間を引き算してエントリーしてからの経過時間を算出しています。

その時間が36000秒(10時間)を超えている場合、決済(OrderClose)するという形です。
※60(秒) * 600(分)という表記にしているのは、わかりやすいようにしているだけなので36000でも問題ありません

エントリー後、バーが10本分を超え&損失中で決済する

if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){
   //オーダー後、バーが10本を超えた かつ 損失中の場合決済する
   if(OrderOpenTime() < iTime(NULL, 0, 10) && OrderProfit() < 0){
      OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);
   }
}

解説

まず最新のポジションのエントリー時間を取得するために、最新のポジションを選択(OrderSelect)しています。次に、こちら側は経過時間ではなく、経過したバーの本数で判断しています。

エントリー時間(OrderOpenTime) < 10本前のバーの開始時間(iTime(NULL, 0, 10)) 

とし、エントリー時間(OrderOpenTime)よりもエントリーしてからのバー10本分の経過時間(iTime(NULL, 0, 10))が大きかったらという条件にしています。
※バー20本分にしたい場合は、iTime(NULL, 0, 20)これでOKです

かつ、OrderProfit<0なので現在の利益が0より小さい(マイナス)なら決済するという形です。
※利益に関わらず決済したい場合は、『&& OrderProfit() < 0』の部分を削除してください

使用例としては、ここは手堅く利益を得られるに違いないと思ってエントリーしたものの、しばらくたっても状況が良くない場合等の決済判断として使ったりします。

スポンサーリンク

バーが新たに出来た時だけ処理を行いたい場合

datetime prevtime;
  
int start()
{
  
   //新しい足ができた時だけ処理する
   if(Time[0] != prevtime){
      //時間を更新して処理を続行する
      prevtime = Time[0];
   }else{
      //処理せずに終わる
      return(0);
   }
  
  
~~~~~~~~~~~~

解説

まず、Time[0]の値をセット(退避)するためにprevtimeというグローバル変数を設けます。

Time[0]は新しい足ができた時の時間がセットされているので、簡単に15分足とかでイメージしてもらうと 2021/04/01 18:15:00.000のような感じの値がセットされています。(実際は秒数)
このTime[0]は2021/04/01 18:30:00.000になるまで変わりません。

よって、2021/04/01 18:18:40.000とかの場合は、

Time[0]=2021/04/01/ 18:15:00.000
prevtime=2021/04/01/ 18:15:00.000

で同じ値となるためreturn(0);が実行されるので、以降処理はしない作りになっています。よって、エントリーもしないしエントリーするかどうかの判断もなくなります。

時間が進み2021/04/01 18:30:00.000になったジャストタイミングで、

Time[0]=2021/04/01/ 18:30:00.000
prevtime=2021/04/01/ 18:15:00.000

という状況になります。この場合は値が違うので、prevtimeに2021/04/01/ 18:30:00.000をセットし、
エントリーするかどうかの判断をしたりエントリーする場合はエントリーするといった形になります。
※if文の条件からreturn(0);は実行されません

こうすることで、『バーが新たに出来た時だけ処理を行う』という事ができるわけです。
※私が作っているサンプルソースは基本殆どがこの形です

1時間毎に新規注文を行いたい場合

//1時間ごとに新規注文を行う
if(Time[0] % 3600 == 0){
   // 新規エントリー注文
   int CNo = OrderSend(NULL,OP_BUY,・・・
}

解説

Time[0]には最新のバーができた時間が秒数で入っています。『2020.01.02 07:00:00』であれば 『1577948400』、『2020.01.02 08:00:00』であれば 『‭1577952000‬』という具合です。この秒数を3600で「%(剰余演算子)」で割り、余りが無い場合のみ新規注文処理(OrderSend)をするようにしています。

上記計算をした場合、ちょうど1時間毎に0になりますので1時間毎に処理ができるという形になります。これで、何分(時間)足でEAを動かしたとしても9時、10時、11時・・・に新規エントリーしてくれます。

あと、9時15分、10時15分、11時15分・・・としたい場合はどうするかと言いますと、3600のところを1時間⇒15分は4で割った秒数となるので、「if(Time[0] % 900 == 0)」こんな感じでOKです。

スポンサーリンク

週末(金曜日)のクローズ前に決済したい場合

//ポジションを保持しており、かつ金曜日、かつ22時(日本時間AM5:00)を超えたら強制決済する 
if(OrdersTotal() >= 1 && DayOfWeek()==5 && Hour() >= 22){
   // 決済注文
   OrderClose(OrderTicket(),・・・・);
}

解説

まず、OrdersTotal()関数でポジション数を確認しています。ポジションが無かったら特に決済する必要が無いためです。

次に、DayOfWeek()関数で曜日を確認しています。日:0、月:1、火:2、水:3、木:4、金:5、土:6という形です。

最後に、Hour()関数で時間を確認しています。22時は日本時間のAM5:00にあたるので、AM5:00になったら決済するような形です。時間は自分の好みに合わせてもっと早く決済したい場合は時間を調整してください。
※時間はもしかしたらズレがあるかもしれないので一応自分で確認してください(私が利用している日本のFX業者は22時でAM5:00でした)

あと条件が満たされた場合の決済ですが、複数ポジションある場合はもちろん複数決済する必要があります。

おまけ(金曜日のエントリーも制限したい場合)

//金曜日、かつ16時(日本時間PM23:00)を超えたら新規エントリーしない
if(DayOfWeek()==5 && Hour() >= 16){
    
   //ポジションを保持しており、かつ22時(日本時間AM5:00)を超えたら強制決済する 
   if(OrdersTotal() >= 1 && Hour() >= 22){
      //決済注文
      OrderClose(OrderTicket(),・・・・);
   } 
       
   //以降処理しない
   return(0);
} 

こんな風にしておけば、週末の新規エントリーも管理できますね!
※return(0);で以降処理しないようにしているだけなので、この処理をソースコードの先頭の方に書き込んでおく必要があります

主な構文

TimeCurrent()

取引サーバを基準に現在の時間を返す。

PCのローカルタイム(PCの時計)に依存しないので、仮に自分のPCの時計が遅れていても問題が発生しません。

OrderOpenTime()

現在選択しているポジションのエントリー時間を返す。

iTime()

【使用例】
iTime(NULL, 0, 10);

指定したバーの時間を返す。引数は以下の通りです。

  • 引数1・・・通貨ペアです(NULLでチャートの通貨になります)
  • 引数2・・・時間軸です(0でチャートの時間軸になります)
  • 引数3・・・バーシフトです(0で現在バーの開始時間、1で1つ前ーのバーの開始時間)

さいごに

以上が、『時間や曜日やバーの経過で注文判断をしたい場合(処理)』のサンプルとなります。

私が現在利用している時間関連の処理は大体上記の内容で全てです。あまり時間関連の処理を書いていないと、『あれ?どう書くんだっけ・・・』とよくなるのでまとめてみました。

※ EAのサンプルソースを一覧表にまとめました

※オンラインレッスンやってます


コメント