本記事で公開しているライブラリーは公開当時のままで、古くなっております。最新版のライブラリーはメルマガ登録いただくことでダウンロードできます。
最大ポジション数制限機能を実現できる関数
現在のポジション数やロット数に応じて、これ以上ロットを増やしたくないなって思う時があると思います。そんな時に役に立つのが今回紹介する注文数またはロット数合計関数です。
注文数(成行注文の場合、ポジション数と同義になる)の方が使うケースが多いかもしれません。
注文数またはロット数合計関数を使えば、最大ポジション数制限機能を実現できますので、サンプル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を載せておきます。
注目すべきは、OnTick()内の以下の記述です。
// ポジション数合計 double positionNumber = sumOrderNumberOrLotSize(OP_OPEN, MagicNumber, SUM_ORDER_NUMBER); // 現在のポジション数が既定ポジション数以上の間は仕掛けない if(positionNumber >= MaxPositionNumber){ return; }
sumOrderNumberOrLotSize()関数で合計ポジション数を取得し、それをパラメータで設定したMaxPositionNumberと比較することで、最大ポジション数以上のポジションを取らないように制御しています。