Что делать если при открытии отложенного ордера «брокер занят»?

[Удален]  
Подскажите, пожалуйста, что делать, если эксперт пытается открыть отложенный ордер, и не может этого сделать, т. к. возникает ошибка 137 — «Брокер занят» (ERR_BROKER_BUSY)?

Предполагал, что раз он занят, нужно подождать и попробовать открыть ордер снова:
 
ResultTicket = OrderSend(Symbol(), OP_SELLLIMIT, Lot, Price, 0, StopLoss, TakeProfit, "", 0, 0, Green);
while (ResultTicket < 0) {
    Alert("Ошибка OrderSend ", GetLastError());
    Sleep(100);
    RefreshRates();
    ResultTicket = OrderSend(Symbol(), OP_SELLLIMIT, Lot, Price, 0, StopLoss, TakeProfit, "", 0, 0, Green);
}
Но подобный принципиальный и настойчивый подход привёл к зависанию терминала. :) Что же делать? Как правильно обработать? Может ли возникать такая ошибка из-за загруженности трафика другими приложениями?

Спасибо за советы.
[Удален]  
И ещё, если не трудно... что есть ошибка 130 — «Неправильные стопы» (ERR_INVALID_STOPS)?
 
Если у тебя выставление ордеров производится в функции start() наверно стоит подождать следующего тика.

И ещё, если не трудно... что есть ошибка 130 — «Неправильные стопы» (ERR_INVALID_STOPS)?

Это значит выставляемый отлженный ордер расположен к цене на расстоянии меньшем чем stop level, то есть близо к цене. Или у открываемой позиции уровень устанавливаемого тэйкпрофита или стоплосс находится близко к цене.
Для определения значения stop level для конкретного символа используй функцию MarketInfo().
[Удален]  
Sleep(100);
Мне кажется маловато. Куда так спешить? Неудивительно, что терминал завис. Вместо посылки нового запроса на открытие надо проверить свободен ли торговый поток, и только потом ломиться. Т.е. на мой взгляд все совсем неправильно. Где-то тут была статья про то как делать это правильно.
 
В указанном коде есть следующие недостатки:
  • зацикленный код отсылки без контроля типов ошибок - такой код вообще нельзя использовать (например, он 100% закцикливается в выходные)
  • частота повторения операций 10 раз в секунду - за это можно получить однозначную блокировку, задержка должна быть не меньше 5 секунд через Sleep(5000)
  • Price, StopLoss и TakeProfit вычисляются заранее, а потом вне зависимости от состояния рынка происходит попытка проталкивания заявки на основе старых расчетов. Если ордер устанавливается близко к рынку, то это серьезная ошибка. Цены надо как минимум перепроверять перед попыткой
Прочтите описание обработки торговых ошибок - в эксперте блок отсылки торговых заявок должен быть _защищенным_, а не _зацикленным_. Повторять торговые операции можно только при нескольких конкретных типах ошибок, а в остальных случаях необходимо прекращать попытки и разбираться со своим кодом.
[Удален]  
Большое спасибо, за обстоятельные ответы. Действительно я не анализировал тип ошибки полагая, что возникает только ошибка одного типа, но оказалось, что были и другие. Ссылка не подробное объяснение всех типов ошибок очень пригодилась и внесла ясность.
[Удален]  
Пытаюсь сейчас сделать правильную обработку ошибок при установке ордера и прихожу к выводу, что чтобы всё было «по фэн-шуй» нужно уметь обрабатывать все типы ошибок и для каждого типа производить свою обработку. Мне вот интересно, неужели в хороших экспертах обрабатываются именно все ошибки? Или всё-таки сначала тестируют систему, узнают наиболее вероятные ошибки, а затем обрабатывают только их? Существует ли какая-нибудь общепринятая схема правильной установки ордера, в которой учитывалсь бы любая «нечистая сила способная вырвать коврик из под наших ног»?

Я представляю себе такую универсальную схему установки ордера:
void SetOrder(все_нужные_параметры_ордера) {
    Res = OrderSend(все_нужные_параметры_ордера);
    switch (Res) {
        //Все возможные случаи ошибок
        ...
        ERR_INVALID_STOPS: {
            //Неправильные стопы
            Alert("Неправильные стопы");           //Сообщаем об ошибке
            Sleep(5000);                           //Ждём 5 секунд
            RefreshRates();                        //Обновляем данные
            SetOrder(все_нужные_параметры_ордера); //Рекурсивно снова пытаемся выставить ордер
        }
        ERR_INVALID_TRADE_VOLUME: {
            //Неправильный объём
            Alert("Неправильные объём");           //Сообщаем об ошибке
            Exit();                                //Завершаем работу эксперта
            ...
        }
        ERR_MARKET_CLOSE: {
            //Рынок закрыт
            ...
        }
        //и т. д.
        ...
    }
}
Пойдёт ли такая схема? Есть ли в ней недостатки?
[Удален]  
Недостатки есть во всем, надо только правильно искать.
Большинство ошибок вызваны неправильным построением советника, т.е. если ты заранее проверил уровни стопов, которые собираешься выставить, то ты никогда не получишь сообщение о неправильных стопах. Т.е. эту ошибку, в принципе, можно будет и не анализировать в будущем.

Ошибки надо предотвращать или исправлять, а не долбиться головой в стену, как в данном случае, ты "рекурсивно снова пытаешься выставить ордер" - RefreshRates не вылечит проблему с ошибкой размера стопа. Неправильный объем ещё не повод завершать работу, надо просто заранее проверить, что объем соответствует правилам твоего ДЦ и забыть про этот тип ошибки.
[Удален]  
timbo:
Недостатки есть во всем, надо только правильно искать.
Большинство ошибок вызваны неправильным построением советника
Т. е. ошибки нужно не обрабатывать, а предотвращать, заранее проверяя всё? Резонно, возразить не чем. :) Дело в том, что у меня эксперт пытается играть по заранее определённым данным ордера, и единственное, что может вызвать ошибку это ситуация на рынке, которая динамически меняется… Всё предусмотреть, конечно, можно наверное, но я пока не имею такого опыта, и в данном случае, я хочу получать корректное описание ошибок, чтобы модифицировать эксперт (т. е. пытаться избежать этих ошибок в будущем), а не просто гадать, что произошло… Поэтому мне наверное лучше начать с обработки ошибок, а потом постепенно улучшать код…


Тут ещё оказалось, что switch не понимает константы ошибок, так как я написал. :( Интересно почему так происходит?..