Como trabalhar corretamente em MT5 com OrderSend - página 11

 
prostotrader:

Não dois, um :)

if(transaction.type == TRADE_TRANSACTION_REQUEST && request.action == TRADE_ACTION_DEAL)

TRADE_TRANSACTION_REQUEST é necessário quando você usa OrderSendAsymc para receber um bilhete de pedido.

Então, o que há de errado aí? Como vocês sabem se estou usando OrderSendAsync() especificamente?
E eu não posso usá-lo para verificar, por exemplo, o carimbo do consultor especializado que me enviou um pedido comercial? Ou, por exemplo, para verificar o bilhete do cargo, a partir do qual a última negociação foi executada?

Finalmente, posso usar este evento para verificar o preço pelo qual a transação foi feita (embora concorde, verificar o preço neste evento só faz sentido quando se usa o comércio assíncrono).

Então, se eu usar o envio assíncrono de pedidos, o código está correto?

 
Oleg Shenker:

Então o que há de errado com isso? Como vocês sabem que talvez eu use OrderSendAsync()?
E não posso usá-lo para verificar, por exemplo, o carimbo do consultor especializado que enviou um pedido comercial? Ou, por exemplo, para verificar o bilhete do cargo, a partir do qual a última negociação foi executada?

Finalmente, posso usar este evento para verificar o preço pelo qual a transação foi feita (embora concorde, verificar o preço neste evento só faz sentido quando se usa o comércio assíncrono).

Então se eu usar o envio assíncrono de pedidos, o código está correto?

O tema é chamado

"Como trabalhar corretamente com a OrderSend".

Esta função (conforme concebida pelos desenvolvedores) deve ser totalmente sincronizada, ou seja, se você enviar um pedido e se receber um ingresso,

tudo está bem com o pedido. Mas agora essa função não funciona muito bem, portanto, após receber um bilhete de um pedido, você

obter uma confirmação na OnTradeTransaction de que tudo está bem.

Ou seja, os dados desta ordem estão totalmente sincronizados no terminal.

//+------------------------------------------------------------------+
// 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;
     }
  }
 
prostotrader:

O tema é chamado

"Como trabalhar corretamente com a OrderSend".

Esta função (conforme concebida pelos desenvolvedores) deve ser totalmente sincronizada, ou seja, se você enviar um pedido e se receber um ingresso,

tudo está bem com o pedido. Mas agora essa função não funciona muito bem, portanto, após receber um bilhete de um pedido, você

obter uma confirmação na OnTradeTransaction de que tudo está bem.

Ou seja, os dados para esta ordem são totalmente sincronizados no terminal.

//+------------------------------------------------------------------+
// 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;
     }
  }


Ótimo! Eu sei disso. Somente estou usando o envio assíncrono de pedidos. Eu tenho um problema diferente, o evento REQUEST (que significa finalizar os totais da transação) para a mesma transação veio duas vezes.
 
Oleg Shenker:
Ótimo! Eu sei como funciona. Somente estou usando o envio assíncrono de pedidos. Eu tenho um problema diferente, o evento REQUEST (no sentido de finalizar os totais da transação) para a mesma transação veio duas vezes.

Você simplesmente não entende bem como as mensagens da OnTradeTransaction devem ser tratadas ao colocar a OrderSEndAsync

Registre esta EA e veja como ela funciona

Arquivos anexados:
TestOrders.mq5  25 kb
 
prostotrader:

Você simplesmente não entende bem como as mensagens da OnTradeTransaction devem ser tratadas ao colocar a OrderSEndAsync

Registre o Expert Advisor e veja como ele funciona

É isso que estou lhe perguntando, como a TradeTransactions deve ser tratada adequadamente.

 
Oleg Shenker:

É isso que estou lhe perguntando, como a TradeTransactions deve ser tratada corretamente.

A ordem para OrderSendAsync é a seguinte:

Quando você envia um pedido com o comando OrderSendAsync, se o pedido for enviado com sucesso, você receberá order_id

bool SendOrderAsyncMode()
  {
   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);
  }

Depois obtemos todos os outros dados na OnTradeTransactions

1. Receber bilhete de pedido

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        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. Se você utiliza ordens de mercado ou de limite (não pendentes), ou seja, aquelas que são executadas imediatamente

ou rejeitada, é necessário monitorar TRADE_TRANSACTION_HISTORY_ADD, já que em qualquer caso 3.

Tais ordens são acrescentadas à história.

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_HISTORY_ADD:
         if(order_ticket==trans.order)
           {
             //Берем данные из истории
           }
         break;
    }
  }


Se você usa ordens pendentes (podem ser executadas em partes), então você deve monitorar

Há três eventos TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD.

TRADE_TRANSACTION_ORDER_UPDATE - serve para obter informações de que o pedido foi estabelecido (modificado)

TRADE_TRANSACTION_DEAL_ADD - obter informações de que um negócio foi executado

TRADE_TRANSACTION_HISTORY_ADD - a ordem não está presente no sistema comercial; podemos visualizar os dados da ordem

Essa é toda a "sabedoria".

Adicionado

A interaçãoOrderSendAsync eOnTradeTransactionfunciona sem problemas.

e sobre forex (real)

 
prostotrader:

Adicionado

OrderSendAsync eOnTradeTransactionfuncionam bem, eu verifiquei no FOREX (demo)

Ambos em FOREX (real)

Obrigado! Agora eu sei como usar a função OnTradeTransaction() ou existem outros segredos?

Como posso fazê-lo sem nenhuma advertência se o evento TradeTransaction() pode se perder?

 
Oleg Shenker:

Obrigado! Agora eu sei como usar a OnTradeTransaction() ou existem outros segredos?

Como não pode haver nenhuma advertência se o evento TradeTransaction() pode se perder?

Não há mais segredos.

Pode se perder (mas aconteceu 3-4 vezes em 4-5 meses e em momentos de forte atividade no mercado),

portanto, o seguro não seria uma coisa ruim.

 

E aqui está um exemplo concreto de verificação de um pedido

Diário de bordo do terminal:

2017.01.05 11:46:01.673 Trades  'xxxxx': buy limit 1.00 PLT-6.17 at 952.3
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

Registro de Conselheiro Especializado:

2017.01.05 11:46:02.829 trader (PLT-3.17,H1)      CheckOrders: Задержка ответа сервера. Ожидание продолжается...


O pedido foi enviado em2017.01.05 11:46:01.673

Sem resposta do servidor por mais de 1 segundo, o pedido foi verificado.

No modo normal, a resposta vem em 7-10 msec.

 

Respondendo à pergunta"Como trabalhar corretamente em MT5 com OrderSend".

Há uma resposta simples.

Até que os desenvolvedores resolvam o problema, então

ulong pre_ticket; //Предварительный тикет
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;
   }
}

Quando o fizerem, então

ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
  {
    if(result.retcode==TRADE_RETCODE_DONE)
    {
      order_ticket=result.order;
    }  
  }
Razão: