//+------------------------------------------------------------------+
//|                                                     EMA_Cross.mq5|
//|                        Generated by ChatGPT                      |
//+------------------------------------------------------------------+
input double TakeProfit = 20;        // TakeProfit em pips
input double StopLoss = 400;         // StopLoss em pips
input int TrailingStop = 10;         // Trailing Stop em pips
input int MagicNumber = 12345;       // Número mágico para identificar as ordens

// Definição dos períodos das médias
input int MA200Period = 200;         // Período da média móvel simples
input int EMA20Period = 20;          // Período da média móvel exponencial 20
input int EMA10Period = 10;          // Período da média móvel exponencial 10

double ma200, ema20, ema10;
double point;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   point = MarketInfo(Symbol(), MODE_POINT);
   return(INIT_SUCCEEDED);
  }

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

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   ma200 = iMA(Symbol(), 0, MA200Period, 0, MODE_SMA, PRICE_CLOSE, 0);
   ema20 = iMA(Symbol(), 0, EMA20Period, 0, MODE_EMA, PRICE_CLOSE, 0);
   ema10 = iMA(Symbol(), 0, EMA10Period, 0, MODE_EMA, PRICE_CLOSE, 0);

   double price = Close[0];

   // Regra 1 - Abertura de Compra
   if(CheckConditionForBuy())
     {
      CloseSellOrders(); // Fechar ordens de venda se existir
      if(!ExistOpenBuyOrder()) // Garantir que não há ordens de compra abertas
        {
         OpenBuyOrder();
        }
     }

   // Regra 2 - Abertura de Venda
   if(CheckConditionForSell())
     {
      CloseBuyOrders(); // Fechar ordens de compra se existir
      if(!ExistOpenSellOrder()) // Garantir que não há ordens de venda abertas
        {
         OpenSellOrder();
        }
     }

   // Aplicar trailing stop
   ApplyTrailingStop();
  }

//+------------------------------------------------------------------+
//| Função para verificar as condições de compra                     |
//+------------------------------------------------------------------+
bool CheckConditionForBuy()
  {
   if(ema20 > ma200 && Close[1] > ma200 && Close[2] > ma200) // Regra para 2 velas fechadas acima da MA200
     {
      if(AngleCheck(EMA10Period, 45)) // Verificar inclinação da EMA10
        return(true);
     }
   return(false);
  }

//+------------------------------------------------------------------+
//| Função para verificar as condições de venda                      |
//+------------------------------------------------------------------+
bool CheckConditionForSell()
  {
   if(ema20 < ma200 && Close[1] < ma200 && Close[2] < ma200) // Regra para 2 velas fechadas abaixo da MA200
     {
      if(AngleCheck(EMA10Period, -45)) // Verificar inclinação da EMA10
        return(true);
     }
   return(false);
  }

//+------------------------------------------------------------------+
//| Verificar inclinação da média móvel                              |
//+------------------------------------------------------------------+
bool AngleCheck(int period, double angle)
  {
   double ma_now = iMA(Symbol(), 0, period, 0, MODE_EMA, PRICE_CLOSE, 0);
   double ma_previous = iMA(Symbol(), 0, period, 0, MODE_EMA, PRICE_CLOSE, 1);
   double slope = (ma_now - ma_previous) / point;

   return(MathAbs(slope) >= angle);
  }

//+------------------------------------------------------------------+
//| Abrir ordem de compra                                             |
//+------------------------------------------------------------------+
void OpenBuyOrder()
  {
   double price = Ask;
   double sl = price - StopLoss * point;
   double tp = price + TakeProfit * point;

   OrderSend(Symbol(), OP_BUY, 0.1, price, 3, sl, tp, "Buy Order", MagicNumber, 0, Green);
  }

//+------------------------------------------------------------------+
//| Abrir ordem de venda                                              |
//+------------------------------------------------------------------+
void OpenSellOrder()
  {
   double price = Bid;
   double sl = price + StopLoss * point;
   double tp = price - TakeProfit * point;

   OrderSend(Symbol(), OP_SELL, 0.1, price, 3, sl, tp, "Sell Order", MagicNumber, 0, Red);
  }

//+------------------------------------------------------------------+
//| Fechar ordens de compra                                           |
//+------------------------------------------------------------------+
void CloseBuyOrders()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderType() == OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
         OrderClose(OrderTicket(), OrderLots(), Bid, 3, Red);
        }
     }
  }

//+------------------------------------------------------------------+
//| Fechar ordens de venda                                            |
//+------------------------------------------------------------------+
void CloseSellOrders()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderType() == OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
         OrderClose(OrderTicket(), OrderLots(), Ask, 3, Green);
        }
     }
  }

//+------------------------------------------------------------------+
//| Verificar se há ordens de compra abertas                         |
//+------------------------------------------------------------------+
bool ExistOpenBuyOrder()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderType() == OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
         return(true);
        }
     }
   return(false);
  }

//+------------------------------------------------------------------+
//| Verificar se há ordens de venda abertas                          |
//+------------------------------------------------------------------+
bool ExistOpenSellOrder()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderType() == OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
         return(true);
        }
     }
   return(false);
  }

//+------------------------------------------------------------------+
//| Aplicar trailing stop nas ordens                                 |
//+------------------------------------------------------------------+
void ApplyTrailingStop()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
        {
         double new_sl;
         if(OrderType() == OP_BUY)
           {
            new_sl = Bid - TrailingStop * point;
            if(new_sl > OrderStopLoss())
              OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, Blue);
           }
         else if(OrderType() == OP_SELL)
           {
            new_sl = Ask + TrailingStop * point;
            if(new_sl < OrderStopLoss())
              OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, Blue);
           }
        }
     }
  }



preciso que o codigo acim siga essas regras abaixo:


crie um EA MQL5 Baseado em cruzamento de medias e preço seguindo as seguinte regras:

O robo precisa ter a media de 200 simples e uma media de 20 exponencial e uma media de 10 exponencial.

Regra 1 para abertura de ordem de Compra:

Caso exista alguma ordem de venda aberta precisa ser fechada. 
Assim que a media de 20 precisa cruzar acima da media de 200 simples e o preço precisa cruzar acima da media de 200 simples e fechar  pelos menos 2 velas de compra acima da media de 200. 



Regra 2 para abertura de ordem de Venda:

Caso exista alguma ordem de compra aberta precisa ser fechada. 
Assim que a media de 20 precisa cruzar abaixo da media de 200 simples e o preço precisa cruzar abaixo da media de 200 simples e fechar  pelos menos 2 velas de venda abaixo da media de 200. 


Regra3
A cada avanço do preço o robo precisa pegar pelo menos 20pips de takeprofit precisa ter trailingstops para proteção caso preço retorno e tambem um stop loss de pelo menos 400 pips en caso de grande queda para evitar grandes percas 


Regra4:

o robo precisa sempre comprar ou vender sempre tambem somente quando a media de 10 estiver com uma inclinação de 45 graus tambem seja para venda quanto para compra, e caso o preço começar a lateralizar fazendo tipo de acumulação o robo precisa parar de executar ordens  de venda ou de compra. 
trailingstop precisa ficar no final da minima da ultima vela que acabou anteriormente enquanto o preço trabalha na proxima vela de fechar e ir a companhnado o preço sempre que ele vai avançando mas respeitndo esse limite