Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Да не в двух, а в одной :)
TRADE_TRANSACTION_REQUEST нужен тогда, когда Вы используете OrderSendAsymc для получения тикета ордера.
И что же там не правильно? Откуда вы знаете, может быть я использую именно OrderSendAsync()?
А для проверки, например, штампа эксперта, пославшего торговый запрос, я не могу это использовать? Или, например, для проверки тикета позиции, с которой была совершена последняя сделка?
Наконец, я могу использовать это событие для того, чтобы проверить цену, по которой была совершена транзакция (хотя, согласен, проверка цены в этом событии имеет смысл только при использовании асинхронной торговли).
То есть, если я использую асинхронную отправку ордера, код правильный?
И что же там не правильно? Откуда вы знаете, может быть я использую именно OrderSendAsync()?
А для проверки, например, штампа эксперта, пославшего торговый запрос, я не могу это использовать? Или, например, для проверки тикета позиции, с которой была совершена последняя сделка?
Наконец, я могу использовать это событие для того, чтобы проверить цену, по которой была совершена транзакция (хотя, согласен, проверка цены в этом событии имеет смысл только при использовании асинхронной торговли).
То есть, если я использую асинхронную отправку ордера, код правильный?
Тема называется
"Как правильно работать с OrderSend"
Эта функция (по замыслу разработчиков) должна быть полностью синхронная, т.е отправил ордер и если получил тикет,
то всё с ордером впорядке. Но сейчас это функция не совсем корректно работает, поэтому, получив тикет ордера, Вы
в OnTradeTransaction должны получить подтверждение, что всё ОК.
Т.е данные по этому ордеру полностью синхронизированы в терминале.
// Expert TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
switch(trans.type)
{
case TRADE_TRANSACTION_ORDER_UPDATE:
switch(trans.order_state)
{
case ORDER_STATE_PLACED:
if(order_ticket==trans.order)
{
Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
if(order_ticket>0)
{
if(OrderSelect(order_ticket))
{
//Данные по ордеру синхронизированы
}
else
{
Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
}
}
else
{
Print(__FUNCTION__," Wrong order ticket = ",trans.order);
}
}
break;
}
break;
}
}
Тема называется
"Как правильно работать с OrderSend"
Эта функция (по замыслу разработчиков) должна быть полностью синхронная, т.е отправил ордер и если получил тикет,
то всё с ордером впорядке. Но сейчас это функция не совсем корректно работает, поэтому, получив тикет ордера, Вы
в OnTradeTransaction должны получить подтверждение, что всё ОК.
Т.е данные по этому ордеру полностью синхронизированы в терминале.
// Expert TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
switch(trans.type)
{
case TRADE_TRANSACTION_ORDER_UPDATE:
switch(trans.order_state)
{
case ORDER_STATE_PLACED:
if(order_ticket==trans.order)
{
Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
if(order_ticket>0)
{
if(OrderSelect(order_ticket))
{
//Данные по ордеру синхронизированы
}
else
{
Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
}
}
else
{
Print(__FUNCTION__," Wrong order ticket = ",trans.order);
}
}
break;
}
break;
}
}
Замечательно! Я это знаю. Только я использую асинхронную отправку ордера. У меня другая проблема, событие REQUEST (по смыслу завершающее подведение итогов транзакции) для одной и той же сделки пришло два раза.
Вы просто не совсем понимаете как нужно обрабатывать сообщения в OnTradeTransaction, при установке ордеров OrderSEndAsync
Запистите этого советника и посмотрите как он работает
Вы просто не совсем понимаете как нужно обрабатывать сообщения в OnTradeTransaction, при установке ордеров OrderSEndAsync
Запистите этого советника и посмотрите как он работает
Так я вас и спрашиваю, как надо правильно обрабатывать TradeTransactions.
Так я вас и спрашиваю, как надо правильно обрабатывать TradeTransactions.
Порядок, для OrderSendAsync такой:
Отправляя ордер командой OrderSendAsync Вы, при успешной отсылке получаете order_id
{
double price=SymbolInfoDouble(Symbol(),SYMBOL_SESSION_PRICE_LIMIT_MAX);
MqlTradeRequest request={0};
MqlTradeResult result={0};
order_ticket=0;
order_id=0;
request.action = TRADE_ACTION_PENDING;
request.magic = 9876543210;
request.symbol = Symbol();
request.volume = 1;
request.price = price;
request.type=ORDER_TYPE_SELL_LIMIT;
request.comment="Async mode";
request.type_filling=ORDER_FILLING_RETURN;
request.type_time=ORDER_TIME_DAY;
if(OrderSendAsync(request,result))
{
if((result.retcode==TRADE_RETCODE_PLACED) || (result.retcode==TRADE_RETCODE_DONE))
{
if(result.request_id>0)
{
order_id=result.request_id;
Print(__FUNCTION__," Order sent in async mode");
return(true);
}
else
{
Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
}
}
else
{
Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
}
}
else
{
Print(__FUNCTION__," Order not sent in async mode.");
}
return(false);
}
Далее ВСЕ остальные данные получаем в OnTradeTransaction
1. Получение тикета ордера
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
switch(trans.type)
{
case TRADE_TRANSACTION_REQUEST:
if((order_id>0) && (order_id==result.request_id))
{
order_id=0;
order_ticket=result.order;
Print(__FUNCTION__," Order get ticket done. Ticket = ",result.order);
}
break;
}
}
2. Если Вы используете рыночные или лимитные (не отложенные) ордера, т.е те, которые сразу исполняются
или отвергаются, то нужно мониторить TRADE_TRANSACTION_HISTORY_ADD, потому что в любом случае
такие ордера добавляются в историю.
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
switch(trans.type)
{
case TRADE_TRANSACTION_HISTORY_ADD:
if(order_ticket==trans.order)
{
//Берем данные из истории
}
break;
}
}
3. Если Вы тспользуете отложенные ордера (могут исполнятся частями), то следует мониторить
стазу три события TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD
TRADE_TRANSACTION_ORDER_UPDATE - служит для получения информации, что ордер установлен (модифицирован)
TRADE_TRANSACTION_DEAL_ADD - узнаём, что произошла сделка
TRADE_TRANSACTION_HISTORY_ADD - ордера НЕТ в торговой системе, смотрим данные по ордеру
Вот и все "премудрости"
Добавлено
Связка OrderSendAsync и OnTradeTransaction работает без нареканий, проверял и на ФОРЕКС (демо)
и на ФОРТС (реал)
Добавлено
Связка OrderSendAsync и OnTradeTransaction работает без нареканий, проверял и на ФОРЕКС (демо)
и на ФОРТС (реал)
Спасибо! Теперь я знаю, как пользоваться функцией OnTradeTransaction() или есть еще какие-то секреты?
Как же без нареканий, если событие TradeTransaction() может потеряться?
Спасибо! Теперь я знаю, как пользоваться функцией OnTradeTransaction() или есть еще какие-то секреты?
Как же без нареканий, если событие TradeTransaction() может потеряться?
Больше нет никаких секретов.
Может потерятся ( но это присходило раза 3-4 за 4-5 месяцев и в моменты сильной активности рынка),
поэтому страховка не помешает.
А вот и конкретный пример проверки ордера
Лог терминала:
2017.01.05 11:46:02.895 Trades 'xxxxx': accepted buy limit 1.00 PLT-6.17 at 952.3
2017.01.05 11:46:02.896 Trades 'xxxxx': buy limit 1.00 PLT-6.17 at 952.3 placed for execution in 1223.187 ms
Лог эксперта:
Приказ был отправлен в 2017.01.05 11:46:01.673
Ответа от сервера небыло более 1 сек., произошла проверка ордера.
В обычном режиме ответ приходит через 7-10 мсек.
Отвечая на вопрос темы "Как правильно работать в MT5 с OrderSend"
Есть простой ответ
Пока рзработчики не исправят недочёт, то
ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
{
if(result.retcode==TRADE_RETCODE_DONE)
{
pre_ticket=result.order;
}
}
//----------------------------------------------------------------+
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
switch(trans.type)
{
case TRADE_TRANSACTION_ORDER_UPDATE:
if((pre_ticket>0) && (trans.order==pre_ticket))
{
switch(trans.order_state)
{
case ORDER_STATE_PLACED:
order_ticket = pre_ticket;
break;
}
}
break;
}
}
А когда исправят, то
//---
if(OrderSend(request,result))
{
if(result.retcode==TRADE_RETCODE_DONE)
{
order_ticket=result.order;
}
}