Функция качественной модификации ордеров.
Она предназначена для того, чтобы предупреждать ситуации когда советник или скрипт не может изменить уровни StopLoss, TakeProfit или же переместить отложенные(Stop/Limit) ордера из-за ошибок сервера (реквоты, пропадание связи и пр.).
Функцию достаточно добавить в код и исправить Ваш вызов OrderModify:
result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(ldStopLoss, Digits),OrderTakeProfit(),0,CLR_NONE);
на
result = ModifyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(ldStopLoss, Digits),OrderTakeProfit(),0,CLR_NONE);
Сама функция:
bool ModifyOrder (int aticket, double aprice, double astoploss,
double atakeprofit, datetime expiration,
color arrow_color = CLR_NONE)
{
if (IsStopped())
{
Print("Ошибка, остановлен: IsStopped() == true");
return(false);
}
int TryCount = 20;
int cnt = 0;
while(!IsTradeAllowed() && cnt 0)
{
aprice = NormalizeDouble(aprice,digits);
astoploss = NormalizeDouble(astoploss,digits);
atakeprofit = NormalizeDouble(atakeprofit,digits);
}
}
int err = GetLastError(); // so we clear the global variable.
err = 0;
bool exit_loop = false;
bool result = false;
while (!exit_loop)
{
if (IsTradeAllowed())
{
result = OrderModify(aticket, aprice, astoploss, atakeprofit, expiration, arrow_color);
err = GetLastError();
}
else cnt++;
if (result == true)
exit_loop = true;
switch (err)
{
case ERR_NO_ERROR:
exit_loop = true;
break;
case ERR_NO_RESULT:
exit_loop = true;
break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
case ERR_TRADE_TIMEOUT:
cnt++;
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue;
default:
exit_loop = true;
break;
} // end switch
if (cnt > TryCount)
exit_loop = true;
if (!exit_loop)
{
Print("Ошибка, попыток: (" + IntegerToString(cnt) + "/" + IntegerToString(TryCount));
Sleep(500);
RefreshRates();
}
if (exit_loop)
{
if ((err != ERR_NO_ERROR) && (err != ERR_NO_RESULT))
Print("Ошибка: " + IntegerToString(err));
}
} // while (!exit_loop)
if ((result == true) || (err == ERR_NO_ERROR))
{
Print("Успешная модификация");
if(OrderSelect(aticket, SELECT_BY_TICKET, MODE_TRADES))
{
OrderPrint();
return(true); // SUCCESS!
}
else
{
return(false);
}
}
if (err == ERR_NO_RESULT)
{
return(true);
}
Print("Ошибка модификации после " + IntegerToString(cnt) + " попыток");
Print("Ошибка модификации: " + IntegerToString(aticket) + " " + Symbol() +
"@" + DoubleToString(aprice) + " tp@" + DoubleToString(atakeprofit) + " sl@" + DoubleToString(astoploss));
Print("Ошибка : " + IntegerToString(err));
return(false);
}