Duplicated Orders - EA - MQL5

 

Hello, 


I have the following code which is duplicating my orders, I create a Rule 

//+------------------------------------------------------------------+
//|                                                        Teste.mq5 |
//|                                                      Felipe Sena |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Felipe Sena"
#property link      ""
#property version   "1.00"

//+------------------------------------------------------------------+
//| INCLUDES                                                        |
//+------------------------------------------------------------------+

#include  <Trade\Trade.mqh>
CTrade         trade;    

//+------------------------------------------------------------------+
//| INPUTS                                                           |
//+------------------------------------------------------------------+

input int var_lote = 1; // Lotes

input int var_periodoMedia = 9;

input float var_variacaoMedia = 50.0;

input float tp_buy = 250.0; // Gain em Operações de Compra.
input float tp_sell = 250.0; // Gain em Operações de Venda.

input float sl_buy = 300.0; // Loss em Operações de Compra.
input float sl_sell = 300.0; // Loss em Operações de Venda.

input string var_horario_Inicio = "09:10"; // Hora Inicio
input string var_horario_limite = "17:30"; // Hora Fim
input string var_encerraPosicao = "17:40"; // Encerrar Posições

string CurrentTime;
bool TradingIsAllowed=false;
bool EncerrarPosicao=false;

bool fezParcial=false;
bool fezBreakEven=false;

bool CheckTradingTime()
   {
      if(StringSubstr(CurrentTime,0,5) == var_horario_Inicio)
         TradingIsAllowed=true;
         EncerrarPosicao=false;
   
      if(StringSubstr(CurrentTime,0,5) == var_horario_limite)
         TradingIsAllowed=false;
     
      return
         TradingIsAllowed;
         //EncerrarPosicao;
   }
   
bool  CheckEncerrarPosicao()
   {
      if(StringSubstr(CurrentTime,0,5) == var_encerraPosicao)
         EncerrarPosicao=true;
     
      return
         EncerrarPosicao;
   }  


//  GLOBAIS  ////////////////////////////////////////////////////////////////

int mediaHandle = INVALID_HANDLE;
double media[];
double high[];
double low[];
MqlRates PriceInformation[];

////////////////////////////////////////////////////////////////////////////

int OnInit()
  {
      ArraySetAsSeries(media, true);
      mediaHandle = iMA(_Symbol,_Period,var_periodoMedia,0,MODE_EMA,PRICE_CLOSE);
      return(INIT_SUCCEEDED);
  }

////////////////////////////////////////////////////////////////////////////

void OnTick() //| Inicio On Tick
  {
 
     //| OBTER DADOS                                                      
     int copy = CopyBuffer(mediaHandle,0,0,7,media);
     int data = CopyRates(_Symbol,_Period,0,Bars(_Symbol,_Period),PriceInformation);
     
     double preco = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   
     bool sinalCompra = false;
     bool sinalVenda = false;
     
     double BarHigh0=iHigh(Symbol(),NULL,0);
     double BarHigh1=iHigh(Symbol(),NULL,1);
     double BarHigh2=iHigh(Symbol(),NULL,2);
     double BarHigh3=iHigh(Symbol(),NULL,3);
     double BarHigh4=iHigh(Symbol(),NULL,4);
     double BarHigh5=iHigh(Symbol(),NULL,5);
     double BarHigh6=iHigh(Symbol(),NULL,6);
     
     double BarLow0=iLow(Symbol(),NULL,0);
     double BarLow1=iLow(Symbol(),NULL,1);
     double BarLow2=iLow(Symbol(),NULL,2);
     double BarLow3=iLow(Symbol(),NULL,3);
     double BarLow4=iLow(Symbol(),NULL,4);
     double BarLow5=iLow(Symbol(),NULL,5);
     double BarLow6=iLow(Symbol(),NULL,6);
     
     double BarClose0=iClose(Symbol(),NULL,0);  

     datetime time = TimeLocal();
     
     CurrentTime = TimeToString(time,TIME_MINUTES);
     
     double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
     double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
     
     // LOGICA SINAIS DE COMPRA E VENDA
   
     if (copy==7 && CheckTradingTime()==true)
        {
         if
            (
               BarClose0 <= (media[0] + var_variacaoMedia)
               && BarClose0 > (media[0] - 20)
               && BarLow1 > media[1]
             )
            {
               sinalCompra = true;
            }
           
         if
            (
               BarClose0 >= (media[0] - var_variacaoMedia)
               && BarClose0 < (media[0] + 20)
               && BarHigh1 < media[1]
            )
            {
               sinalVenda = true;
            }  
        }
     
     
     //| VERIFICAR SE ESTOU POSICIONADO                                  
         
       bool comprado = false;
       bool vendido = false;
       
       if(PositionSelect(_Symbol))
         {
            if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
               {
                  comprado = true;
               }
         
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
               {
                  vendido = true;
               }
         }  
     
     
     
     //| LOGICA DE ROTEAMENTO                                            
     
     if(!comprado && !vendido)
        {
           if(sinalCompra && !comprado)
              {
                  trade.Buy(var_lote,_Symbol,Bid,(Bid - sl_buy+ var_variacaoMedia),(Bid + tp_buy + var_variacaoMedia),"Compra a Mercado");
              }
           
           
           if(sinalVenda && !vendido)
              {
                  trade.Sell(var_lote,_Symbol,Ask,(Ask + sl_sell - var_variacaoMedia),(Ask-tp_sell - var_variacaoMedia),"Venda a Mercado");
              }
        }
     
       
     else
        {
           if(comprado)
               {
                  if(sinalVenda && !vendido)
                     {
                        trade.Sell(var_lote*2,_Symbol,Ask,(Ask+ sl_sell - var_variacaoMedia),(Ask-tp_sell - var_variacaoMedia),"Virada de mão (compra->venda)");
                     }
               }
           
           else if (vendido)
            {
               if(sinalCompra && !comprado)
                  {
                     trade.Buy(var_lote*2,_Symbol,Bid,(Bid - sl_buy + var_variacaoMedia),(Bid + tp_buy + var_variacaoMedia),"Virada de mão (venda->compra)");
                  }
           
            }
        }
         
     
     //| ENCERRAR POSIÇÃO
     
     if(comprado && CheckEncerrarPosicao()==true)
         {
            trade.Sell(var_lote,_Symbol,Ask,0,(Ask * _Point),"Encerrar Posição");
         }
         
     if(vendido && CheckEncerrarPosicao()==true)
         {
            trade.Buy(var_lote,_Symbol,Ask,0,(Ask * _Point),"Encerrar Posição");
         }    
       
     } //| Fim On Tick


I create the following rule to avoid it, but it keeps duplicating sometimes. not always. 


     //| VERIFICAR SE ESTOU POSICIONADO                                  
         
       bool comprado = false;
       bool vendido = false;
       
       if(PositionSelect(_Symbol))
         {
            if (PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
               {
                  comprado = true;
               }
         
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
               {
                  vendido = true;
               }
         }  
     
     
     
     //| LOGICA DE ROTEAMENTO                                            
     
     if(!comprado && !vendido)
        {
           if(sinalCompra && !comprado)
              {
                  trade.Buy(var_lote,_Symbol,Bid,(Bid - sl_buy+ var_variacaoMedia),(Bid + tp_buy + var_variacaoMedia),"Compra a Mercado");
              }
           
           
           if(sinalVenda && !vendido)
              {
                  trade.Sell(var_lote,_Symbol,Ask,(Ask + sl_sell - var_variacaoMedia),(Ask-tp_sell - var_variacaoMedia),"Venda a Mercado");
              }
        }
     
       
     else
        {
           if(comprado)
               {
                  if(sinalVenda && !vendido)
                     {
                        trade.Sell(var_lote*2,_Symbol,Ask,(Ask+ sl_sell - var_variacaoMedia),(Ask-tp_sell - var_variacaoMedia),"Virada de mão (compra->venda)");
                     }
               }
           
           else if (vendido)
            {
               if(sinalCompra && !comprado)
                  {
                     trade.Buy(var_lote*2,_Symbol,Bid,(Bid - sl_buy + var_variacaoMedia),(Bid + tp_buy + var_variacaoMedia),"Virada de mão (venda->compra)");
                  }
           
            }
        }


I don't understand why it's duplicating the orders. 

 
You have to know that with mql5, you can get a new tick while your "current" order is not yet processed. So your "comprado" and "vendido" can be false while you have an order still in processing on the server (or on the wire).