Come lavorare correttamente in MT5 con OrderSend - pagina 11

 
prostotrader:

Non due, uno :)

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

TRADE_TRANSACTION_REQUEST è necessario quando si usa OrderSendAsymc per ricevere un biglietto d'ordine.

Allora, cosa c'è che non va? Come si fa a sapere se sto usando OrderSendAsync() nello specifico?
E non posso usarlo per controllare, per esempio, il timbro dell'Expert Advisor che mi ha inviato una richiesta di trading? O, per esempio, per controllare il biglietto della posizione da cui è stato eseguito l'ultimo trade?

Infine, posso usare questo evento per controllare il prezzo al quale la transazione è stata fatta (anche se sono d'accordo, controllare il prezzo in questo evento ha senso solo quando si usa il trading asincrono).

Quindi, se uso l'invio asincrono degli ordini, il codice è corretto?

 
Oleg Shenker:

Allora cosa c'è di sbagliato? Come fai a sapere che forse uso OrderSendAsync()?
E non posso usarlo per controllare, per esempio, il timbro dell'Expert Advisor che ha inviato una richiesta di trading? O, per esempio, per controllare il biglietto della posizione da cui è stato eseguito l'ultimo trade?

Infine, posso usare questo evento per controllare il prezzo al quale la transazione è stata fatta (anche se sono d'accordo, controllare il prezzo in questo evento ha senso solo quando si usa il trading asincrono).

Quindi se uso l'invio asincrono dell'ordine, il codice è corretto?

L'argomento si chiama

"Come lavorare correttamente con OrderSend".

Questa funzione (come concepita dagli sviluppatori) dovrebbe essere completamente sincrona, cioè se si invia un ordine e se si riceve un biglietto,

tutto è a posto con l'ordine. Ma ora questa funzione non funziona del tutto correttamente, quindi dopo aver ricevuto il biglietto di un ordine, si

ottenere una conferma in OnTradeTransaction che tutto è a posto.

Cioè, i dati di questo ordine sono completamente sincronizzati nel terminale.

//+------------------------------------------------------------------+
// 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:

L'argomento si chiama

"Come lavorare correttamente con OrderSend".

Questa funzione (come concepita dagli sviluppatori) dovrebbe essere completamente sincrona, cioè se si invia un ordine e se si riceve un biglietto,

tutto è a posto con l'ordine. Ma ora questa funzione non funziona del tutto correttamente, quindi dopo aver ricevuto il biglietto di un ordine, si

ottenere una conferma in OnTradeTransaction che tutto è a posto.

Cioè, i dati di questo ordine sono completamente sincronizzati nel terminale.

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


Grande! Lo so. Solo che sto usando l'invio asincrono degli ordini. Ho un problema diverso, l'evento REQUEST (che significa finalizzare i totali delle transazioni) per la stessa transazione è arrivato due volte.
 
Oleg Shenker:
Grande! So come funziona. Solo che sto usando l'invio asincrono degli ordini. Ho un problema diverso, l'evento REQUEST (nel senso di finalizzare i totali delle transazioni) per la stessa transazione è arrivato due volte.

Non hai capito bene come i messaggi OnTradeTransaction dovrebbero essere gestiti quando si inserisce OrderSEndAsync

Registra questo EA e vedi come funziona

File:
TestOrders.mq5  25 kb
 
prostotrader:

Non hai capito bene come i messaggi OnTradeTransaction dovrebbero essere gestiti quando si inserisce OrderSEndAsync

Registrare l'Expert Advisor e vedere come funziona

Questo è quello che ti sto chiedendo, come TradeTransactions dovrebbe essere gestito correttamente.

 
Oleg Shenker:

Questo è quello che ti sto chiedendo, come TradeTransactions dovrebbe essere gestito correttamente.

L'ordine per OrderSendAsync è il seguente:

Quando si invia un ordine con il comando OrderSendAsync, se l'ordine viene inviato con successo, si riceve 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);
  }

Poi otteniamo tutti gli altri dati in OnTradeTransactions

1. Ricevere il biglietto d'ordine

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 usate ordini a mercato o a limite (non pendenti), cioè quelli che vengono eseguiti immediatamente

o rifiutato, è necessario monitorare TRADE_TRANSACTION_HISTORY_ADD, poiché in ogni caso 3.

Tali ordini vengono aggiunti alla storia.

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 usate ordini pendenti (possono essere eseguiti in parti), allora dovreste monitorare

Ci sono tre eventi TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD.

TRADE_TRANSACTION_ORDER_UPDATE - serve per ottenere informazioni che l'ordine è stato impostato (modificato)

TRADE_TRANSACTION_DEAL_ADD - ottenere informazioni che un accordo è stato eseguito

TRADE_TRANSACTION_HISTORY_ADD - l'ordine non è presente nel sistema commerciale; possiamo visualizzare i dati dell'ordine

Questa è tutta la "saggezza"

Aggiunto

L'interazioneOrderSendAsync eOnTradeTransactionfunziona senza problemi.

e sul forex (reale)

 
prostotrader:

Aggiunto

OrderSendAsync eOnTradeTransactionfunzionano bene, ho controllato su FOREX (demo)

Entrambi su FOREX (reale)

Grazie! Ora so come usare la funzione OnTradeTransaction() o ci sono altri segreti?

Come posso farlo senza alcun avvertimento se l'evento TradeTransaction() può essere perso?

 
Oleg Shenker:

Grazie! Ora so come usare OnTradeTransaction() o ci sono altri segreti?

Come può non esserci alcun avvertimento se l'evento TradeTransaction() può essere perso?

Non ci sono più segreti.

Può perdersi (ma è successo 3-4 volte in 4-5 mesi e in momenti di forte attività di mercato),

quindi l'assicurazione non sarebbe una brutta cosa.

 

Ed ecco un esempio concreto di controllo di un ordine

Registro del terminale:

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 del consulente esperto:

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


L'ordine è stato inviato il2017.01.05 11:46:01.673

Nessuna risposta dal server per più di 1 secondo, l'ordine è stato controllato.

In modalità normale la risposta arriva in 7-10 msec.

 

Rispondere alla domanda"Come lavorare correttamente in MT5 con OrderSend"

C'è una risposta semplice.

Finché gli sviluppatori non risolvono il problema, allora

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 lo fanno, allora

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