Как убрать ошибку 4107

 

Собственно просто делюсь опытом решения ошибки 4107. Возникает она при закрытии ордера функцией OrderClose и суть в том, что советник посылает цену закрытия ордера не 1.23455, например, а 1.2345500000000. В этом случае лишние нули нужно просто "отбросить". Делается это функцией NormalizeDouble. То есть строка должна выглядеть уже таким образом OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,5),2,Violet) (при закрытии ордера на продажу вместо Bid указывается Ask).

Но это в том случае, если мы знаем количество знаков после запятой (в нашем случае указано 5). Допустим в советнике, который будет стоять на одном графике, а отслеживать открытые ордера по всем графикам возникнет сложность с тем, что на других графиках количество знаков после запятой может быть различным. В этой ситуации нам надо будет получить количество знаков после запятой именно по той паре, где ордер открыт, а не по той, где стоит советник. И тогда код будет выглядеть следующим образом:

if(OrderType()==OP_BUY)
           {
            Dig=(int)MarketInfo(OrderSymbol(),MODE_DIGITS); // Определение кол-ва знаков после запятой на паре, где открыт выбранный ордер
            if(!OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Dig),2,Violet))
               Print("OrderClose error ",GetLastError());
            return;

           } 

 
 
Alexey Surkov:

Собственно просто делюсь опытом решения ошибки 4107. Возникает она при закрытии ордера функцией OrderClose и суть в том, что советник посылает цену закрытия ордера не 1.23455, например, а 1.2345500000000. В этом случае лишние нули нужно просто "отбросить". Делается это функцией NormalizeDouble. То есть строка должна выглядеть уже таким образом OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,5),2,Violet) (при закрытии ордера на продажу вместо Bid указывается Ask).

Но это в том случае, если мы знаем количество знаков после запятой (в нашем случае указано 5). Допустим в советнике, который будет стоять на одном графике, а отслеживать открытые ордера по всем графикам возникнет сложность с тем, что на других графиках количество знаков после запятой может быть различным. В этой ситуации нам надо будет получить количество знаков после запятой именно по той паре, где ордер открыт, а не по той, где стоит советник. И тогда код будет выглядеть следующим образом:

if(OrderType()==OP_BUY)
           {
            Dig=(int)MarketInfo(OrderSymbol(),MODE_DIGITS); // Определение кол-ва знаков после запятой на паре, где открыт выбранный ордер
            if(!OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Dig),2,Violet))
               Print("OrderClose error ",GetLastError());
            return;

           } 

Не надо-бы делиться плачевным опытом...

Если советник поставлен на EURUSD а закрывать ордер надо на USDJPY то этот код работать не будет потому, Bid будет равен цене EURUSD а не USDJPY.

Попробуй лучше так

if(OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 20, Violet)) Print(" Ураааа, заработало!!!");

будешь приятно удивлён когда будут закрываться ВСЕ ордера не зависимо от валюты или направления.

 
Спасибо за совет)