//+------------------------------------------------------------------+
//|                                                       MyRobot.mq5|
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.metaquotes.net/|
//+------------------------------------------------------------------+
#include <Trade/Trade.mqh>

input double lotSize = 0.01;          // Lote padrão
double profitTargetPips = 100.0;      // Alvo de lucro em pips
double maxSpreadPips = 100.0;         // Limite máximo de spread para abrir ordens

CTrade trade; // Cria um objeto para operações de trading

// Função para converter pips em pontos
double PipsToPoints(double pips)
{
   return pips * _Point;
}



// Função para obter o spread atual em pips
double GetCurrentSpreadPips()
{
   double spreadPoints;
   if (SymbolInfoDouble(_Symbol, SYMBOL_SPREAD, spreadPoints)) // Chamada corrigida
   {
      return spreadPoints / _Point; // Converte pontos para pips
   }
   else
   {
      Print("Erro ao obter spread: ", GetLastError());
      return 0; // Retorna 0 em caso de erro
   }
}



// Função para definir o alvo de lucro de acordo com o símbolo
void SetProfitTarget(double spreadPips)
{
   if (_Symbol == "EURUSD" || _Symbol == "USDJPY" || _Symbol == "GBPJPY" || 
       _Symbol == "AUDJPY" || _Symbol == "AUDUSD" || _Symbol == "NZDUSD" || 
       _Symbol == "GBPUSD" || _Symbol == "USDCHF" || _Symbol == "USDCAD" || 
       _Symbol == "AUDCAD" || _Symbol == "AUDNZD" || _Symbol == "NZDCAD" || 
       _Symbol == "AUDSGD" || _Symbol == "EURNZD" || _Symbol == "EURCAD")
   {
      profitTargetPips = 10.0 + MathRand() % 11; // Entre 10 e 20 pips
   }
   else if (_Symbol == "NASDAQ" || _Symbol == "US100" || _Symbol == "USATECH" || 
            _Symbol == "US30" || _Symbol == "US500" || _Symbol == "DOW" || 
            _Symbol == "S&P500" || _Symbol == "FTSE100" || _Symbol == "DAX30" || 
            _Symbol == "CAC40" || _Symbol == "NIKKEI" || _Symbol == "ASX200")
   {
      profitTargetPips = 50.0 + MathRand() % 51; // Entre 50 e 100 pips
   }
   else if (_Symbol == "GOLD" || _Symbol == "XAUUSD")
   {
      profitTargetPips = 50.0 + MathRand() % 51; // Entre 50 e 100 pips
   }
   else
   {
      profitTargetPips = 100.0; // Valor padrão para outros ativos
   }

   // Adiciona o spread ao alvo de lucro para compensar o custo do spread
   profitTargetPips += spreadPips;
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Define o alvo de lucro com base no ativo e spread
   double currentSpreadPips = GetCurrentSpreadPips();
   SetProfitTarget(currentSpreadPips);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   //---
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // Calcula as médias móveis e o preço de fechamento
   double sma20 = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE);
   double sma200 = iMA(NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE);
   double closePrice = iClose(NULL, 0, 0);
   double prevClose = iClose(NULL, 0, 1); // Fechamento da vela anterior

   bool positionExists = false;
   ENUM_POSITION_TYPE currentPositionType = POSITION_TYPE_BUY;
   ulong positionTicket = 0;

   // Verifica se existe uma posição aberta para o símbolo atual
   if (PositionSelect(_Symbol))
   {
      positionTicket = PositionGetInteger(POSITION_TICKET);
      currentPositionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      positionExists = true;
   }

   // Debug para acompanhar o estado do robô
   Print("Posição existente: ", positionExists, " Tipo de posição: ", EnumToString(currentPositionType));

   // ** Verifica se o lucro é maior ou igual ao alvo e fecha a posição **
   if (positionExists)
   {
      double positionPrice = PositionGetDouble(POSITION_PRICE_OPEN);
      double currentProfitPips = (currentPositionType == POSITION_TYPE_BUY) ? 
                                 (closePrice - positionPrice) / _Point : 
                                 (positionPrice - closePrice) / _Point;

      if (currentProfitPips >= profitTargetPips)
      {
         if (trade.PositionClose(positionTicket))
         {
            Print("Posição fechada com lucro de ", currentProfitPips, " pips");
            positionExists = false;
         }
         else
         {
            Print("Erro ao fechar posição com lucro: ", trade.ResultRetcode(), " Erro: ", GetLastError());
            return; // Interrompe se houver erro ao fechar
         }
      }
   }

   // ** Fechamento de posição existente antes de abrir nova posição **
   if (positionExists && currentPositionType == POSITION_TYPE_BUY && sma200 > closePrice && closePrice < sma20)
   {
      if (trade.PositionClose(positionTicket))
      {
         Print("Compra fechada por cruzar abaixo da SMA20 com SMA200 acima");
         positionExists = false; // Atualiza estado para permitir nova posição
      }
      else
      {
         Print("Erro ao fechar posição de compra: ", trade.ResultRetcode(), " Erro: ", GetLastError());
         return; // Interrompe se houver erro ao fechar
      }
   }

   if (positionExists && currentPositionType == POSITION_TYPE_SELL && sma200 < closePrice && closePrice > sma20)
   {
      if (trade.PositionClose(positionTicket))
      {
         Print("Venda fechada por cruzar acima da SMA20 com SMA200 abaixo");
         positionExists = false; // Atualiza estado para permitir nova posição
      }
      else
      {
         Print("Erro ao fechar posição de venda: ", trade.ResultRetcode(), " Erro: ", GetLastError());
         return; // Interrompe se houver erro ao fechar
      }
   }

   // ** Obter o spread atual e validar se pode abrir uma nova posição **
   double currentSpreadPips = GetCurrentSpreadPips();
   if (currentSpreadPips > maxSpreadPips)
   {
      Print("Spread atual de ", currentSpreadPips, " pips é muito alto. Ordem não aberta.");
      return; // Não abre a ordem se o spread for maior que o limite
   }

   // ** Abertura de uma nova posição de compra (BUY) **
   if (!positionExists && sma200 < closePrice && closePrice > sma20 && closePrice > prevClose)
   {
      if (trade.Buy(lotSize, NULL, closePrice, 0, 0, "Comprado por cruzar SMA20 com SMA200 abaixo"))
      {
         Print("Compra aberta por cruzar SMA20 com SMA200 abaixo");
      }
      else
      {
         Print("Erro ao abrir posição de compra: ", trade.ResultRetcode(), " Erro: ", GetLastError());
      }
   }

   // ** Abertura de uma nova posição de venda (SELL) **
   if (!positionExists && sma200 > closePrice && closePrice < sma20 && closePrice < prevClose)
   {
      if (trade.Sell(lotSize, NULL, closePrice, 0, 0, "Vendido por cruzar SMA20 com SMA200 acima"))
      {
         Print("Venda aberta por cruzar SMA20 com SMA200 acima");
      }
      else
      {
         Print("Erro ao abrir posição de venda: ", trade.ResultRetcode(), " Erro: ", GetLastError());
      }
   }
}
//+------------------------------------------------------------------+


errors:

'HTF_Medias_Fecha_Lucro_Pips_Setup_003_arrumar_02.mq5'			1
Trade.mqh			
Object.mqh			
StdLibErr.mqh			
OrderInfo.mqh			
HistoryOrderInfo.mqh			
PositionInfo.mqh			
DealInfo.mqh			
'SymbolInfoDouble' - no one of the overloads can be applied to the function call	HTF_Medias_Fecha_Lucro_Pips_Setup_003_arrumar_02.mq5	26	8
could be one of 2 function(s)	HTF_Medias_Fecha_Lucro_Pips_Setup_003_arrumar_02.mq5	26	8
   built-in: double SymbolInfoDouble(const string,ENUM_SYMBOL_INFO_DOUBLE)	HTF_Medias_Fecha_Lucro_Pips_Setup_003_arrumar_02.mq5	26	8
   built-in: bool SymbolInfoDouble(const string,ENUM_SYMBOL_INFO_DOUBLE,double&)	HTF_Medias_Fecha_Lucro_Pips_Setup_003_arrumar_02.mq5	26	8
possible use of uninitialized variable 'spreadPoints'	HTF_Medias_Fecha_Lucro_Pips_Setup_003_arrumar_02.mq5	28	14
1 errors, 1 warnings		2	2