決済処理でOrderSelectを利用する際のfor文の注意点

MQL4でポジション情報を取得するには、OrderSelect関数とfor文を組み合わせて処理を行います。
例えば以下のような処理では、保有中の全てのポジションをチェックすることが可能です。

for(int i = OrdersTotal() - 1; i >= 0; i--){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break;
// 処理
}

または

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

この2つの書き方はfor文の順番が違います。
前者はインデックス(上記コードのiの値)がポジションの数から0に向かって処理を行っています。
後者はインデックスが0からポジションの数に向かって処理を行っています。

合計損益を調べる場合など、ポジション数が変化しない処理ではどちらの書き方でも問題ありませんが、for文の中で決済処理を記述する場合には必ず前者を使用する必要があります。
この理由はインデックスの値に関係しています。
例えばポジションを3つ保有している場合、各ポジションには0~2の数値が割り振られています。
後者のように0から順に処理を行って決済して行くと次のような処理になります。

最初にインデックス0のポジションが決済される。残ったポジションのインデックスには0と1が割り振られる。
次にインデックス1のポジションが決済される。残ったポジションのインデックスには0が割り振られる。
最後にインデックス2のポジションを選択しようとするが失敗する。インデックス0のポジションは決済されずに残る。

このように途中でインデックスの値が合わなくなり、決済されないポジションが発生します。
前者のようにポジション数から順に決済していく場合には無事決済が行われます。

最初にインデックス2のポジションが決済される。残ったポジションのインデックスには0と1が割り振られる。
次にインデックス1のポジションが決済される。残ったポジションのインデックスには0が割り振られる。
最後にインデックス0のポジションが決済される。
TwitterでシェアFacebookでシェアGoogle+でシェアはてなブックマークに追加

TOPへ