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

 
Подскажите, пожалуйста, что делать, если эксперт пытается открыть отложенный ордер, и не может этого сделать, т. к. возникает ошибка 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 не понимает константы ошибок, так как я написал. :( Интересно почему так происходит?..