Не выйдя из OnTick наверно не получится, так как обработчики выполняются в блокируемом режиме.
То есть, если зациклиться в каком то обработчике, то другому обработчику не будет передано управление.
Заводить глобальный флаг, и ловить событие в обработчике OnTrade

Заводить глобальный флаг, и ловить событие в обработчике OnTrade
Есть поверье, что вместо этой функции лучше использовать OnTradeTransaction. Я сейчас как раз с этим разбираюсь.
Но это же в любом случае означает выход из обработчика OnTick, верно? А вот находясь внутри OnTick и отправив запрос посредством OrderSend, нет ли способа дождаться выставления ордера в терминале?В MQL5 же я столкнулся с тем, что функция OrderSend является асинхронной.
Не используйте асинхронную OrderSendAsync() , используйте синхронную OrdersSend() , не выходя из OnTick(), дожидайтесь ответа и анализируйте структуру MqlTradeResult на наличие тиккета ордера.
Как то так наверное.
ЗЫ. Есть нюанс, если пинг больше 400мс то функция OrdersSend() может завершиться не дождавшись ответа.
Не знаю, как у других специалистов реализовано, но у меня (правда, сразу предупрежу, что спецом в программировании не являюсь) по условию:
if(OrdersTotal() == 0) { // здесь размещаете свою функцию на установку отложенного ордера }
всегда устанавливается только один отложенный ордер.
С уважением, Владимир.
В MQL5 же я столкнулся с тем, что функция OrderSend является асинхронной. В том смысле, что возвращаемое ей значение true не гарантирует того, что отложенный ордер был выставлен, а лишь подтверждает тот факт, что торговый сервер успешно принял запрос.
OrderSend() не является асинхронной. Поэтому общая логика ее использования точно такая же, как OrderSend() в MQL4.
Другое дело, что анализировать нужно не то, что возвращает функция в bool, а то, что она возвращает в аргументе result. Об этом прямо написано в документации:
Не используйте асинхронную OrderSendAsync() , используйте синхронную OrdersSend()
Я специально несколько раз упомянул, что использую именно OrdersSend, а не OrderSendAsync. Если почитать описание OrdersSend в справочнике, то там сказано, что она отличается от OrderSendAsync тем, что дожидается ответа от торгового сервера о принятии запроса для обработки. Но это не означает (точнее, не гарантирует), что ордер был или будет выставлен.
не выходя из OnTick(), дожидайтесь ответа и анализируйте структуру MqlTradeResult на наличие тиккета ордера
А как быть, если в этой структуре поле order окажется не заполненным? В документации сказано, что это поле заполняется только в том случае, если ордер был выставлен.
ЗЫ. Есть нюанс, если пинг больше 400мс то функция OrdersSend() может завершиться не дождавшись ответа.
Я так понял, что если даже она дождётся ответа, от этого не станет легче. Ведь это будет означать только то, что торговый сервер принял запрос на выставление ордера, разве нет?
Не знаю, как у других специалистов реализовано, но у меня (правда, сразу предупрежу, что спецом в программировании не являюсь) по условию:
if(OrdersTotal() == 0)
всегда устанавливается только один отложенный ордер.
С уважением, Владимир.
У меня в 95% случаев тоже так. А вот в оставшихся 5% случаев выставляется два. Именно поэтому и возник вопрос, вынесенный в заголовок темы.
OrderSend() не является асинхронной. Поэтому общая логика ее использования точно такая же, как OrderSend() в MQL4.
Да, наверное, я выразился некорректно. Имел в виду, что возвращаемое этой функцией значение true не означает, что ордер был выставлен.
Достаточно проанализировать три первых поля структуры MqlTradeResult (retcode, deal, order), чтобы понять, выставлен ордер (открыта позиция) или нет.
Скажите, пожалуйста, в вашей практике никогда не бывало так, что поле order этой структуры не было заполнено?
У меня ситуация такая, что тики идут очень интенсивно, как из пулемёта, а вот торговые запросы исполняются очень медленно, от 5 секунд до одной минуты.
Сначала анализируйте retcode, потом уже deal и order
Спасибо, попробую это.
Сейчас пока реализовал торговую логику так, как вчера порекомендовал @Roman — с глобальным счётчиком запросов, отправленных на сервер и обработкой события TradeTransaction.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
В ходе портирования одной из своих старых разработок с MQL4 на MQL5 столкнулся с различиями при выставлениями отложенных ордеров в платформе МТ5 по сравнению с МТ4. А может просто не разобрался. В любом случае, хочу попросить совета у опытных разработчиков.
Итак, согласно логике работы советника, в терминале всегда должен находиться один (и только один) отложенный ордер типа BUY LIMIT.
В MQL4 c этой целью в функции OnTick осуществлялся перебор активных ордеров и при выявлении факта отсутствия ордеров типа BUY LIMIT отправлялся запрос на выставление ордера данного типа. Поскольку функция OrderSend в MQL4 является синхронной, поток выполнения эксперта останавливался до момента получения ответа от торгового сервера об успешном выставлении ордера. Вопрос обработки ошибок пока оставим за скобками — будем считать, что запрос всегда обрабатывается успешно. Таким образом, на следующем тике ордер типа BUY LIMIT гарантированно был выставлен (вспомним наше допущение об отсутствии ошибок) и второй ордер этого типа не мог быть выставлен до тех пор, пока существующий не исполнится или не будет удалён.
В MQL5 же я столкнулся с тем, что функция OrderSend является асинхронной. В том смысле, что возвращаемое ей значение true не гарантирует того, что отложенный ордер был выставлен, а лишь подтверждает тот факт, что торговый сервер успешно принял запрос.
В тестере исполнение ордеров происходит молниеносно и там всё работает хорошо. А при торговле в реальном времени я столкнулся с тем, что иногда следующий вызов OnTick происходит раньше, чем ордер BUY LIMIT, отправленный на предыдущем тике, был фактически выставлен. И в таких случаях запрос на его выставление отправляется повторно и появляются два активных ордера BUY LIMIT, что противоречит логике торговой стратегии.
Порекомендуйте, пожалуйста, как наиболее простым способом решить эту задачу?
Иными словами, как, находясь в обработчике OnTick, дождаться фактического (гарантированного) выставления отложенного ордера, отправленного из этого обработчика функцией OrderSend ?