Пока OrderSend() пытается дозвониться, молотить не должно. Когда выяснилось, что облом - новая попытка. И так пока не поставит. Переменные именно это и должны обеспечивать. Я не имею достаточного опыта автоматической реальной торговли, да и документирован MQ4 недостаточно, вот собака и роется.
IsTradeAllowed() возможно всё равно нужно использовать. Но смысл в том, чтобы повторять запрос пока ордер не будет установлен (не на каждом тике, а только при провале предыдущей попытки).
Вот более реалистичный код, но тоже писался сходу, могут быть огрехи.
... int ticket = 0; bool FirstAttempt = FALSE; ... bool IsSignal() { ... if (условие сигнала) { ticket = 0; FirstAttempt = TRUE; return(TRUE); } else return(FALSE); } int start() { ... if (IsSignal() && (ticket == -1 || FirstAttempt)) { FirstAttempt = FALSE; ticket = OrderSend( ...); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } } ... }
Предположим, есть некая система, дающая сигналы на постановку ордеров, причём раз возникнув, сигнал некоторое время сохраняется. Нужно попытаться поставить один ордер, несмотря на возможные сбои связи и сбои сервера. Если через некоторое время сигнал возникнет снова, нужно ставить новый ордер, и.т.д. (то есть режим мультиордер).
Вот более или менее обдуманный вариант кода. Было бы особенно интересно узнать мнение авторов реально торгующих экспертов, а также их варианты (если это не засекреченное ноу хау, конечно).
... int ticket = 0; bool FirstAttempt = FALSE; bool SendOrder = FALSE; ... bool IsSignal() { ... if (условие сигнала) { // Есть сигнал if (!SendOrder ) { // Сигнал только что возник, заряжаем логику SendOrder = TRUE; // Пока сигнал не прервётся, мы сюда больше не попадём ticket = 0; // Чтобы не вызывать OrderSend(), пока не отработан предыдущий вызов FirstAttempt = TRUE; // Чтобы в первый раз вызвать OrderSend(), вопреки ticket = 0 } else { if (ticket > 0) return(FALSE); // Сигнал продолжается, но ордер уже стоит } return(TRUE); // Есть сигнал, но нет ордера } else { // Сигнал отсутствует SendOrder = FALSE; // Обеспечим зарядку логики при возникновении следующего сигнала return(FALSE); } } int start() { ... // Пытаемся ставить ордер только в момент возникновения сигнала или // если OrderSend() отработала и вернула ошибку, а сигнал ещё сохраняется if (IsSignal() && (ticket == -1 || FirstAttempt)) { FirstAttempt = FALSE; // Чтобы не попадать сюда пока работает OrderSend() if (ticket == -1) ticket = 0; // Чтобы не попадать сюда пока работают повторные вызовы OrderSend() ticket = OrderSend( ...); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } } ... }
Очень правильная постановка вопроса.
Я бы тоже с интересом послушал рекомендации разработчиков.
Одним из методов выяснения отношений с сервером является точное знание его реакции. Более-менее ясен вопрос обработки ошибок, возвращаемых сервером. Но что делать в случае, если информационный пакет с ответом сервера по какой-то причине (здесь - не суть важно) не пришёл?
Какое развитие при этом получит программа, содержащая такой фрагмент?
ticket = OrderSend( ...);
Мои представления о судьбе этого эксперта таковы:
Переменная ticket никогда не получит никакого значения и программа в ожидании ответа сервера (наполняющего хоть чем-то OrderSend() для возврата этому ticket-у) по идее просто "застрянет".
Существует ли какой-нибудь штатный способ разрешения этого конфликта?
Хотелось бы узнать рекомендации разработчиков.
Какое развитие при этом получит программа, содержащая такой фрагмент?
ticket = OrderSend( ...);
Мои представления о судьбе этого эксперта таковы:
Переменная ticket никогда не получит никакого значения и программа в ожидании ответа сервера (наполняющего хоть чем-то OrderSend() для возврата этому ticket-у) по идее просто "застрянет".
Существует ли какой-нибудь штатный способ разрешения этого конфликта?
Хотелось бы узнать рекомендации разработчиков.
Функция OrderSend в любом случае завершится. В сетевом протоколе (и в его независимом диспетчере) есть жесткие ограничения на время проведения операций и таймауты. Если заявка не может быть выполнена из-за сетевых проблем, то операция будет прервана с кодом ошибки.
Эксперт на торговой операции не может зависнуть навечно. Максимум на несколько десятков секунд.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Предполагается, что повторные попытки отправки ордера будут делаться только после того, как OrderSend() закончит работу и вернёт ошибку. И никаких Sleep. Действительно ли это будет так работать?