OnTradeTransaction

É chamada em EAs quando ocorre o evento TradeTransaction. A função é projetada para processar os resultados de execução da solicitação de negociação.

void  OnTradeTransaction()
   const MqlTradeTransaction&    trans,     // estrutura da transação comercial
   const MqlTradeRequest&        request,   // estrutura da solicitação
   const MqlTradeResult&         result     // estrutura da resposta
   );

Parâmetros

trans

[in]  Variável do tipo MqlTradeTransaction com descrição da transação feita na conta de negociação.

request

[in]  Variável do tipo MqlTradeRequest com descrição da solicitação que gerou a transação. Contém os valores apenas para a transação de tipo TRADE_TRANSACTION_REQUEST.

result

[in]  Variável do tipo MqlTradeResult com resultado da execução da solicitação que gerou a transação. Contém os valores apenas para a transação de tipo TRADE_TRANSACTION_REQUEST.

Valor retornado

Sem valor retornado

Observação

OnTradeTransaction() é chamada para manipular o evento TradeTransaction que o servidor de negociação envia para o terminal nos seguintes casos:

  • envio da solicitação de negociação a partir do programa MQL5 usando as funções OrderSend()/OrderSendAsync() e sua posterior execução;
  • envio manual da solicitação de negociação através da interface gráfica e sua posterior execução;
  • desencadeamento de ordens pendentes e ordens stop no servidor;
  • execução de operações no lado do servidor de negociação.

 

Informações sobre o tipo de transação são contidas no campo type da variável trans. Os tipos de trasações comerciais são descritas na enumeração ENUM_TRADE_TRANSACTION_TYPE:

  • TRADE_TRANSACTION_ORDER_ADD — adição de uma nova ordem ativa
  • TRADE_TRANSACTION_ORDER_UPDATE — alteração da ordem ativa
  • TRADE_TRANSACTION_ORDER_DELETE — remoção da ordem da lista de ordens ativas
  • TRADE_TRANSACTION_DEAL_ADD — adição da transação ao histórico
  • TRADE_TRANSACTION_DEAL_UPDATE — alteração da transação no histórico
  • TRADE_TRANSACTION_DEAL_DELETE — remoção da transação do histórico
  • TRADE_TRANSACTION_HISTORY_ADD — adição da ordem ao histórico como resultado da execução ou do cancelamento
  • TRADE_TRANSACTION_HISTORY_UPDATE — alteração da ordem que se encontra no histórico de ordens
  • TRADE_TRANSACTION_HISTORY_DELETE — remoção da ordem do histórico de ordens
  • TRADE_TRANSACTION_POSITION — alteração da posição não relacionada à execução da transação
  • TRADE_TRANSACTION_REQUEST — notificação de que a solicitação de negociação foi processada pelo servidor e o resultado de seu processamento foi recebido.

Ao processar transações do tipo TRADE_TRANSACTION_REQUEST, para obter informações adicionais, é necessário analisar os segundo e terceiro parâmetros da função OnTradeTransaction() — request e result.

O envio de uma solicitação de compra leva a uma cadeia de transações comerciais feitas na conta de negociação: 1) a solicitação é aceita para ser processada, 2) para a conta é criada a respectiva solicitação de compra, 3) é executada a ordem, 4) a ordem executada é removida da lista de ordens ativas, 5) adicionada ao histórico de ordens, 6) a transação correspondente é adicionada ao histórico e 7) é criada uma nova posição. Todas essas ações são transações comerciais. A chegada de cada transação desse tipo no terminal é um evento TradeTransaction. FFNeste caso, não é garantida a ordem de recepção destas transações ao terminal, portanto, não se pode construir seu próprio algoritmo de negociação na expectativa de receber certas transações comerciais após a chegada de outras.

Quando EA processa transações comerciais usando o manipulador OnTradeTransaction(), o terminal continua processando as transações recém-chegadas. Assim, o estado da conta de negociação pode mudar já durante o funcionamento da OnTradeTransaction(). Por exemplo, enquanto o programa MQL5 manipula o evento de adição de nova ordem, ela pode ser executada, excluída da lista de pedidos ordens abertas e movida para o histórico. No futuro, o programa será notificado de todos esses eventos.

O comprimento da fila de transações é de 1 024 itens. Se a OnTradeTransaction() demorar a processar a seguinte transação muito tempo, as transações anteriores na fila poderão ser substituídas por transações mais recentes.

O manipulador OnTrade() é chamado após as respectivas chamadas da OnTradeTransaction(). Em geral, não há correlação exata no número de chamadas da OnTrade() e da OnTradeTransaction(). Uma chamada da OnTrade() corresponde a uma ou mais chamadas da OnTradeTransaction.

Cada evento Trade pode ser o resultado de uma ou mais solicitações de negociação. As solicitações de negociação são enviadas para o servidor usando OrderSend() ou OrderSendAsync(). Cada solicitação pode gerar vários eventos de negociação. Você não pode confiar na regra «Uma solicitação - Um evento 'Trade'», já que o processamento de solicitações pode ocorrer em vários estágios e cada operação pode alterar o status de ordens, de posições e do histórico de negociação.

Exemplo de EA com manipulador OnTradeTransaction()

//+------------------------------------------------------------------+
//|                                    OnTradeTransaction_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Exemplo de ouvinte do evento TradeTransaction"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   PrintFormat("LAST PING=%.f ms",
               TerminalInfoInteger(TERMINAL_PING_LAST)/1000.);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
 
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   static int counter=0;   // contador de chamadas da OnTradeTransaction()
   static uint lasttime=0; // hora da última chamada da OnTradeTransaction()
//---
   uint time=GetTickCount();
//--- se a última operação tiver sido realizada há mais de 1 segundo,
   if(time-lasttime>1000)
     {
      counter=0; // significa que se trata de uma nova operação de negociação e, portanto, podemos redefinir o contador
      if(IS_DEBUG_MODE)
         Print(" Nova operação de negociação");
     }
   lasttime=time;
   counter++;
   Print(counter,". ",__FUNCTION__);
//--- resultado da execução do pedido de negociação
   ulong            lastOrderID   =trans.order;
   ENUM_ORDER_TYPE  lastOrderType =trans.order_type;
   ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- nome do símbolo segundo o qual foi realizada a transação
   string trans_symbol=trans.symbol;
//--- tipo de transação
   ENUM_TRADE_TRANSACTION_TYPE  trans_type=trans.type;
   switch(trans.type)
     {
      case  TRADE_TRANSACTION_POSITION:   // alteração da posição
        {
         ulong pos_ID=trans.position;
         PrintFormat("MqlTradeTransaction: Position  #%I64u %s modified: SL=%.5f TP=%.5f",
                     pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
        }
      break;
      case TRADE_TRANSACTION_REQUEST:     // envio do pedido de negociação
         PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST");
         break;
      case TRADE_TRANSACTION_DEAL_ADD:    // adição da transação
        {
         ulong          lastDealID   =trans.deal;
         ENUM_DEAL_TYPE lastDealType =trans.deal_type;
         double        lastDealVolume=trans.volume;
         //--- identificador da transação no sistema externo - bilhete atribuído pela bolsa
         string Exchange_ticket="";
         if(HistoryDealSelect(lastDealID))
            Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID);
         if(Exchange_ticket!="")
            Exchange_ticket=StringFormat("(Exchange deal=%s)",Exchange_ticket);
 
         PrintFormat("MqlTradeTransaction: %s deal #%I64u %s %s %.2f lot   %s",EnumToString(trans_type),
                     lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
        }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD// adição da ordem ao histórico
        {
         //--- identificador da transação no sistema externo - bilhete atribuído pela bolsa
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_FILLED)
           {
            if(HistoryOrderSelect(lastOrderID))
               Exchange_ticket=HistoryOrderGetString(lastOrderID,ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("(Exchange ticket=%s)",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%I64u %s %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
      default// outras transações  
        {
         //--- identificador da ordem no sistema externo - bilhete atribuído pela Bolsa de Valores de Moscou
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_PLACED)
           {
            if(OrderSelect(lastOrderID))
               Exchange_ticket=OrderGetString(ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("Exchange ticket=%s",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%I64u %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
     }
//--- bilhete da ordem    
   ulong orderID_result=result.order;
   string retcode_result=GetRetcodeID(result.retcode);
   if(orderID_result!=0)
      PrintFormat("MqlTradeResult: order #%d retcode=%s ",orderID_result,retcode_result);
//---   
  }
//+------------------------------------------------------------------+
//| converte códigos numéricos de respostas em códigos Mnemonic de string       
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
  {
   switch(retcode)
     {
      case 10004: return("TRADE_RETCODE_REQUOTE");             break;
      case 10006: return("TRADE_RETCODE_REJECT");              break;
      case 10007: return("TRADE_RETCODE_CANCEL");              break;
      case 10008: return("TRADE_RETCODE_PLACED");              break;
      case 10009: return("TRADE_RETCODE_DONE");                break;
      case 10010: return("TRADE_RETCODE_DONE_PARTIAL");        break;
      case 10011: return("TRADE_RETCODE_ERROR");               break;
      case 10012: return("TRADE_RETCODE_TIMEOUT");             break;
      case 10013: return("TRADE_RETCODE_INVALID");             break;
      case 10014: return("TRADE_RETCODE_INVALID_VOLUME");      break;
      case 10015: return("TRADE_RETCODE_INVALID_PRICE");       break;
      case 10016: return("TRADE_RETCODE_INVALID_STOPS");       break;
      case 10017: return("TRADE_RETCODE_TRADE_DISABLED");      break;
      case 10018: return("TRADE_RETCODE_MARKET_CLOSED");       break;
      case 10019: return("TRADE_RETCODE_NO_MONEY");            break;
      case 10020: return("TRADE_RETCODE_PRICE_CHANGED");       break;
      case 10021: return("TRADE_RETCODE_PRICE_OFF");           break;
      case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION");  break;
      case 10023: return("TRADE_RETCODE_ORDER_CHANGED");       break;
      case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS");   break;
      case 10025: return("TRADE_RETCODE_NO_CHANGES");          break;
      case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT");  break;
      case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT");  break;
      case 10028: return("TRADE_RETCODE_LOCKED");              break;
      case 10029: return("TRADE_RETCODE_FROZEN");              break;
      case 10030: return("TRADE_RETCODE_INVALID_FILL");        break;
      case 10031: return("TRADE_RETCODE_CONNECTION");          break;
      case 10032: return("TRADE_RETCODE_ONLY_REAL");           break;
      case 10033: return("TRADE_RETCODE_LIMIT_ORDERS");        break;
      case 10034: return("TRADE_RETCODE_LIMIT_VOLUME");        break;
      case 10035: return("TRADE_RETCODE_INVALID_ORDER");       break;
      case 10036: return("TRADE_RETCODE_POSITION_CLOSED");     break;
      default:
         return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode));
         break;
     }
//---
  }

Veja também

OrderSend, OrderSendAsync, OnTradeTransaction, Estrutura do pedido de negociação, Estrutura da transação comercial, Tipos de transações comerciais, Tipos de operações de negociação, Eventos do terminal do cliente