Calcular Ordem Fechada em Fim de Pregão

 

Olá!


Após criar um EA para operar Mini-Índice, fiz um breve código para calcular o valor de fechamento das ordens.

Quando uma ordem atinge o TakeProft (TP) ou StopLoss (SL), está calculando corretamente os valores. 

Mas como eu programei para ser apenas Day Trade, fiz uma função que ao término do expediente (no horário que o usuário setar em parâmetros), se houver ordens abertas, estas são fechadas.

O problema é que quando as ordens são fechadas no fim do expediente, eu não consigo pegar o valor do resultado desta ordem. 

User a transação "OnTradeTransaction" para este controle.

Vou compartilhar o código de OnTradeTransaction e da Função que fecha as ordens no fim do expediente.

Por favor, poderiam me ajudar a calcular o  resultado da ordem fechada pela função do fim do expediente?

//+-------------------------------------------+
//| Evento chamado em cada transação de trade |
//+-------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
{       
    // Se a transação é adição de um deal
    if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
    {
            
        if(HistoryDealSelect(trans.deal))
        {
            m_deal.Ticket(trans.deal);
        }
        else
        {
            return;
        }
        
        // Verifica se o deal é do EA e do símbolo atual
        if(m_deal.Magic() == NumeroMagico && m_deal.Symbol() == _Symbol)
        {
            if(m_deal.DealType() == DEAL_TYPE_BUY || m_deal.DealType() == DEAL_TYPE_SELL)
            {
                if(m_deal.Entry() == DEAL_ENTRY_IN)
                {
                    //Print("UMA ORDEM FOI ABERTA");
                    // Aqui você pode atualizar variáveis globais para controle da operação aberta
                                       
                }
                
                //AO FECHAR ORDEM DE VENDA
                else if(m_deal.Entry() == DEAL_ENTRY_OUT)
                {
                    if(m_deal.DealType() == DEAL_TYPE_BUY)
                    {
                        double precoFechamento = m_deal.Price();  // Obtém o preço do deal (fechamento)
                        double lucroUltimaOperacao = 0.0;
                        
                        lucroUltimaOperacao = ((precoAberturaOrdem-precoFechamento)/5) * Lote;
                        resultadoUltimaOperacao = lucroUltimaOperacao;
                        
                        //Print("LUCRO ANTES...: ", Lucro);
                        
                        //Atualiza o Controle de Lucros
                        Lucro += lucroUltimaOperacao;
                        SaldoAtual = Lucro;
                        
                        if (lucroUltimaOperacao > 10)   TakeAtingido=true;    // Se teve TP em C2, Não Abre Ordem em C3
                        if (lucroUltimaOperacao >= 0)    OrdensVencedoras++;  // Conta Ordens Vencedoras

                        // Atualiza Taxa de Acertividade (%)                           
                        TaxaAcertividade = (OrdensVencedoras/QtdeOperacoes) * 100;


                        //Print("Resultado da Venda = ", lucroUltimaOperacao, 
                        //" | Preço de Abertura = ", precoAberturaOrdem,
                        //" | Preço de Fechamento = ", precoFechamento);
                        
                        //Print("LUCRO DEPOIS...: ", Lucro);
                    
                    }
                    
                    //AO FECHAR ORDEM DE COMPRA
                    else if(m_deal.DealType() == DEAL_TYPE_SELL)
                    {
                        double precoFechamento = m_deal.Price();  // Obtém o preço do deal (fechamento)
                        double lucroUltimaOperacao = 0.0;
                        
                        lucroUltimaOperacao = ((precoFechamento-precoAberturaOrdem)/5) * Lote;
                        resultadoUltimaOperacao = lucroUltimaOperacao;
                        
                        //Print("LUCRO ANTES...: ", Lucro);
                        
                        //Atualiza o Controle de Lucros
                        Lucro += lucroUltimaOperacao;
                        SaldoAtual = Lucro;
                        
                        if (lucroUltimaOperacao > 10)   TakeAtingido=true;    // Se teve TP em C2, Não Abre Ordem em C3
                        if (lucroUltimaOperacao >= 0)    OrdensVencedoras++;  // Conta Ordens Vencedoras

                        // Atualiza Taxa de Acertividade (%)                           
                        TaxaAcertividade = (OrdensVencedoras/QtdeOperacoes) * 100;

                        
                       // Print("Resultado da Compra = ", lucroUltimaOperacao, 
                       // " | Preço de Abertura = ", precoAberturaOrdem,
                       // " | Preço de Fechamento = ", precoFechamento);
                        
                        //Print("LUCRO DEPOIS...: ", Lucro);
                    }
                }
            }
        }
    }
} // Fim da Função OnTradeTransaction()


//+-------------------------------------------------------------+
//| Função para Fechar Ordens Abertas no Fim do Dia/Pregão      |
//| (Fecha a posição associada ao ticket TicketAberto e exibe   |
//| preços de abertura e fechamento da posição fechada)         |
//+-------------------------------------------------------------+
void FecharOrdemFimDia()
{
   // Obtém o horário atual do servidor
   datetime currentTime = TimeCurrent();
   
   // Converte o datetime para uma estrutura contendo os componentes de data/hora
   MqlDateTime dt;
   TimeToStruct(currentTime, dt);
   
   // Hora de fechamento definida pelo usuário
   int closeHour = HoraFechamentoMercado;   // Exemplo: 17
   int closeMin  = MinutoFechamentoMercado;  // Exemplo: 45
   
   // Se estivermos na última hora do pregão e já tiver passado os minutos definidos
   if((dt.hour == (closeHour - 1)) && (dt.min >= closeMin))
   {
      // Verifica se TicketAberto é válido
      if(TicketAberto > 0)
      {
         // Tenta selecionar a posição ativa associada ao ticket
         if(PositionSelectByTicket(TicketAberto))
         {
            // Obtém o símbolo associado à posição
            string sym = PositionGetString(POSITION_SYMBOL);
            // Tenta fechar a posição utilizando o símbolo obtido
            if(trade.PositionClose(sym))
            {
               Print("FIM DE PREGÃO: Ticket ", TicketAberto, " (símbolo: ", sym, ") Fechado Automaticamente!");
               
               //Pegar Valor de Fechamento Aqui...
               //Ainda não consegui atualizar valores com base neste fechamento (Pentende...)
                             
            }
            else
            {
               Print("FIM DE PREGÃO: Erro ao Fechar a Posição com Ticket ", TicketAberto, ": ", trade.ResultRetcodeDescription());
            }
         }
         else
         {
            //Print("FIM DE PREGÃO: Não foi possível selecionar a posição com ticket ", TicketAberto);
         }
      }
      else
      {
         Print("FIM DE PREGÃO: TicketAberto não é válido.");
      }
   }
} //Fim da Função FecharOrdemFimDia()


Obrigado.

 
O seu tópico foi movido para a secção: Expert Advisors e Negociação Automatizada.
Por favor ter em conta a secção adequada quando criar tópicos — https://www.mql5.com/pt/forum/421109/page6#comment_49385139 
 
Heri PiresOlá! Após criar um EA para operar Mini-Índice, fiz um breve código para calcular o valor de fechamento das ordens. Quando uma ordem atinge o TakeProft (TP) ou StopLoss (SL), está calculando corretamente os valores. Mas como eu programei para ser apenas Day Trade, fiz uma função que ao término do expediente (no horário que o usuário setar em parâmetros), se houver ordens abertas, estas são fechadas. O problema é que quando as ordens são fechadas no fim do expediente, eu não consigo pegar o valor do resultado desta ordem. User a transação "OnTradeTransaction" para este controle. Vou compartilhar o código de OnTradeTransaction e da Função que fecha as ordens no fim do expediente. Por favor, poderiam me ajudar a calcular o  resultado da ordem fechada pela função do fim do expediente? Obrigado.

Olá, segue um exemplo funcional postado por um xará em outro tópico:

Fórum de negociação, sistemas de negociação automatizados e testes de estratégias de negociação

Como calcular o valor de ordens fechadas com PositionClose ?

Vinicius Oliveira, 2021.09.10 13:37

Utilize a função OnTradeTransaction junto a biblioteca DealInfo, a função será chamada cada vez que ocorrer o evento de transação e com a biblioteca você conseguirá ver o resultado da sua operação.


#include    <Trade\DealInfo.mqh> //Biblioteca para o uso do OnTradeTransaction
CDealInfo   m_deal; 

void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result)
  {
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type; //get transaction type as enumeration value
   
    //--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      if(HistoryDealSelect(trans.deal))
         m_deal.Ticket(trans.deal);
      else
         return;
      
      if(m_deal.Magic()==EXPERT_MAGIC && m_deal.Symbol()==_Symbol)
        {
         if(m_deal.DealType() == DEAL_TYPE_BUY || m_deal.DealType()==DEAL_TYPE_SELL)
           {
            if(m_deal.Entry() == DEAL_ENTRY_IN)
              {
               Print("Este bloco será chamado ao abrir uma nova posição");
              }
              
            else if(m_deal.Entry() == DEAL_ENTRY_OUT)
              {
               if(m_deal.DealType()==DEAL_TYPE_BUY)
                 {
                     Print("Este bloco será chamado ao fechar uma posição de compra");
                     double lucroUltimaOperacao = m_deal.Profit();
                     Print("Lucro da última operação = ", lucroUltimaOperacao);
                 }
               else if(m_deal.DealType()==DEAL_TYPE_SELL)
                 {
                     Print("Este bloco será chamado ao fechar uma posição de venda");
                     double lucroUltimaOperacao = m_deal.Profit();
                     Print("Lucro da última operação = ", lucroUltimaOperacao);

                 }  
              }
           }
        }
     }
  } 

 
Vinicius Pereira De Oliveira #:

Olá, segue um exemplo funcional postado por um xará em outro tópico:


Olá!


Muito obrigado... conseguir ter um valor mais exato da operação fechada usando o "m_deal.Profit()" no lugar de "m_deal.Price()". 

Mas ainda não está pegando o valor de fechamento da ordem para quando eu fecho a ordem pela minha função "FecharOrdemFimDia()".

Por favor, teria alguma ideia?


Obrigado.

 
Heri Pires #:

Olá!


Muito obrigado... conseguir ter um valor mais exato da operação fechada usando o "m_deal.Profit()" no lugar de "m_deal.Price()". 

Mas ainda não está pegando o valor de fechamento da ordem para quando eu fecho a ordem pela minha função "FecharOrdemFimDia()".

Por favor, teria alguma ideia?


Obrigado.

m_deal.Price() deve estar pegando sempre o Bid ou o Last. Talvez se tu variar isso pra encerramento de compra pegar o Bid e pra encerramento de venda pegar o Ask deva ficar mais correto.
 
Heri Pires #Olá! Muito obrigado... conseguir ter um valor mais exato da operação fechada usando o "m_deal.Profit()" no lugar de "m_deal.Price()". Mas ainda não está pegando o valor de fechamento da ordem para quando eu fecho a ordem pela minha função "FecharOrdemFimDia()". Por favor, teria alguma ideia? Obrigado.

Opa, você poderia incluir captura de tela (de preferência) dos resultados dessas operações encerradas ao final do dia e dos resultados retornados por OnTradeTransaction(), ou descrevê-los com mais detalhes, para que possamos ter uma melhor noção dessa diferença que está ocorrendo?