Да, в общем, все не очень в тему ) Но спасибо за участие.
Речь о том, что "синхронный" ОрдерСенд завершается раньше, чем советник видит его влияние на счет (нет сделки в истории и не меняется позиция).
И для нормальной работы приходится придумывать костыли в виде ожидания события (очень удобная функция! но не в этом случае) или поиска по истории (тоже с ожиданием).
Действительно для ФОРЕКСа есть проблема (запустил этот же советник на ФОРЕКСе)
2016.10.1402:18:20.229 Trades '3941932': buy limit 1.00 GBPUSD at 1.223742016.10.1402:18:20.276 Trades '3941932': accepted buy limit 1.00 GBPUSD at 1.223742016.10.1402:18:20.292 Trades '3941932': order #102956267 buy limit 1.00 / 1.00 GBPUSD at market done in62.769 ms
2016.10.1402:18:20.292 Trades '3941932': failed cancel order #102956267 buy limit 1.00 GBPUSD at 1.22374 [Invalid request]2016.10.1402:18:20.292 Trades '3941932': cancel order #102956267 buy limit 1.00 GBPUSD at 1.223742016.10.1402:18:20.354 Trades '3941932': accepted cancel order #102956267 buy limit 1.00 GBPUSD at 1.223742016.10.1402:18:20.354 Trades '3941932': cancel #102956267 buy limit 1.00 GBPUSD at market done in66.823 ms
2016.10.1402:18:20.229 TestOrders (GBPUSD,H1) OnChartEvent Send Order Sync mode
2016.10.1402:18:20.292 TestOrders (GBPUSD,H1) SendOrderSyncMode Order sent in sync mode
2016.10.1402:18:20.292 TestOrders (GBPUSD,H1) RemoveOrderSyncMode Order not sent (remove) in sync mode.2016.10.1402:18:20.292 TestOrders (GBPUSD,H1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_ADD
2016.10.1402:18:20.292 TestOrders (GBPUSD,H1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_REQUEST
2016.10.1402:18:20.292 TestOrders (GBPUSD,H1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_UPDATE
2016.10.1402:18:20.292 TestOrders (GBPUSD,H1) OnTradeTransaction Order update state = ORDER_STATE_PLACED
2016.10.1402:18:20.292 TestOrders (GBPUSD,H1) OnTradeTransaction Order plased done. Ticket = 1029562672016.10.1402:18:20.292 TestOrders (GBPUSD,H1) RemoveOrderAsyncMode Order sent (remove) in async mode
2016.10.1402:18:20.354 TestOrders (GBPUSD,H1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_UPDATE
2016.10.1402:18:20.354 TestOrders (GBPUSD,H1) OnTradeTransaction Order update state = ORDER_STATE_REQUEST_CANCEL
2016.10.1402:18:20.354 TestOrders (GBPUSD,H1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_DELETE
2016.10.1402:18:20.354 TestOrders (GBPUSD,H1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_HISTORY_ADD
2016.10.1402:18:20.354 TestOrders (GBPUSD,H1) OnTradeTransaction Order remove done. Ticket = 1029562672016.10.1402:18:20.354 TestOrders (GBPUSD,H1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_REQUEST
2016.10.1402:18:20.354 TestOrders (GBPUSD,H1) OnTradeTransaction Order get ticket done. Ticket = 102956267
Andrey Khatimlianskii: Конечно, все получат сообщение. Но они же не будут знать, что кто-то не получил это же сообщение на такт раньше и не запустил новый ордер-сенд.
Новая идея.
Написать советник-синхронизатор. Как только делается OrderSend, отправляются данные на этот советник и ожидается, пока он не ответит.
Хотя, разница со слип-вариантом - те же яйца. В общем, Ваш вариант таки оптимальный, к сожалению.
Спасибо, за ссылку. Но вопрос был немного в другом. Скорее это был не вопрос, а аргумент в пользу проверки состояния ордера на месте, не дожидаясь отработки события OnTrade().
Oleg Shenker: Спасибо, за ссылку. Но вопрос был немного в другом. Скорее это был не вопрос, а аргумент в пользу проверки состояния ордера на месте, не дожидаясь отработки события OnTrade().
Вы, значит не смотрели код примера.
if(SendOrderSyncMode()) { if(order_ticket>0) { if(OrderSelect(order_ticket)) { RemoveOrderSyncMode(order_ticket); } else { Print(__FUNCTION__," Order not select! Ticket = ",order_ticket); } } }
Удаление ордера в синхронном режиме (OrderSend()) должно было быть после получения ответа от
fxsaber: В случае с двумя советниками на одном символе?
Да, двумя советниками на одном символе.
structMqlTradeRequest { ENUM_TRADE_REQUEST_ACTIONS action; // Тип выполняемого действия ulong magic; // Штамп эксперта (идентификатор magic number) ulong order; // Тикет ордера string symbol; // Имя торгового инструмента double volume; // Запрашиваемый объем сделки в лотах double price; // Цена double stoplimit; // Уровень StopLimit ордера double sl; // Уровень Stop Loss ордера double tp; // Уровень Take Profit ордера ulong deviation; // Максимально приемлемое отклонение от запрашиваемой цены ENUM_ORDER_TYPE type; // Тип ордера ENUM_ORDER_TYPE_FILLING type_filling; // Тип ордера по исполнению ENUM_ORDER_TYPE_TIME type_time; // Тип ордера по времени действия datetime expiration; // Срок истечения ордера (для ордеров типа ORDER_TIME_SPECIFIED) string comment; // Комментарий к ордеру ulong position; // Тикет позиции ulong position_by; // Тикет встречной позиции };
Картинку видел. Для биржи все понятно (с лимитным ордером).
Про форекс и маркет-ордера вы не в курсе. Все ясно.
С рыночным ордером тоже самое (на Бирже)
Добавлено
Если посылается рыночный ордер, то получив билет, идём с ним в историю и
смотрим, что с ним произошло. Можно так же, смотреть в OnTradeTransaction
TRADE_TRANSACTION_HISTORY_ADDА как же "если ОрдерСенд вернул тикет, значит исполнено"?
Нужно все-таки в историю бежать, или события ждать? Ну так об этом и ветка!!!
Правильно. А что я не в "кассу" сказал?
Я даже в качестве примера выложил советника (для Биржи)
Да, в общем, все не очень в тему ) Но спасибо за участие.
Речь о том, что "синхронный" ОрдерСенд завершается раньше, чем советник видит его влияние на счет (нет сделки в истории и не меняется позиция).
И для нормальной работы приходится придумывать костыли в виде ожидания события (очень удобная функция! но не в этом случае) или поиска по истории (тоже с ожиданием).
Действительно для ФОРЕКСа есть проблема (запустил этот же советник на ФОРЕКСе)
А вот в ассинхронном режиме (ФОРЕКС) всё отлично работает
Конечно, все получат сообщение. Но они же не будут знать, что кто-то не получил это же сообщение на такт раньше и не запустил новый ордер-сенд.
Новая идея.
Написать советник-синхронизатор. Как только делается OrderSend, отправляются данные на этот советник и ожидается, пока он не ответит.
Хотя, разница со слип-вариантом - те же яйца. В общем, Ваш вариант таки оптимальный, к сожалению.
С рыночным ордером тоже самое (на Бирже)
Добавлено
Если посылается рыночный ордер, то получив билет, идём с ним в историю и
смотрим, что с ним произошло.
OrderSend() абсодютно синхронная функци - если получили билет, то всё исполнилось.
Внизу пример
Добавлено, а здесь логи
https://www.mql5.com/ru/forum/38456/page85#comment_2888263
Спасибо, за ссылку. Но вопрос был немного в другом. Скорее это был не вопрос, а аргумент в пользу проверки состояния ордера на месте, не дожидаясь отработки события OnTrade().
Вы, значит не смотрели код примера.
{
if(order_ticket>0)
{
if(OrderSelect(order_ticket))
{
RemoveOrderSyncMode(order_ticket);
}
else
{
Print(__FUNCTION__," Order not select! Ticket = ",order_ticket);
}
}
}
Удаление ордера в синхронном режиме (OrderSend()) должно было быть после получения ответа от
функции SendOrserSyncMode, но этого не произошло.
2016.10.14 02:18:20.292 Trades '3941932': failed cancel order #102956267 buy limit 1.00 GBPUSD at 1.22374 [Invalid request]
В этом-то и заключается ошибка. По документации, если мы получили тикет, то ордер выставлен в торговую систему,
Но этого (на ФОРЕКС) не происходит, а удаление произошло в теле функции RemoveOrderAsyncMode, т.е
после получения сообщения в OnTradeTransaction
Добавлено
Отвечая на вопрос топикстартера, то после отправки ордера командой OrderSend(),
можно оперировать с ордером после получения события в OntradeTransaction (OnTrade)
Думается, что разработчики пофиксят проблему.
Добавлено
Сейчас посмотрел на ФОРТС - тоже есть эта проблема
2016.10.17 18:45:19.081 Trades '1007932': accepted buy limit 1.00 GAZR-12.16 at 12847
2016.10.17 18:45:19.081 Trades '1007932': buy limit 1.00 GAZR-12.16 at 12847 placed for execution
2016.10.17 18:45:19.091 Trades '1007932': order #52178167 buy limit 1.00 / 1.00 GAZR-12.16 at 12847 done in 17.440 ms
2016.10.17 18:45:19.091 Trades '1007932': failed cancel order #52178167 buy limit 1.00 GAZR-12.16 at 12847.00000 [Invalid request]
2016.10.17 18:45:19.091 Trades '1007932': cancel order #52178167 buy limit 1.00 GAZR-12.16 at 12847
2016.10.17 18:45:19.098 Trades '1007932': accepted cancel order #52178167 buy limit 1.00 GAZR-12.16 at 12847
2016.10.17 18:45:19.099 Trades '1007932': cancel order #52178167 buy limit 1.00 GAZR-12.16 at 12847 placed for execution in 7.215 ms
2016.10.17 18:45:19.074 TestOrders (GAZR-12.16,M1) OnChartEvent Send Order Sync mode
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) SendOrderSyncMode Order sent in sync mode
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) RemoveOrderSyncMode Order not sent (remove) in sync mode.
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_ADD
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_REQUEST
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_UPDATE
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Order update state = ORDER_STATE_REQUEST_ADD
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_REQUEST
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_UPDATE
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Order update state = ORDER_STATE_PLACED
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) OnTradeTransaction Order plased done. Ticket = 52178167
2016.10.17 18:45:19.091 TestOrders (GAZR-12.16,M1) RemoveOrderAsyncMode Order sent (remove) in async mode
2016.10.17 18:45:19.098 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_UPDATE
2016.10.17 18:45:19.098 TestOrders (GAZR-12.16,M1) OnTradeTransaction Order update state = ORDER_STATE_REQUEST_CANCEL
2016.10.17 18:45:19.099 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_REQUEST
2016.10.17 18:45:19.099 TestOrders (GAZR-12.16,M1) OnTradeTransaction Order get ticket done. Ticket = 52178167
2016.10.17 18:45:19.099 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_UPDATE
2016.10.17 18:45:19.099 TestOrders (GAZR-12.16,M1) OnTradeTransaction Order update state = ORDER_STATE_REQUEST_CANCEL
2016.10.17 18:45:19.108 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_REQUEST
2016.10.17 18:45:19.108 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_ORDER_DELETE
2016.10.17 18:45:19.108 TestOrders (GAZR-12.16,M1) OnTradeTransaction Transaction type: TRADE_TRANSACTION_HISTORY_ADD
2016.10.17 18:45:19.108 TestOrders (GAZR-12.16,M1) OnTradeTransaction Order remove done. Ticket = 52178167
Отвечая на вопрос топикстартера, то после отправки ордера командой OrderSend(),
можно оперировать с ордером после получения события в OntradeTransaction (OnTrade)
В случае с двумя советниками на одном символе?
Да, двумя советниками на одном символе.
{
ENUM_TRADE_REQUEST_ACTIONS action; // Тип выполняемого действия
ulong magic; // Штамп эксперта (идентификатор magic number)
ulong order; // Тикет ордера
string symbol; // Имя торгового инструмента
double volume; // Запрашиваемый объем сделки в лотах
double price; // Цена
double stoplimit; // Уровень StopLimit ордера
double sl; // Уровень Stop Loss ордера
double tp; // Уровень Take Profit ордера
ulong deviation; // Максимально приемлемое отклонение от запрашиваемой цены
ENUM_ORDER_TYPE type; // Тип ордера
ENUM_ORDER_TYPE_FILLING type_filling; // Тип ордера по исполнению
ENUM_ORDER_TYPE_TIME type_time; // Тип ордера по времени действия
datetime expiration; // Срок истечения ордера (для ордеров типа ORDER_TIME_SPECIFIED)
string comment; // Комментарий к ордеру
ulong position; // Тикет позиции
ulong position_by; // Тикет встречной позиции
};
отсеивая "не свои" позиции, ордера и сделки.