いやー、MQL4は仕様どおりに作っても、取引所が絡んだエラーが多いです。
OrderCloseの関数でも同じでした。エラーコード138が必ず返ってくる。
色々調べて試して、ようやく解決しました。記事にまとめてみました。
OrderCloseのエラー内容
20日移動平均線にタッチしたら手仕舞いするというロジックを組んだんだけど、どうしてもオーダーがオープンになったままクローズしない。
ログで表示するようにしてみると、OrderCloseの際に、エラーコード138、その内容はREQUOTEでした。

エラーコード138の意味
公式リファレンスによると


REQUOTE(再見積もり)のエラーという意味のようですが、意味がわからん。
原因はスリッページの値が低いから
相当しらべて、あれこれ色々いじってみたのですが、解決せず。
しかし、以下の方の記事に検索でヒットして、解決しました。


スリッページの値を低く設定すると発生するようです。現に、僕のソースではスリッページ0で動かしてました。
スリッページ=30で実施したところ無事うごきました
スリッページを30ポイントに設定したら、ちゃんとクロースできました。

取引所によって、スリッページの下限は変わるみたい。
調べてもわからないはずだ。。
最後に正常稼働したOrderCloseのソース
このページに検索でたどり着いた方は、色々やっている方だろうから、ご存知だと思うけど。
void ClosePositions_BUY(int my_magic){
int i;
int my_ticket_no;
double my_lots;
double my_price = NormalizeDouble(Ask,int(MarketInfo(Symbol(),MODE_DIGITS)));
bool chk;
int errorcode;
for(i=0;i<OrdersTotal();i++){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false){
break;
}
if(OrderMagicNumber() != my_magic || OrderSymbol() != Symbol()){
continue;
}
my_ticket_no = OrderTicket();
my_lots = OrderLots();
//買いポジションのチェック
if(OrderType() == OP_BUY){
chk = OrderClose(my_ticket_no,my_lots,my_price,Slippage,White);
printf("OrderClose ret=%d , ticket_no=%d , lots=%f , BUY price=%f",chk,my_ticket_no,my_lots,my_price);
if(chk == False){
errorcode = GetLastError(); // エラーコード取得
printf("OrderClose Error! error_code:%d , detail:%s ",errorcode , ErrorDescription(errorcode));
}else{
printf("OrderClose Done!");
}
break;
}
// ループを抜ける
break;
}
}

長くなるので書かなかったけど、上記はロングのみのオーダーをクローズする関数です。OrderType() == OP_SELL でショートのオーダーを検知できます。









ご質問はコメント欄からお願いします
コメント一覧 (4件)
バックテストとの整合性もあるので、スリッページ30は痛くないですか?
私の場合はAlpariのデモで、スリッページ3~5だとエラー138がたびたび返ってきますが、
スリッページ6だと大丈夫なようです?!
サーバーが遠いんですかね?
先月までは3でも問題なく約定していましたが、今月に入ってエラー138が頻発し始めました。
ただpipsでなくpoint表記だから30point=3pipsなのでバックテスト結果とそれほど乖離もないだろうし、それでいいわけですかね?
今まで動いていたのにスリッページでエラーになるということは仕様が変わったのかもしれませんね。スリッページの許容値については、自分ではコントロールできないので、動く範囲にこちらが合わせるしかないかなと思ってます。
コメントありがとうございます。サーバーによって、スリッページの許容値はかなり違うと思います。そして、デモとリアルでも変わってきます。デモでは低スリッページでも動くけど、いざリアルで動かすとエラー連発みたいな。それでかなり悩まされました。