MQL5で直近のトレードがエグジットしてから経過した秒数を返す関数を作った。
直近のトレードがエグジットしてから一定の時間を経過するまでエントリーしたくないときなどに使える。
この関数はEAが最後にエグジットした時間を起点としている。このため、トレーダーが手動でポジションを決済した場合、その時間は起点とはならず、あくまでもEAが最後にエグジットした時間が起点となったままである点に注意が必要だ。恐らく、EA自身がエグジットした場合しかエグジット時間が記録されないのだろう。
ポジションが存在するかいなかを返す関数を内部で使用しているので、この関数も併せて書く。
(補足)取引が存在するかいなかを返す関数も追加しておく。この関数は必要ないが、エグジット後の秒数を返す関数を直近のトレードがエグジットしてから一定の時間を経過するまでエントリーしたくないときに使う場合は併用したほうがいい。例えばエグジットしてから1時間以上経過しないとエントリーしないとする。これを売買ルールに入れると、1回もエントリーしないということが起きる。なぜなら最初のエントリーではその前のエグジットが存在しないため、エグジット後の秒数が0になるからだ。よって、少なくとも1回は取引が存在することは確認する必要がある。
なお、MQL5での取引とは入金、エントリー、エグジットのタイミングで発生する。例えば、バックテストをして10回トレードがあった場合、取引数は21回になる。最初の入金1回、エントリー10回、エグジット10回で計21回というわけだ。ここではトレードはエントリー1回、エグジット1回のセットという意味で使うことにする。したがって必ずしも「取引=トレード」ではない。
環境
- OANDA MetaTrader 5: 5.00 build 4040
- MetaEditor: 5.00 build 4040
エグジット後のバー数を返す関数
//+------------------------------------------------------------------+ //| 取引が存在するかいなか(2023/12/08動作確認) | //+------------------------------------------------------------------+ bool isDealExist(int magic // マジックナンバー ) { bool res=false; // 戻り値 HistorySelect(0,TimeCurrent()); for(int i=0;i<HistoryDealsTotal();i++) { ulong deal_ticket=HistoryDealGetTicket(i); // 取引のチケット string deal_symbol=HistoryDealGetString(deal_ticket,DEAL_SYMBOL); // 取引の銘柄 ulong deal_magic=HistoryDealGetInteger(deal_ticket,DEAL_MAGIC); // 取引のマジックナンバー if(deal_symbol==Symbol() && deal_magic==magic) { res=true; break; } } return(res); } //+------------------------------------------------------------------+ //| ポジションが存在するかいなか(2023/11/10動作確認) | //+------------------------------------------------------------------+ bool isPositionExist(int magic // マジックナンバー ) { bool res=false; // 戻り値 for(int i=0;i<PositionsTotal();i++) { string position_symbol=PositionGetSymbol(i); // ポジションの銘柄 long position_magic=PositionGetInteger(POSITION_MAGIC); // ポジションのマジックナンバー if(position_symbol==Symbol() && position_magic==magic) { res=true; break; } } return(res); } //+------------------------------------------------------------------+ //| エグジット後の秒数(2023/12/09動作確認) | //+------------------------------------------------------------------+ int SecondsSinceExit(int magic // マジックナンバー ) { HistorySelect(0,TimeCurrent()); int res=0; // 戻り値 //--- 新しい順に検索している点に注意。ここでは最新の取引のみ検索対称としている for(int i=HistoryDealsTotal()-1;i>=0;i--) { ulong deal_ticket=HistoryDealGetTicket(i); // 取引のチケット string deal_symbol=HistoryDealGetString(deal_ticket,DEAL_SYMBOL); // 取引の銘柄 ulong deal_magic=HistoryDealGetInteger(deal_ticket,DEAL_MAGIC); // 取引のマジックナンバー ulong deal_entry=HistoryDealGetInteger(deal_ticket,DEAL_ENTRY); // 取引のエントリー if(deal_symbol==Symbol() && deal_magic==magic && deal_entry==DEAL_ENTRY_OUT) { datetime deal_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME); // 取引の時間 res=int(TimeCurrent()-deal_time); break; } } //--- return(res); }
使用例
マジックナンバーが1であるとして、直近のトレードがエグジットしてから1時間(3600秒)はエントリーしたくない場合、以下のようにする。
if((isDealExist(1)==false || SecondsSinceExit(1)>=3600) && 他のエントリー条件) 新規注文;