ブログタイトルを「FX自動売買システム開発部」から「autoFX」に変更しました!

注文数/ロット数合計関数と最大ポジション数制限機能

本記事で公開しているライブラリーは公開当時のままで、古くなっております。最新版のライブラリーはメルマガ登録いただくことでダウンロードできます。

最大ポジション数制限機能を実現できる関数

現在のポジション数やロット数に応じて、これ以上ロットを増やしたくないなって思う時があると思います。そんな時に役に立つのが今回紹介する注文数またはロット数合計関数です。

注文数(成行注文の場合、ポジション数と同義になる)の方が使うケースが多いかもしれません。

注文数またはロット数合計関数を使えば、最大ポジション数制限機能を実現できますので、サンプルEAで一緒に紹介したいと思います。

//|
//|【関数】指定の注文種類の注文数またはロット数を合計する
//|
//|【引数】 IN OUT  引数名        説明
//|        ----------------------------------
//|         ○      aType         注文種別
//|         ○      aMagic        マジックナンバー
//|         ○      aKbn          カウント対象
//|                                1: 注文数
//|                                2: ロット数
//|         △      aComment      合計対象コメント
//|
//|【戻値】合計注文数または合計ロット数
//|
//|【備考】△:既定値あり
//|
double sumOrderNumberOrLotSize(int aType,
                               int aMagic,
                               int aKbn,
                               string aComment = "")
{
  double sumOrder = 0.0;
  double sumLot   = 0.0;

  for(int i = 0; i < OrdersTotal(); i++){
    if(OrderSelect(i, SELECT_BY_POS) == false){
      break;
    }

    if(OrderSymbol() != Symbol() || 
	   OrderMagicNumber() != aMagic){
      continue;
    }

    if(aComment != "" && 
	   OrderComment() != aComment){
      continue;
    }

    int type = OrderType();
    double lot = OrderLots();

    if(aType == OP_BUY){
      if(type == OP_BUY){
        sumOrder += 1.0;
        sumLot   += lot;
      }
    }else if(aType == OP_SELL){
      if(type == OP_SELL){
        sumOrder += 1.0;
        sumLot   += lot;
      }
    }else if(aType == OP_BUYSTOP){
      if(type == OP_BUYSTOP){
        sumOrder += 1.0;
        sumLot   += lot;
      }
    }else if(aType == OP_SELLSTOP){
      if(type == OP_SELLSTOP){
        sumOrder += 1.0;
        sumLot   += lot;
      }
    }else if(aType == OP_OPEN){
      if(type == OP_BUY || type == OP_SELL){
        sumOrder += 1.0;
        sumLot   += lot;
      }
    }else if(aType == OP_LIMIT){
      if(type == OP_BUYLIMIT || 
	     type == OP_SELLLIMIT){
        sumOrder += 1.0;
        sumLot   += lot;
      }
    }else if(aType == OP_STOP){
      if(type == OP_BUYSTOP || 
	     type == OP_SELLSTOP){
        sumOrder += 1.0;
        sumLot   += lot;
      }
    }else if(aType == OP_ALL){
      sumOrder += 1.0;
      sumLot   += lot;
    }else{
      Print("不正な注文種別 aType = " + aType);
      return(-1);
    }
  }

  if(aKbn == SUM_ORDER_NUMBER){
    double num = sumOrder;
  }else if(aKbn == SUM_LOTSIZE){
    num = sumLot;
  }

  return(num);
}

OrdersTotal()はトレーディングプールにある全ての注文(成行、指値、逆指値)の数を計算してくれます。

OrderSelect()で1つずつ注文を取得し、その注文種別を確認していきます(全ての注文の数だけ繰り返します)。ポジション数を単に合計したい場合は、OP_OPENを関数の引数として渡せばOKです。OP_OPEN、OP_LIMIT、OP_STOP、OP_ALLは独自の注文種別定数で、MQL4の冒頭に以下の通り、定義しておきます。

// 注文数またはロット数合計
#define OP_OPEN           6 // ポジション
#define OP_LIMIT          7 // 指値注文
#define OP_STOP           8 // 逆指値注文
#define OP_ALL            9 // 全て
#define SUM_ORDER_NUMBER  1 // 注文数
#define SUM_LOTSIZE       2 // ロット数

SUM_ORDER_NUMBERとSUM_LOTSIZEも独自の定数で、注文数とロット数、どちらを関数の戻り値とするのかを区別するのに使います。具体的には関数の引数として渡します。

OP_OPENを指定することで、トレーディングプールにある全ての注文から成行注文だけを選出し、その注文数なりロット数なりを合計します。最後のif文で注文数を返すのかロット数を返すのかを判断しています。

サンプルEA

関数だけではイメージが沸きづらいと思いますので、サンプルEAを載せておきます。

「注文数/ロット数合計関数と最大ポジション数制限機能」のSample.mq4
サイズ: 5.0KB
バージョン: 1.0
公開:2019年10月16日

注目すべきは、OnTick()内の以下の記述です。

// ポジション数合計
double positionNumber = sumOrderNumberOrLotSize(OP_OPEN,
                                                MagicNumber,
                                                SUM_ORDER_NUMBER);

// 現在のポジション数が既定ポジション数以上の間は仕掛けない
if(positionNumber >= MaxPositionNumber){
  return;
}

sumOrderNumberOrLotSize()関数で合計ポジション数を取得し、それをパラメータで設定したMaxPositionNumberと比較することで、最大ポジション数以上のポジションを取らないように制御しています。

MQL4プログラミングの最新記事8件

>完全放ったらかしEA 「AutoEndlessCatchRange」

完全放ったらかしEA 「AutoEndlessCatchRange」

「本業が忙しい!」「でも資産運用したい!」そんなあなたに最適なEAです。兼業トレーダーの方はチャートを毎日みて分析してトレードする時間はなかなか確保できないものです。トレードは本EAに任せて、本業やプライベートの時間をもっと増やしませんか?元々は自分自身のために開発したEAですので、手抜き無しのガチものです。

CTR IMG