E.A. trigger StopLoss with wrong value

 

Hi!


I'm trying to develop an E.A. but when the price trigger the StopLoss it execute with the wrong value (one tick below when it's a buy).


I appreciate any help.

Files:
11.JPG  177 kb
22.JPG  171 kb
33.JPG  222 kb
 
Bruno Manhães Siqueira: I appreciate any help.
Do you really expect an answer? We can't see your broken code. There are no mind readers here and our crystal balls are cracked.
 
whroeder1:
Do you really expect an answer? We can't see your broken code. There are no mind readers here and our crystal balls are cracked.
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   ShowInfo_Text="";

   if(!RefreshRates())
      return;

   if(!iGetArray(envelope_indicator_handle,0,0,10,upper_band_array) || 
      !iGetArray(envelope_indicator_handle,1,0,10,lower_band_array) || 
      !iGetArray(moving_average_indicator_handle,0,0,10,moving_average_array))
     {
      DebugBreak();
      return;
     }

   if(HoraFechamento())
     {
      FechaPosicao();
     }

   isThereOpenedPosition=isThereOpenedPosition();
   isNegotiationTime=isNegotiationTime();

   if(getNumberOfPendingOrders()>0 && !isThereOpenedPosition()) //Se tiver uma ordem pendente e se não estiver posicionado, significa que tomou um SL e deve ser encerrada a ordem pendente
     {
      cancelPendingOrders();
     }

   if(isNegotiationTime)
     {
      weReachMinimalVolumeToOpenPosition=weReachMinimalVolumeToOpenPosition();
      weHaveOperatedInThisBar=weHaveOperatedInThisBar();

      if(weReachMinimalVolumeToOpenPosition && !weHaveOperatedInThisBar)
        {
         if(SemOrdem() && SemPosicao())
           {
            bool Buy_Condition_1=(m_symbol.Ask()<=lower_band_array[0]);
            bool Sell_Condition_1=(m_symbol.Bid()>=upper_band_array[0]);

            if(Buy_Condition_1)
              {
               Compra();
              }
            else if(Sell_Condition_1)
              {
               Vende();
              }
           }
        }
     }

//ShowInfo(getBalanceInfo());

   return;
  }
//+------------------------------------------------------------------+
//| Entra comprado                                                   |
//+------------------------------------------------------------------+
void Compra()
  {
   PRC = m_symbol.Ask();
   STL = m_symbol.NormalizePrice(PRC - operation_stop_loss);
   TKP = m_symbol.NormalizePrice(PRC + operation_take_profit);
   double STL_2=m_symbol.NormalizePrice(PRC -(2*operation_stop_loss));

   if(m_trade.Buy(operation_volume,my_symbol,PRC,STL_2,NULL,__FILE__+", "+DoubleToString(PRC,3)+" / "+DoubleToString(STL,3)))
     {
      CopyTime(my_symbol,my_timeframe,0,1,lastOperationCandleTime);
      Print("Ordem de Compra - Sem falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());

      //Ordem na direção contrária para definir o TakeProfit no preço desejado
      if(m_trade.SellLimit(operation_volume,TKP,my_symbol,NULL,NULL,ORDER_TIME_GTC,0,__FILE__+" TakeProfit "+DoubleToString(TKP,3)))
        {
         Print("Ordem de Venda (TakeProfit) - Sem falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
        }
      else
        {
         Print("Ordem de Venda (TakeProfit) - Com falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
        }

      //Ordem para modificar o stop loss da ordem de compra
      if(PositionSelect(my_symbol))
        {
         long ticket=PositionGetInteger(POSITION_TICKET);
         if(m_trade.PositionModify(ticket,STL,NULL))
           {
            Print("Modificação do StopLoss da Ordem de Compra - Sem falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
           }
         else
           {
            Print("Modificação do StopLoss da Ordem de Compra - Com falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
           }
        }
     }
   else
     {
      Print("Ordem de Compra - Com falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
     }
  }
//+------------------------------------------------------------------+
//| Entra vendido                                                    |
//+------------------------------------------------------------------+
void Vende()
  {
   PRC = m_symbol.Bid();
   STL = m_symbol.NormalizePrice(PRC + operation_stop_loss);
   TKP = m_symbol.NormalizePrice(PRC - operation_take_profit - m_symbol.TickSize());
   double STL_2=m_symbol.NormalizePrice(PRC+(2*operation_stop_loss));

   if(m_trade.Sell(operation_volume,my_symbol,PRC,STL,TKP,"Entrou vendido"))
     {
      CopyTime(my_symbol,my_timeframe,0,1,lastOperationCandleTime);
      Print("Ordem de Venda - Sem falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());

      //Ordem na direção contrária para definir o TakeProfit no preço desejado
      if(m_trade.BuyLimit(operation_volume,TKP,my_symbol,NULL,NULL,ORDER_TIME_GTC,0,__FILE__+" TakeProfit "+DoubleToString(TKP,3)))
        {
         Print("Ordem de Compra (TakeProfit) - Sem falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
        }
      else
        {
         Print("Ordem de Compra (TakeProfit) - Com falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
        }

      //Ordem para modificar o stop loss da ordem de venda
      if(PositionSelect(my_symbol))
        {
         long ticket=PositionGetInteger(POSITION_TICKET);
         if(m_trade.PositionModify(ticket,STL,NULL))
           {
            Print("Modificação do StopLoss da Ordem de Venda - Sem falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
           }
         else
           {
            Print("Modificação do StopLoss da Ordem de Venda - Com falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
           }
        }
     }
   else
     {
      Print("Ordem de Venda - Com falha. ResultCode: ",m_trade.ResultRetcode(),", RetCodeDescription: ",m_trade.ResultRetcodeDescription());
     }
  }
//+------------------------------------------------------------------+
//| Cancela as ordens pendentes                                      |
//+------------------------------------------------------------------+
void cancelPendingOrders()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong ticket=OrderGetTicket(i);
      string comment=OrderGetString(ORDER_COMMENT);

      if(OrderSelect(ticket) && OrderGetString(ORDER_SYMBOL)==my_symbol && OrderGetInteger(ORDER_MAGIC)==my_magic)
        {
         if(StringFind(comment,"TakeProfit",0)>=0)
           {
            m_trade.OrderDelete(ticket);
            CopyTime(my_symbol,my_timeframe,0,1,lastOperationCandleTime);
            Print("Excluindo ordem #",ticket," / Comment: "+comment);
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ulong getTicket()
  {
   ulong    ticket=0;
   double   open_price;
   double   initial_volume;
   datetime time_setup;
   string   symbol;
   string   type;
   long     order_magic;
   long     positionID;

   uint total=OrdersTotal();
   for(uint i=0;i<total;i++)
     {
      if((ticket=OrderGetTicket(i))>0)
        {
         open_price     = OrderGetDouble(ORDER_PRICE_OPEN);
         time_setup     = (datetime)OrderGetInteger(ORDER_TIME_SETUP);
         symbol         = OrderGetString(ORDER_SYMBOL);
         order_magic    = OrderGetInteger(ORDER_MAGIC);
         positionID     = OrderGetInteger(ORDER_POSITION_ID);
         initial_volume = OrderGetDouble(ORDER_VOLUME_INITIAL);
         type           = EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE)));
        }
     }

   return ticket;
  }
//+------------------------------------------------------------------+
//| Verifica se possui volume mínimo para abrir posição              |
//+------------------------------------------------------------------+
bool weReachMinimalVolumeToOpenPosition()
  {
   bool ret=false;

   ret=((minimal_volume_to_operate==0) || (m_symbol.Volume()>=minimal_volume_to_operate));

   return ret;
  }
//+------------------------------------------------------------------+
//| Verifica se já realizou uma operação na barra atual              |
//+------------------------------------------------------------------+
bool weHaveOperatedInThisBar()
  {
   bool ret=false;
   datetime New_Time[1];

   int copied=CopyTime(my_symbol,my_timeframe,0,1,New_Time);

   if(copied>0)
     {
      if(lastOperationCandleTime[0]==New_Time[0])
        {
         ret=true;
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      ret=false;
     }

   return ret;
  }
//+------------------------------------------------------------------+
//| Verifica se temos uma nova barra (Candle)                        |
//+------------------------------------------------------------------+
bool isNewBar()
  {
   bool ret=false;
   datetime New_Time[1];

   int copied=CopyTime(my_symbol,my_timeframe,0,1,New_Time); //Copying the last bar time to the element New_Time[0]

   if(copied>0)
     {
      if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
        {
         ret=true;
         Old_Time=New_Time[0]; // saving bar time
        }
     }
   else
     {
      Alert("Error in copying historical times data, error =",GetLastError());
      ResetLastError();
      ret=false;
     }

   return ret;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool EhBarraNova()
  {
   if(BARS!=Bars(my_symbol,my_timeframe))
     {
      BARS=Bars(my_symbol,my_timeframe);
      return(true);
     }
   return(false);
  }
//+------------------------------------------------------------------+
//| Verifica se há ordem aberta                                      |
//+------------------------------------------------------------------+
bool SemOrdem()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      OrderGetTicket(i);
      if((OrderGetString(ORDER_SYMBOL)==my_symbol) && (OrderGetInteger(ORDER_MAGIC)==my_magic))
         return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//| Verifica se há posição aberta                                   |
//+------------------------------------------------------------------+
bool SemPosicao()
  {
   bool resultado=!PositionSelect(my_symbol);
   return resultado;
  }
//+------------------------------------------------------------------+
//| Get the position count for the specified symbol                  |
//+------------------------------------------------------------------+
int getPositionCount(string aSymbol)
  {
   int positionCount=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      string symbol=PositionGetSymbol(i);

      if(aSymbol==Symbol())
        {
         positionCount++;
        }
     }

   return positionCount;
  }
//+------------------------------------------------------------------+
//| Retorna o tipo de posição aberta (Comprado ou Vendido)           |
//+------------------------------------------------------------------+
string openedPositionType()
  {
   string ret="---";

   if(PositionSelect(my_symbol)==true) //TODO: Verificar o magic number além do símbolo
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         ret="COMPRADO";
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         ret="VENDIDO";
        }
     }

   return ret;
  }
//+------------------------------------------------------------------+
//| Verifica se existe posição aberta                                |
//+------------------------------------------------------------------+
bool isThereOpenedPosition()
  {
   bool ret=false;

   for(int i=PositionsTotal()-1; i<=0; i++)
     {
      string symbol=PositionGetSymbol(i);
      ulong magic=PositionGetInteger(POSITION_MAGIC);
      if(symbol==my_symbol && magic==my_magic)
        {
         ret=true;
         break;
        }
     }

   return ret;
  }
//+------------------------------------------------------------------+
//| Verifica se existe ordem pendente                                |
//+------------------------------------------------------------------+
bool isTherePendingOrder() //TODO: Verificar se essa função está funcionando, não pode haver tentativa de uma segunda ordem caso existe ordem aberta
  {

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong ticket=OrderGetTicket(i);
      string symbol=OrderGetString(ORDER_SYMBOL);
      ulong magic=OrderGetInteger(ORDER_MAGIC);
      if(symbol==my_symbol && magic==my_magic)
        {
         return true;
         break;
        }
     }

   return false;
  }
//+------------------------------------------------------------------+
//| Retorna a quantidade de orden pendentes                          |
//+------------------------------------------------------------------+
int getNumberOfPendingOrders()
  {
   int pendingOrders=0;

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong ticket=OrderGetTicket(i);
      string symbol=OrderGetString(ORDER_SYMBOL);
      ulong magic=OrderGetInteger(ORDER_MAGIC);
      if(symbol==my_symbol && magic==my_magic)
        {
         pendingOrders++;
        }
     }

   return pendingOrders;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Verifica se já passou do horário para fechar as operações        |
//+------------------------------------------------------------------+
bool HoraFechamento()
  {
   TimeToStruct(TimeCurrent(),horaAtual);

   if(horaAtual.hour>=my_operation_close_operations_time.hour)
     {
      if(horaAtual.hour==my_operation_close_operations_time.hour)
        {
         if(horaAtual.min>=my_operation_close_operations_time.min)
           {
            return true;
           }
         else
           {
            return false;
           }
        }
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void FechaPosicao()
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      string symbol=PositionGetSymbol(i);
      ulong magic=PositionGetInteger(POSITION_MAGIC);
      if(symbol==my_symbol && magic==my_magic)
        {
         ulong PositionTicket=PositionGetInteger(POSITION_TICKET);
         if(m_trade.PositionClose(PositionTicket,my_deviation_points))
           {
            Print("Posição fechada por limite de horário de operação - sem falha. ResultRetcode: ",m_trade.ResultRetcode(),", RetcodeDescription: ",m_trade.ResultRetcodeDescription());
           }
         else
           {
            Print("Posição fechada por limite de horário de operação - com falha. ResultRetcode: ",m_trade.ResultRetcode(),", RetcodeDescription: ",m_trade.ResultRetcodeDescription());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Verifica se está dentro do horário de negociação                 |
//+------------------------------------------------------------------+
bool isNegotiationTime()
  {
   TimeToStruct(TimeCurrent(),horaAtual);
   if(horaAtual.hour>=my_operation_start_time.hour && horaAtual.hour<=my_operation_end_time.hour)
     {
      if(horaAtual.hour==my_operation_start_time.hour)
        {
         if(horaAtual.min>=my_operation_start_time.min)
           {
            return true;
           }
         else
           {
            return false;
           }
        }
      if(horaAtual.hour==my_operation_end_time.hour)
        {
         if(horaAtual.min<=my_operation_end_time.min)
           {
            return true;
           }
         else
           {
            return false;
           }
        }
      return true;
     }
   return false;
  }


Sorry!

 
   PRC = m_symbol.Ask();
   STL = m_symbol.NormalizePrice(PRC - operation_stop_loss);
   TKP = m_symbol.NormalizePrice(PRC + operation_take_profit);
You buy at the Ask and sell at the Bid.
  • Your buy order's TP/SL are triggered when the Bid reaches it. Not the Ask.
  • Your sell order's TP/SL will be triggered when the Ask reaches it. To trigger at a specific Bid price, add the average spread.
              MODE_SPREAD (Paul) - MQL4 and MetaTrader 4 - MQL4 programming forum - Page 3
  • The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools -> Options {control-O} -> charts -> Show ask line.)
 
whroeder1:
You buy at the Ask and sell at the Bid.
  • Your buy order's TP/SL are triggered when the Bid reaches it. Not the Ask.
  • Your sell order's TP/SL will be triggered when the Ask reaches it. To trigger at a specific Bid price, add the average spread.
              MODE_SPREAD (Paul) - MQL4 and MetaTrader 4 - MQL4 programming forum - Page 3
  • The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools -> Options {control-O} -> charts -> Show ask line.)

Thanks a lot whroeder1!

I'll do this.

Regards!

Reason: