【FX自動売買】EA入門 合計注文数を知る一度に一つの注文に制限する【MT4】

この記事は【EAの教科書シリーズ】の一部です。全記事は以下から確認できます。

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

合計注文数を確認する

上の記事で作成したコードに付け足していく形で解説していきます。先に読んでおくとより理解しやすいかもしれませんが、今回解説していく内容とは切り離せるので、以下のコードを使うことだけさらっと目を通して確認しておければと思います。

前回までのコード:

//+------------------------------------------------------------------+
//|                                                         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);
}

 

 

今回は既に注文しているトレードの数を調べる関数を作成していきます。

目的は一度に成行注文を複数回出さないようにするために現在までの成行注文の数を知ることです。

関数名はTotalOpenOrders()としましょう。先に関数の中身を公開しておきます。

int TotalOpenOrders()
{
int Orders=0;
int Total=OrdersTotal();
   for(int i=Total; i>0; i--)
      {
      bool res=OrderSelect(i-1,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()==OP_BUY || OrderType()==OP_SELL)
         {
         Orders++;
         }
      }
   return(Orders);
}

この関数の戻り値は注文数なので、戻り値の型はintにしてください。それでは順番に解説していきます。

  1. はじめにOrdersというint型の変数を宣言し、0を代入します。これは現在までの成行注文の数を代入するための変数になります。
  2. 次にTotalというint型の変数を宣言し、これにOrdersTotal()という関数の戻り値を代入します。この関数は注文済みのトレードと待機中の注文の数の合計を返します。
  3. 次にfor文でループ処理を作成します。これは先程の変数Totalを利用して、待機中・注文済みの注文がある限り、中身が処理されるようにしています。for文の使い方としては、 はじめに変数iを宣言し、これにTotalを代入し、次にi>0という文で、iが0より大きい間処理を繰り返すようにしています。i–でそして一つの処理が終わるごとに、iの値を-1します。こうすることでTotalに代入された値分だけ処理を繰り返させることができます。
  4. bool res=OrderSelect(i-1,SELECT_BY_POS,MODE_TRADES);というfor文の中の最初の処理は、自分のトレードの中からOrderSelect()という関数を使って、ある一つのトレードを選択するためのコードです。この関数はトレードプール(全てのトレードが保存されている場所)に指定したトレードが存在すればtrueを返します。

    OrderSelect()関数を使った処理が2つある場合、1つは注文を選択するためのもので、trueを返したあとで次の処理に制御を委ねることになります。

    OrderSelect関数は3つの引数をとり、1つ目は選択する注文のインデックス番号です。この番号は0から始まるので、i-1にしてあげることでループ文の最後がちょうど0になり、全てのトレードがインデックス場号の大きい方から順に選択されることになります。

    次の引数SELECT_BY_POSはインデックス番号によってトレードを選択することを指定するためのものです。実は1つ目の引数はチケット番号(詳しい説明は省略)を指定することもできるため、この2つ目の引数によってインデックス番号であることを明示する必要があります。

    3つ目のMODE_TRADESは現在のトレードプールを利用することを指定しています。MODE_HISTORYとすると過去のデータを指定することができます。
  5. 次にif文で選択した注文が買い注文または売り注文であることを判定しています。
  6. もし買い注文または売り注文である場合、Orders変数に1を足します。どちらでもない場合は何もせずに次のfor文に進みます。例えば合計で8つの注文がトレードプールにある場合、次のiは7になります。
  7. 全ての注文を確認し終わったら、iの値は0になり、for文を抜けてOrdersを返します。

TotalOpenOrders()の使い方

TotalOpenOrders()についての解説が終わったので、具体的な使い方について説明します。

この関数はOnTick()の中の前回作成したIsNewCandle()がtrueの場合に呼び出し、注文が存在しない場合、つまりTotalOpenOrders()<1である場合のみトレードを行わせるようにします。そうすることで一度に複数のトレードが行われることを回避できます。

確認:IsNewCandle()は現在のチャート上に新しいローソク足が作成されたかを確認するための関数です。時間軸を一時間にしている場合は一時間ごとにtrueを返します。

void OnTick()
  {
//---
if(IsNewCandle()){
   if(TotalOpenOrders()<1){
      NewOrder();
   }
}
   
  }

まとめ

現在行われているトレードの合計数を確認するための関数TotalOpenOrders()について解説しました。この関数は現在行われているトレードの合計数を返すもので、これが0である場合はトレードが何も行われていないということになります。

自動売買で注文を一つずつ行わせたい場合はこの関数を利用して、値が1未満(=0)である場合のみ注文を出す処理を行わせるようにしましょう。

[itemlink post_id=”2273″]