【MQL4】EA複数ポジションの決済で問題。インデックス番号の罠

スポンサーリンク

問題のポイント

EA決済するときに、ハマったポイントがあったので書いておきます。

オーダー決済すると「インデックス番号の再計算」が行われます。
この再計算は、0から連番になるように再計算されています。

これを把握していないと、複数ポジションの決済でハマります。

ループ処理する際、何か理由がない限りは「0」から初めますよね。
単純な例で書くと、こんな感じですね。
(今はマジックナンバー、シンボルなど無視します)

for(i=0; i<OrdersTotal(); i++){
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true){
        OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
    }
}

これの何が問題かというと、決済したい2つ目以降のポジションで問題が発生します。

インデックス番号の再計算

1つ目のポジションを決済した瞬間に、インデックス番号の再計算が行われるため、こんな感じになっちゃいます。

初期値再計算後「i」値
index 0index 0i = 0 → 1
iindex 1index 1i = 1 → 2
index 2index 2 を決済(欠番)i = 2 → 3
index 3index 2(飛ばされる)
index 4index 3i = 3 → 4
index 5index 4i = 4 → 5
::::

「index 2」の注文を決済したとすると、上記ループで、次は「index 3」をOrderSelectします。

しかし、このときの「index 3」は、元々の「index 4」が再計算されて、繰り上がった注文です。

本来、次に処理したいはずの元々の「index 3」は再計算されて、「index 2」に繰り上がっているため、以降、永遠にOrderSelectされず、処理が飛ばされることになります。

元々の「index 3」も決済対象だったとしたら、
決済されずに残ってしまいます。

以降、ループ終了まで、同じ問題が発生します。

これ、知らないとハマっちゃいます。

解決策

解決策は簡単で「最後尾」から決済していくだけです。

for(i=OrdersTotal()-1; i>=0; i--){
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true){
        OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
    }
}

インデックス番号の再計算で影響が出るのは、決済した注文よりも後ろの注文になります。そのため、最後尾から先頭に向かって処理すると、問題が発生しません。

決済するたびに「i」の値をマイナスして戻してあげる方法もありますが、最後尾から処理した方が簡単です。

決済ループは、最後尾から先頭に向かって処理しましょう。

タイトルとURLをコピーしました