OnTradeTransaction Wrong Volume

 
Hello, I developed an EA (account Netting) which uses pending orders  SellLimit and BuyLimit  instead of MT5 native TakeProfit. The reason for this was to avoid the slippage that occurs when using MT5's TP and SP, since they close market positions and not with book orders.

EA Places Orders BuyLimit and SellLimit on the chart to enter the operation and when one of these orders is executed it places a reverse order (BuyLimit or SellLimit) to exit the operation, functioning as a TakeProfit. When this exit order is executed, it replaces the entry order in the same place as before and with the same volume of contracts.

It turns out that I used the function OnTradeTransaction for this manipulation of orders and everything happens correctly on a DEMO account and on a REAL account with 1 volume contract.

The problem occurs when I try to use more than 1 volume contract on the REAL account. The EA executes an entry order with 4 contracts and sometimes places an exit order with only 3 contracts, or sometimes it places the exit with the correct number of contracts, but when it is executed the entry order is replaced. ends up having fewer contracts.

My suspicion is that there may be an error in the way I am using the enum DEAL_VOLUME, however I was unable to identify what the logic error would be.

Important points: 1- The bug always occurs with a smaller number of contracts, it never happened to add more contracts.
2- The bug does not occur on Demo accounts and on   Strategy Tester s.
3- In the real account, sometimes the correct number of contracts is placed and sometimes the bug occurs.
4- If you use the EA for a long time, the bug will always occur, decreasing contracts until one hour remains just 1 contract.

Below is the OnTradeTransaction code (The rest of the EA code has no connection with this function)

//+-------------------------------------------------------------------------+
//| RECOLOCA A ORDEM EM CASO DE OPERAÇÃO COM LUCRO    |
//+-------------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{
//--- get transaction type as enumeration value 
   ENUM_TRADE_TRANSACTION_TYPE type = trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD && closePosition==false) // Se closePosition == True, não precisa abrir novas ordens 
     {
      long     deal_entry        =0;
      string   deal_symbol       ="";
      long     deal_type         =0;
      double   deal_volume       =0;
      double   deal_price        =0;
      
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry  = HistoryDealGetInteger(trans.deal,DEAL_ENTRY);         
         deal_symbol = HistoryDealGetString (trans.deal,DEAL_SYMBOL);
         deal_type   = HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_volume = HistoryDealGetDouble (trans.deal,DEAL_VOLUME);
         deal_price  = HistoryDealGetDouble (trans.deal,DEAL_PRICE);         
        }
      else 
         return;
         
          
       if(deal_symbol==Symbol())
       {                

         //RECOLOCAÇÃO DE ORDENS ACIMA DA ABERTURA                      
            if(preco.last>=value_open)
            {
               //-- Recoloca a ordem de venda 
               if(deal_entry==DEAL_ENTRY_OUT && deal_type==DEAL_TYPE_BUY)
               {
                 trade.SellLimit(deal_volume,deal_price+take*Point(),_Symbol,0,0,0,0,"Venda Recolocada");       
                 Print("■ Venda Recolocada - Contratos = ", deal_volume, " - Preço ",deal_price+take*Point());
               }
                     //Recoloca Saida da Venda
                     if(deal_entry==DEAL_ENTRY_IN && deal_type==DEAL_TYPE_SELL)
                      {
                       trade.BuyLimit(deal_volume,deal_price-take*Point(),_Symbol,0,0,0,0,"Saida da Venda");    // Saida da Venda 
                       Print("■ Gain da venda colocado no preço : ",deal_price-take*Point());
                      }                                             
            }
         //RECOLOCAÇÃO DE ORDENS ABAIXO DA ABERTURA            
            if(preco.last<value_open)
            {        
               //-- Recolca a ordem de compra
               if(deal_entry==DEAL_ENTRY_OUT && deal_type==DEAL_TYPE_SELL)
               {
                 trade.BuyLimit(deal_volume,deal_price-take*Point(),_Symbol,0,0,0,0,"Compra Recolocada");
                 Print("■ Compra Recolocada - Contratos = ",deal_volume, " - Preço ",deal_price-take*Point());
               } 
                     //Recoloca Saida da Compra
                    if(deal_entry==DEAL_ENTRY_IN && deal_type==DEAL_TYPE_BUY)
                      {               
                       trade.SellLimit(deal_volume,deal_price+take*Point(),_Symbol,0,0,0,0,"Saida da Compra");   // Saida da Compra
                       Print("■ Gain da compra colocado no preço : ",deal_price+take*Point());
                      }
            }
      }
}

Documentação sobre MQL5: Elementos Básicos da Linguagem / Funções / Funções de Manipulação de Evento
Documentação sobre MQL5: Elementos Básicos da Linguagem / Funções / Funções de Manipulação de Evento
  • www.mql5.com
Funções de Manipulação de Evento - Funções - Elementos Básicos da Linguagem - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
 

An order volume, a deal volume and a position volume are 3 different things. You need to deal with that on a real account when opening a position greater than the minimum.

As an order of 4 for example can result in 1 deal (4 or even possibly 3 only) or 2 deals (1+3 or 2+2...), 3 deals...or 4 deals.

 
Alain Verleyen # :

An order volume, a deal volume and a position volume are 3 different things. You need to deal with that on a real account when opening a position greater than the minimum.

As an order of 4 for example can result in 1 deal (4 or even possibly 3 only) or 2 deals (1+3 or 2+2...), 3 deals...or 4 deals.

Ok. So, from what I understand, the error is that I am using DEAL_VOLUME and instead I should look for the value of the volume of the executed order and not of the deal carried out, perhaps using HistoryOrderGetDouble.

Anyway, thanks for the help. It was enough to give me a path to fix.