Cómo trabajar correctamente en MT5 con OrderSend - página 11

 
prostotrader:

No dos, uno :)

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

TRADE_TRANSACTION_REQUEST es necesario cuando se utiliza OrderSendAsymc para recibir un ticket de pedido.

¿Qué pasa ahí? ¿Cómo se sabe si estoy utilizando específicamente OrderSendAsync()?
¿Y no puedo utilizarlo para comprobar, por ejemplo, el sello del Asesor Experto que me ha enviado una solicitud de operación? ¿O, por ejemplo, para comprobar el ticket de la posición desde la que se ejecutó la última operación?

Por último, puedo utilizar este evento para comprobar el precio al que se realizó la transacción (aunque estoy de acuerdo, comprobar el precio en este evento sólo tiene sentido cuando se utiliza la negociación asíncrona).

Entonces, si utilizo el envío de órdenes asíncronas, ¿el código es correcto?

 
Oleg Shenker:

Entonces, ¿qué tiene de malo? ¿Cómo sabes que tal vez use OrderSendAsync()?
¿Y no puedo utilizarlo para comprobar, por ejemplo, el sello del Asesor Experto que envió una solicitud de operación? ¿O, por ejemplo, para comprobar el ticket de la posición desde la que se ejecutó la última operación?

Por último, puedo utilizar este evento para comprobar el precio al que se realizó la transacción (aunque estoy de acuerdo, comprobar el precio en este evento sólo tiene sentido cuando se utiliza la negociación asíncrona).

Entonces, si utilizo el envío de órdenes asíncronas, ¿el código es correcto?

El tema se llama

"Cómo trabajar correctamente con OrderSend".

Esta función (tal y como la conciben los desarrolladores) debería ser totalmente sincrónica, es decir, si se envía un pedido y si se recibe un billete,

todo está bien con la orden. Pero ahora esta función no funciona del todo bien, por lo que después de recibir un ticket de un pedido, se

obtener una confirmación en OnTradeTransaction de que todo está bien.

Es decir, los datos de esta orden están totalmente sincronizados en el 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:

El tema se llama

"Cómo trabajar correctamente con OrderSend".

Esta función (tal y como la conciben los desarrolladores) debería ser totalmente sincrónica, es decir, si se envía un pedido y si se recibe un billete,

todo está bien con la orden. Pero ahora esta función no funciona del todo bien, por lo que después de recibir un ticket de un pedido, se

obtener una confirmación en OnTradeTransaction de que todo está bien.

Es decir, los datos de esta orden están totalmente sincronizados en el 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;
     }
  }


¡Genial! Lo sé. Sólo que estoy utilizando el envío de órdenes asíncronas. Tengo un problema diferente, el evento REQUEST (que significa finalizar los totales de la transacción) para la misma transacción llegó dos veces.
 
Oleg Shenker:
¡Genial! Sé cómo funciona. Sólo que estoy utilizando el envío de órdenes asíncronas. Tengo un problema diferente, el evento REQUEST (en el sentido de finalizar los totales de la transacción) para la misma transacción llegó dos veces.

Simplemente no entiende cómo deben manejarse los mensajes OnTradeTransaction al colocar OrderSEndAsync

Grabar este EA y ver cómo funciona

Archivos adjuntos:
TestOrders.mq5  25 kb
 
prostotrader:

Es que no entiendes muy bien cómo se deben manejar los mensajes en OnTradeTransaction al establecer las órdenes OrderSEndAsync

Grabar el Asesor Experto y ver cómo funciona

Eso es lo que te pregunto, cómo se deben manejar correctamente las TradeTransactions.

 
Oleg Shenker:

Eso es lo que te pregunto, cómo se deben manejar correctamente las TradeTransactions.

El orden de OrderSendAsync es el siguiente:

Cuando envíe un pedido con el comando OrderSendAsync, si el pedido se envía con éxito, recibirá 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);
  }

Luego obtenemos todos los demás datos en OnTradeTransactions

1. Recibir el ticket 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. Si utiliza órdenes de mercado o limitadas (no pendientes), es decir, las que se ejecutan inmediatamente

o rechazado, es necesario controlar TRADE_TRANSACTION_HISTORY_ADD, ya que en cualquier caso 3.

Estas órdenes se añaden al historial.

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


Si utiliza órdenes pendientes (pueden ser ejecutadas en partes), entonces debe monitorear

Hay tres eventos TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD.

TRADE_TRANSACTION_ORDER_UPDATE - sirve para obtener información de que la orden ha sido fijada (modificada)

TRADE_TRANSACTION_DEAL_ADD - obtener información de que se ha ejecutado una operación

TRADE_TRANSACTION_HISTORY_ADD - la orden no está presente en el sistema comercial; podemos ver los datos de la orden

Esa es toda la "sabiduría"

Añadido

La interacciónOrderSendAsync yOnTradeTransactionfunciona sin problemas.

y en forex (real)

 
prostotrader:

Añadido

OrderSendAsync yOnTradeTransactionfuncionan bien, lo he comprobado en FOREX (demo)

Ambos en FOREX (real)

Gracias. ¿Ahora sé cómo utilizar la función OnTradeTransaction() o hay algún otro secreto?

¿Cómo puedo hacerlo sin ninguna advertencia si el evento TradeTransaction() puede perderse?

 
Oleg Shenker:

Gracias. ¿Ahora sé cómo usar OnTradeTransaction() o hay algún otro secreto?

¿Cómo es posible que no haya advertencias si el evento TradeTransaction() puede perderse?

No hay más secretos.

Puede perderse (pero ha ocurrido 3-4 veces en 4-5 meses y en momentos de fuerte actividad del mercado),

por lo que el seguro no sería algo malo.

 

Y he aquí un ejemplo concreto de comprobación de un pedido

Registro de la 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 asesores expertos:

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


El pedido fue enviado el2017.01.05 11:46:01.673

No hay respuesta del servidor durante más de 1 segundo, el pedido ha sido comprobado.

En modo normal la respuesta llega en 7-10 mseg.

 

Respondiendo a la pregunta"Cómo trabajar correctamente en MT5 con OrderSend"

La respuesta es sencilla.

Hasta que los desarrolladores arreglen el problema, entonces

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

Cuando lo hacen, entonces

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