EAやScriptを自作される方は、Order関数群を使っておられるはずです。
for文内でポジションのクローズ処理を書くのが、一般的ではないでしょうか。
以下の2コードを見てください。
コードA
コードB
2つのコードではfor (...)部分が違うだけです。
Aではiの値が1ずつ増加(インクリメント)しています。
Bではiの値が1ずつ減少(デクリメント)しています。
このコードは、
『複数ポジションを持っていた場合に、全てのポジションをクローズする』
という処理を行っているように見えます。
しかし、
実はコードAでは全てのポジションをクローズすることはできません。
iがインクリメントしているか、デクリメントしているか
たったこれだけの違いで現われてくる問題なんです。
具体的に解説します。
今、3つのポジションを持っていると仮定しましょう。
3つのポジションにおける情報は以下の通りとします。
○コードB
まずi = 2(OrdersTotal() - 1)によってポジションcが選択され、ポジションcが決済されました。
決済された後のポジションの状態は以下になります。
その後iはデクリメントされi = 1となります。
i = 1によってポジションbが選択され、…以下略
と、i = -1になるまで以上の操作が繰り返され、めでたく全クローズが完了します。
○続いてA
i = 0によってポジションaが選択され、ポジションaが決済されました。
決済された後のポジションの状態は以下になります。
その後iはインクリメントされi = 1となります。
i = 1によってポジションbが…あれれ?
i = 1によって選択されるのはポジションcですね。
これでは最終的にポジションbが残ってしまうことになりますね。
ポジションが決済される度に、ポジション番号は再割り振りされるみたいで、
その影響でコードAでは全クローズが完了しないのです。
クローズ処理をしないのであれば、コードAでも問題ありませんが、
クローズ処理をする、しないに関わらず、コードBのように書いた方がいいと思います。
for文内でポジションのクローズ処理を書くのが、一般的ではないでしょうか。
以下の2コードを見てください。
コードA
int start()
{
int i, magic;
magic = 111;
for (i = 0; i < OrdersTotal() - 1; i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false)
continue;
if (OrderSymbol() != Symbol() || OrderMagicNumber() != magic)
continue;
if (OrderType() == OP_BUY)
OrderClose(OrderTicket(), OrderLots(), Bid, 3);
else if (OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), Ask, 3);
}
}
コードB
int start()
{
int i, magic;
magic = 111;
for (i = OrdersTotal() - 1; i >= 0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false)
continue;
if (OrderSymbol() != Symbol() || OrderMagicNumber() != magic)
continue;
if (OrderType() == OP_BUY)
OrderClose(OrderTicket(), OrderLots(), Bid, 3);
else if (OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), Ask, 3);
}
}
2つのコードではfor (...)部分が違うだけです。
Aではiの値が1ずつ増加(インクリメント)しています。
Bではiの値が1ずつ減少(デクリメント)しています。
このコードは、
『複数ポジションを持っていた場合に、全てのポジションをクローズする』
という処理を行っているように見えます。
しかし、
実はコードAでは全てのポジションをクローズすることはできません。
iがインクリメントしているか、デクリメントしているか
たったこれだけの違いで現われてくる問題なんです。
具体的に解説します。
今、3つのポジションを持っていると仮定しましょう。
3つのポジションにおける情報は以下の通りとします。
呼び名 | ポジション番号(iの値によって選択) | チケット番号 | タイプ |
ポジションa | 0 | 100 | BUY |
ポジションb | 1 | 101 | SELL |
ポジションc | 2 | 102 | BUY |
○コードB
まずi = 2(OrdersTotal() - 1)によってポジションcが選択され、ポジションcが決済されました。
決済された後のポジションの状態は以下になります。
呼び名 | ポジション番号(iの値によって選択) | チケット番号 | タイプ |
ポジションa | 0 | 100 | BUY |
ポジションb | 1 | 101 | SELL |
その後iはデクリメントされi = 1となります。
i = 1によってポジションbが選択され、…以下略
と、i = -1になるまで以上の操作が繰り返され、めでたく全クローズが完了します。
○続いてA
i = 0によってポジションaが選択され、ポジションaが決済されました。
決済された後のポジションの状態は以下になります。
呼び名 | ポジション番号(iの値によって選択) | チケット番号 | タイプ |
ポジションb | 0 | 101 | SELL |
ポジションc | 1 | 102 | BUY |
その後iはインクリメントされi = 1となります。
i = 1によってポジションbが…あれれ?
i = 1によって選択されるのはポジションcですね。
これでは最終的にポジションbが残ってしまうことになりますね。
ポジションが決済される度に、ポジション番号は再割り振りされるみたいで、
その影響でコードAでは全クローズが完了しないのです。
クローズ処理をしないのであれば、コードAでも問題ありませんが、
クローズ処理をする、しないに関わらず、コードBのように書いた方がいいと思います。


| HOME |