Функция качественного открытия ордеров BUY/SELL.
Она предназначена для того, чтобы предупреждать ситуации когда советник или скрипт не может открыть ордер из-за ошибок сервера (реквоты, пропадание связи и пр.).
Функцию достаточно добавить в код и исправить Ваш вызов OrderSend:
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, comment, Magic, 0, Blue);
на
ticket = OpenOrder(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, comment, Magic, 0, Blue);
Итак, сама функция:
int OpenOrder (string asymbol, int cmd, double avolume, double aprice, int aslippage, double astoploss, double atakeprofit, string acomment, int amagic, datetime aexpiration = 0, color arrow_color = CLR_NONE) { int err = GetLastError(); err = 0; bool exit_loop = false; int aticket = -1; err = GetLastError(); err = 0; aticket = -1; int TryCount = 20; // Количество попыток на открытие ордера if (cmd == OP_BUY || cmd == OP_SELL) { int cnt = 0; while (!exit_loop) { if (IsTradeAllowed()) { aticket = OrderSend(asymbol, cmd, avolume, aprice, aslippage, astoploss, atakeprofit, acomment, amagic, aexpiration, arrow_color); err = GetLastError(); } else { cnt++; } switch (err) { case ERR_NO_ERROR: 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: 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) { Sleep(1000); RefreshRates(); } if (exit_loop) { if (err != ERR_NO_ERROR) { Print("Ошибка : " + IntegerToString(err)); } } } if (err == ERR_NO_ERROR) { if (OrderSelect(aticket, SELECT_BY_TICKET, MODE_TRADES)) return(aticket); else return(-1); } Print("Ошибка открытия ордера после " + IntegerToString(cnt) + " попыток."); Print("Ошибка : " + IntegerToString(err)); return(-1); } return(-1); }