【FX自動売買】EA入門 Barsで新しいローソク足ができたかを判定する【MT4】

FX 自動売買(EA)

MT4をまだダウンロードしていない方はこちらのページでダウンロード方法を案内しているので、事前にMT4を用意しておいてください。

新しくローソク足ができたかを確かめる

前回、上の記事で簡単な注文を出すための関数を実装したEAを作成しました。今回はそちらの完成コードを改良していく形で解説していくので、まだ読んでいない方はそちらを先に読まれることをお勧めしますが、以下に完成コードのみを張り付けておくので、時間がない方はそちらを見ていただければと思います。

test.mq4

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                                                         Kanrinin |
//|                                           https://codelabsjp.net |
//+------------------------------------------------------------------+
#property copyright "Kanrinin"
#property link      "https://codelabsjp.net"
#property version   "1.00"
#property strict

extern double TakeProfit=0.010;
extern double StopLoss=0.005;
extern double LotSize=0.01;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
NewOrder();
   
  }
//+------------------------------------------------------------------+
void NewOrder()
{

int Result=OrderSend(Symbol(),OP_BUY,LotSize,Ask,3,Ask-StopLoss,Ask+TakeProfit,NULL,0123,0,clrNONE);
return;
}

このコードの問題点は新しいティックが作成される度に注文を出していたので、注文量が膨大になってしまうということです。ですので、今回は作成されたティックによって次のバー(ローソク足など)が出来上がったのか、それともバーは増えていないのかを判定して、ティックごとではなくバーごとにEAで注文を出せるようにしていきたいと思います。

今回作成する関数

今回はチャート上に新しいローソク足ができたかどうかをtrue、またはfalseのBoolean値で返す関数を作成していきます。関数名をIsNewCandle()としましょう。

この関数はNewOrder()を呼び出す前にOnTick()の中でティック毎に呼び出し、ローソク足をできたかをチェックします。そのティックと同時にローソク足が作成されていればtrue同じローソク足のままならfalseを返すようにします。

コードは以下のようになっています。

bool IsNewCandle()
{
   static int BarsOnChart=0;  //①
   if(Bars==BarsOnChart){     //②
      BarsOnChart = Bars;     //③
      return(false);          //④
   }
   BarsOnChart = Bars;        //⑤
   return(true);              //⑥
}

戻り値の方はBooleanなので、関数名の前にboolと書きます。

①関数の初めにBarsOnChartという変数を用意し、初期値は0にします。これはチャート上のローソク足の数を記録するためのものです。この変数はstaticをつけて宣言しているため、static変数と呼ばれます。static変数にすることで、関数を何度呼び出しても前回までの値が保存されます。

例えば、通常の変数であればIsNewCandle()が呼び出されるたびにBarsOnChartには0が新しく代入されるため、前回までのローソク足の数を記録しておくことはできません。

しかしstatic変数はもし前回BarsOnChartに10という値が入っていた場合、次にIsNewCandle()を呼び出したときにも10が保存されているため、if文の中で値を正しく比較できるようになります。

②if文の中では前のティックまでのローソク足の数と今回のティック時のローソク足の数が等しいかをチェックしています。BarsはMQLにもともと定義されているもので、現在のバー(ローソク足)の数を表しています。

③④BarsとBarsOnChartの数の等しいということは新しくローソク足が作成されていないということになるため、BarsOnChartにBarsを代入した後で、falseを返します。

return文が実行されると、関数はそこで停止するため、if文の中身のreturn(false);が実行された場合、その後の処理は行われません。

つまりその後の処理はローソク足が新しく作成されていた場合のみに実行されます。

④ローソク足が新しく作成されていた場合にはBarsOnChartに現在のローソク足の数を新しく代入し、⑤trueを返して関数は終了します。

フローチャートで理解する

IsNewCandle()関数をフローチャートで表すと上のフローチャートになります。フローチャートにすると流れが一目でわかるので、便利ですね。

ではIsNewCandle()がOnTick()の中でどのように使われるのかもフローチャートで確認しておきましょう。

OnTick()が呼び出されると、まずはじめにIsNewCandleが呼び出されます。IsNewCandleは新しいローソク足が作成されていれば、trueを返すので、それをif文の中でチェックし、trueであればNewOrder()で新しい注文を出すようにします。難しくないですね。

今回の修正で最終的なコードは以下のようになっています。

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                                                         Kanrinin |
//|                                           https://codelabsjp.net |
//+------------------------------------------------------------------+
#property copyright "Kanrinin"
#property link      "https://codelabsjp.net"
#property version   "1.00"
#property strict

extern double TakeProfit=0.0050;
extern double StopLoss=0.0025;
extern double LotSize=0.01;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
if(IsNewCandle()){
   NewOrder();
}
   
  }
//+------------------------------------------------------------------+
void NewOrder()
{

int Result=OrderSend(Symbol(),OP_BUY,LotSize,Ask,3,Ask-StopLoss,Ask+TakeProfit,NULL,0123,0,clrNONE);
return;
}

bool IsNewCandle()
{
   static int BarsOnChart=0;
   if(Bars==BarsOnChart){
      BarsOnChart = Bars;
      return(false);
   }
   BarsOnChart = Bars;
   return(true);
}

まとめ

ティックごとに新しいバーが作成されたかを確かめてあげることで、ローソク足ごとに注文を出すことができるようになりました。

このEAを1時間足のチャート上で使っている場合は一時間ごとにNewOrder()が実行されるということになります。

合わせてif文の使い方とBarsの使い方も理解できたと思います。

プロフィール

プロフィール
コードラボJP

大学卒業後SEに就職、現在は退職しフリーランスとして活動中。
『初心者でも挫折せずに一人でプログラミングを学べる』をモットーに、コードラボJPを開設
お問い合わせ等はcodelabsjp@gmail.comまで

コードラボJPをフォローする
タイトルとURLをコピーしました