#include <Trade\Trade.
mqh>
// Entradas del usuario
input int FastMA_Period = 100;
input int SlowMA_Period = 200;
static input long InpMagicNumber = 546812;
input int RSI_Period = 8;
input double RSI_Level = 30.0;
input double LotSize = 0.05;
input int InputSL = 100000;
input int InputTP = 100000;
input bool ImpCloseSignal = false;
// Variables globales
int ticket1 = 0;
int fastHandle;
int slowHandle;
double fastMA[];
double slowMA[];
double rsi[];
CTrade trade;
int handlersi;
bool CountOpenPositions;
MqlTick currentTick;
datetime openTimeBuy = 0;
datetime openTimeSell = 0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
      // check input rsi
      if(InpMagicNumber <= 0){
       Alert("Magic Number <=0");
       return INIT_PARAMETERS_INCORRECT;
    }
      // check input rsi
      if(LotSize <= 0 || LotSize >10){
       Alert("lot not acepted <=0");
       return INIT_PARAMETERS_INCORRECT;
    }
    // check input rsi
      if(RSI_Period <= 1){
       Alert("Rsi period <=0");
       return INIT_PARAMETERS_INCORRECT;
    }
    // check input rsi
      if(RSI_Level >= 100 || RSI_Level <= 50){
       Alert("Rsi not accepted");
       return INIT_PARAMETERS_INCORRECT;
    }
  // set magic number to objet
  trade.SetExpertMagicNumber(InpMagicNumber);
   //validate inputs
   if(FastMA_Period <= 0){
      Alert("Fast period <=0");
      return INIT_PARAMETERS_INCORRECT;
   }
   if(SlowMA_Period <= 0){
      Alert("Slow period <=0");
      return INIT_PARAMETERS_INCORRECT;
   }
   if(SlowMA_Period <= FastMA_Period){
      Alert("Fast period >= Slow period");
      return INIT_PARAMETERS_INCORRECT;
   }
   if(InputSL <= 0){
      Alert("stop loss <=0");
      return INIT_PARAMETERS_INCORRECT;
   }
   if(InputTP <= 0){
      Alert("Take profit <=0");
      return INIT_PARAMETERS_INCORRECT;
   }
   //creat handles
   fastHandle = iMA(_Symbol,PERIOD_CURRENT,FastMA_Period,0,MODE_SMA,PRICE_CLOSE);
   if(fastHandle == INVALID_HANDLE){
   Alert("Failed to create fast handle");
   return INIT_FAILED;
   }
   slowHandle = iMA(_Symbol,PERIOD_CURRENT,SlowMA_Period,0,MODE_SMA,PRICE_CLOSE);
   if(slowHandle == INVALID_HANDLE){
   Alert("Failed to create slow handle");
   return INIT_FAILED;
   }
        //create handle
     handlersi = iRSI (_Symbol,PERIOD_CURRENT,RSI_Period, PRICE_CLOSE);
     if (handlersi == INVALID_HANDLE){
       Alert("Failed to create indictor handle");
       return INIT_FAILED;
     }
   ArraySetAsSeries(fastMA,true);
   ArraySetAsSeries(slowMA,true);
   ArraySetAsSeries(rsi,true);
   return(INIT_SUCCEEDED);
 }
//
// Función de inicio
void OnTick()
{
if(!SymbolInfoTick(_Symbol,currentTick))
   {
      Print("Failed to get current tick"); return;}
          // Copy the   values of the moving averages into the arrays
        int values1 =   CopyBuffer(fastHandle, 0, 0, 2, fastMA);
        int values2 =   CopyBuffer(slowHandle, 0, 0, 2, slowMA);
        int values3 =   CopyBuffer(handlersi, 0, 0, 2, rsi);
      // Check if the values were successfully copied
      if (values1 != 2 || values2 != 2 || values3 != 2) {
         printf("Failed to get indicator values");
         return;
      }
   Comment("slowMA[0]:", slowMA[0],
            "\nslowMA[1]:",slowMA[1],
            "\nfastMA[0]:", fastMA[0],
            "\nslowMA[1]:",fastMA[1],
            "\nbufferrsi[0]:", rsi[0],
            "\nbufferrsi[1]:",rsi[1]);
   // Obtener los valores de las medias móviles y el RSI
   if (values1 <= 0 || values2 <= 0 || values3 <= 0)
   {
      Print("Error al obtener los valores de los indicadores: ", GetLastError());
      return;
   }
   // count opern position
   int cntBuy, cntSell;
   if(!CountOpenPositions(cntBuy,cntSell)){return;}
   //check for buy position
   if(cntBuy==0 && rsi[1]>=(100-RSI_Level) && rsi[0]<(100-RSI_Level) && openTimeBuy
!= iTime(_Symbol,PERIOD_CURRENT,0)){
        openTimeBuy=iTime(_Symbol,PERIOD_CURRENT,0);
        if(ImpCloseSignal){if(!ClosePositions(2)){return;}}
        double sl = InputSL==0 ? 0 : currentTick.bid - InputSL * _Point;
        double tp = InputTP==0 ? 0 : currentTick.bid + InputTP * _Point;
        if(!NormalizeDouble(sl)){return;}
        if(!NormalizeDouble(tp)){return;}
        trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,LotSize,currentTick.ask,sl,tp, "RSI
EA");
    //check for SELL position
   if(cntSell==0 && rsi[1]<=RSI_Level && rsi[0]>RSI_Level && openTimeSell !=
iTime(_Symbol,PERIOD_CURRENT,0)){
        openTimeSell=iTime(_Symbol,PERIOD_CURRENT,0);
        if(ImpCloseSignal){if(!ClosePositions(1)){return;}}
        double sl = InputSL==0 ? 0 : currentTick.ask + InputSL * _Point;
        double tp = InputTP==0 ? 0 : currentTick.ask - InputTP * _Point;
        if(!NormalizeDouble(sl)){return;}
        if(!NormalizeDouble(tp)){return;}
      trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,LotSize,currentTick.bid,sl,tp,
"RSI EA");
    // funciones
    // open positions
    bool CountOpenPositions (int &cntBuy, int &cntSell){
      cntBuy = 0;
      cntSell = 0;
      int total = PositionsTotal();
      for(int i=total-1 ; i>=0 ; i--){
             ulong ticket = PositionGetTicket(i);
             if(ticket<=0){Print("Failed to open posistion ticket"); return false;}
             if(!PositionSelectByTicket(ticket)){Print("Failed to select
position");}
             long magic;
             if(!PositionGetInteger(POSITION_MAGIC,magic)){Print("failed to get
psition magic number");return false;}
             if(magic == InpMagicNumber){
                long type;
                if(!PositionGetInteger(POSITION_TYPE,type)){Print("Failed to get
position types");return false;}
                if(type==POSITION_TYPE_BUY){cntBuy++;}
                if(type==POSITION_TYPE_SELL){cntSell++;}
             }
      }
      return true;
   }
    // nomalize price
    bool NormalizeDouble(double &price){
       double tickSize=0;
       if(!SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE,tickSize)){
          Print("Failed to get tick size");
          return false;
       }
       price = NormalizeDouble(MathRound(price/tickSize)*tickSize,_Digits);
       return true;
// close positions
    bool ClosePositions (int all_buy_sell){
        int total = PositionsTotal();
      for(int i=total-1 ; i>=0 ; i--){
             ulong ticket = PositionGetTicket(i);
             if(ticket<=0){Print("Failed to open posistion ticket"); return false;}
             if(!PositionSelectByTicket(ticket)){Print("Failed to select
position");}
             long magic;
             if(!PositionGetInteger(POSITION_MAGIC,magic)){Print("failed to get
psition magic number");return false;}
             if(magic == InpMagicNumber){
                long type;
                if(!PositionGetInteger(POSITION_TYPE,type)){Print("Failed to get
position types");return false;}
                if(all_buy_sell==1 && type== POSITION_TYPE_SELL){continue;}
                if(all_buy_sell == 2 && type==POSITION_TYPE_BUY){continue;}
                trade.PositionClose(ticket);
                if(trade.ResultRetcode()!=TRADE_RETCODE_DONE){
                   Print("Failed to close position", (string)ticket, "result",
(string)trade.ResultRetcode(), ":", trade.CheckResultRetcodeDescription());
                   }
             }
      }
      return true;
   }