//+------------------------------------------------------------------+
//|                                       H4Media200StrategeTest.mq4 |
//|                                       Rodolfo Leonardo de Morais |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "rodolfo.leonardo@gmail.com"
#property link "https://www.mql5.com"
#property version "1.00"
//#property strict

extern string ___Configuracoes_Gerais___ = "------------Configuracoes Gerais------------";
extern bool chartDisplay = FALSE; // Habilita informações na tela
extern color   background_color = Teal; // Cor de fundo das informações

extern bool UseManualLots = FALSE; // Usa Lote Manual (Desabilita RiskPercent)
extern double Lots = 1; // Quantidade de Lote caso UseManualLots = false

extern double TakeProfit =20.0; // Lucro planejado -  0 desativa
extern double MaxSpread = 29.0; // Maximo de Spread p/ abertura de Ordem
extern double TrailingStop = 0.0; // Deslize de StopLoss -  0 desativa
extern int     slippage    = 10; // Tolerância de ordem desliza / cotações de fechamento

extern string system1_comment = "Forex ROBO H4 V2.0"; // Comentário EA
extern int MagicNumber = 20160905; // Identificador de EA
extern ENUM_TIMEFRAMES  TimeFrame = PERIOD_M15; // Periodo de atuação
extern int     PeriodoMM    = 500;
extern double vMargem = 30; // Margem da MM p/ inicio da Compra/Venda

extern bool DiminuirCadaLoteAberto = true; // Diminui a Qtd de Lotes a cada lote aberto
extern bool  Martingale = true; // Habilita Martingale

extern double RiskPercent = 1; // Percentual de Risco (RiskPercent)
extern double MaxLotOrder = 0.0; // Maximo de Lote por Ordem -  0 desativa
extern double MaxOrderLot = 0.0; // Maximo de Ordem a ser aberto conjuntas  -  0 desativa
//extern string Chave = "";
extern bool AbrirApenasEmFundoTopo = true;


extern string ___HORARIO_ATUACAO___ = "------------HORARIO DE ATUACAO------------";
extern bool Trade_in_Monday  =true; 
extern bool Trade_in_Tuesday =true; 
extern bool Trade_in_Wednesday=true;
extern bool Trade_in_Thursday=true; 
extern bool Trade_in_Friday  =true;

extern string StartHour = "00:00"; 
extern string EndHour   = "23:00";  

bool gi_244 = TRUE;
int gi_800;
bool Gi_596 = true;
double G_pips_288 = 500.0;
int vQtdOrdensAbertas = 0;

datetime vUltCandleVerificado;
int maxOrdens = 1;
double vSpread = 0;
double vFundo = 0;

int sinal = 0;
int vNovoFundo = 0;
double shortEma, longEma;
double Gd_228 = 1.0;
double Gd_444 = 0.0;
double Gd_492;
bool Gi_460 = FALSE;
 bool Gi_468 = FALSE;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init() {
    //---
    Gd_228 = 1.0;
   if (Digits == 3 || Digits == 5) Gd_228 = 10;
    if (gi_244) gi_800 = 0;
    else gi_800 = 1;
    //---
    return (0);
    
  // TakeProfit =  10.0 * TakeProfit;
    
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit() {
    return (0);
}


void Informacoes() {
   double Ld_0;
   double Ld_8;
   double Ld_16;
   double Ld_24;
   double Ld_32;
   double Ld_40;
   double Ld_48;
   double Ld_56;
   string Ls_64;
   string Ls_72;
   int Li_84;

   if ( !IsOptimization())
    {
     
      Ls_64 = "==========================\n";
      Ls_64 = Ls_64 + "               " + "ROBO H4 v2.00" 
      + "\n";
      Ls_64 = Ls_64 + "==========================\n";
      Ls_64 = Ls_64 + "  Base Lot Size: " + DoubleToStr(Lots, 2) + " lots\n";
      Ls_64 = Ls_64 + "  Slippage: " + DoubleToStr(slippage, 2) + " \n";
      Ls_64 = Ls_64 + "  TakeProfit: " + DoubleToStr(TakeProfit, 2) + " pips\n";
      Ls_64 = Ls_64 + "  TrailingStop: " + DoubleToStr(TrailingStop, 2) + " pips\n";
      Ls_64 = Ls_64 + "  UseManualLots: " + UseManualLots + "\n";
      Ls_64 = Ls_64 + "  RiskPercent: " + DoubleToStr(RiskPercent, 2) + " %\n";
      Ls_64 = Ls_64 + "  MaxOrderLot: " + DoubleToStr(MaxOrderLot, 2) + " \n";
      Ls_64 = Ls_64 + "  MaxLotOrder: " + DoubleToStr(MaxLotOrder, 2) + " lots\n";
      Ls_64 = Ls_64 + "  MaxSpread: " + DoubleToStr(MaxSpread, 2) + " pips\n";
      Ls_64 = Ls_64 + "==========================\n";
       Ls_64 = Ls_64 + "  QtdOrderOpen: " + Lots  * 1.5  + " \n"; 
      Ls_64 = Ls_64 + "  QtdOrderOpen: " + vQtdOrdensAbertas + " \n";
      Ls_64 = Ls_64 + "  Spread: " + vSpread + " \n";
      Ls_64 = Ls_64 + "  Lucro/Perda: " + SomaOrderProfitDoDia() + " \n";
      Ls_64 = Ls_64 + "  Fundo/Topo: " + vFundo + " \n";
      Ls_64 = Ls_64 + "  Margem NEG : " + NormalizeDouble((longEma - vMargem * Point), Digits) + " \n";
      Ls_64 = Ls_64 + "  Margem POS : " + NormalizeDouble((longEma + vMargem * Point), Digits) + " \n";
      Ls_64 = Ls_64 + "  Last Close : " + NormalizeDouble(iClose(Symbol(),TimeFrame,1), Digits) + " \n";
      Ls_64 = Ls_64 + " ==========================\n";
      Ls_64 = Ls_64 + " Creditos: rodolfo.leonardo@gmail.com \n";
      Ls_64 = Ls_64 + " ==========================\n";
      
      
      Comment(Ls_64);
      Li_84 = 11;
    
      if (Gi_596 || Seconds() % 5 == 0) {
         Gi_596 = FALSE;
         for (int count_88 = 0; count_88 < 9; count_88++) {
            for (int count_92 = 0; count_92 < Li_84; count_92++) {
               ObjectDelete("background" + count_88 + count_92);
               ObjectDelete("background" + count_88 + ((count_92 + 1)));
               ObjectDelete("background" + count_88 + ((count_92 + 2)));
               ObjectCreate("background" + count_88 + count_92, OBJ_LABEL, 0, 0, 0);
               ObjectSetText("background" + count_88 + count_92, "n", 30, "Wingdings", background_color);
               ObjectSet("background" + count_88 + count_92, OBJPROP_XDISTANCE, 20 * count_88);
               ObjectSet("background" + count_88 + count_92, OBJPROP_YDISTANCE, 23 * count_92 + 9);
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()

{
if(chartDisplay){
   Informacoes();
}


   
    int cnt, ticket, total;


    if (Bars < 10) {
        Print("bars less than 100");
        return (0);
    }
  
   double max = NormalizeDouble(iHigh(Symbol(),1440,0),Digits);
   double min = NormalizeDouble(iLow (Symbol(),1440,0),Digits);
   double opp=NormalizeDouble(iOpen(Symbol(),1440,0),Digits);
   double cl=NormalizeDouble(iClose(Symbol(),1440,0),Digits);

     //if(!TimeFilter()) return (0);
     //if(!IsExpertEnabled()) return (0);
     

    //Caso o spreed seja maior que o parametrizado foge
    vSpread = MarketInfo(Symbol(), MODE_SPREAD);
    if (vSpread > MaxSpread) return (0);
    
    
   
    if(!UseManualLots){
       Lots = CalculaQtdLotesRisco(RiskPercent);
       }
    
  
    
    if(DiminuirCadaLoteAberto && vQtdOrdensAbertas>0 ) Lots = Lots / vQtdOrdensAbertas;
    
    if(Martingale &&  vQtdOrdensAbertas>0 ) Lots = Lots  * 1.55 ;
    
    if( MaxLotOrder > 0 && Lots > MaxLotOrder) Lots=MaxLotOrder;
    

    Lots = NormalizaLotes(Lots);

 
    
    longEma = iMA(Symbol(), TimeFrame, PeriodoMM, 0, MODE_LWMA, PRICE_CLOSE, gi_800 + 0);

    //int isCrossed = Crossed(iClose(Symbol(),TimeFrame,2), longEma);
    
    total = OrdersTotal();
    
    if(MaxOrderLot > 0 && vQtdOrdensAbertas > MaxOrderLot ) return(0);
    
    //Cruzou p/ baixo compra
    if (NormalizeDouble(iClose(Symbol(),TimeFrame,1), Digits) < NormalizeDouble((longEma - vMargem * Point),Digits) ) {
       
     
       
       
       //Indentifica novo Fundo
       if(NormalizeDouble(iLow (Symbol(),TimeFrame,1),Digits) <   vFundo && vNovoFundo == 0 || !AbrirApenasEmFundoTopo ) {
           vNovoFundo = 1;
           vFundo = NormalizeDouble(iLow (Symbol(),TimeFrame,1),Digits);
        }
    
    
       // verifica se candle anterior fechou vermelho (fechamento abaixo da abertura)
       if( vNovoFundo == 1 && iClose(Symbol(),TimeFrame,1) < iOpen(Symbol(),TimeFrame,1 )  && vUltCandleVerificado != iTime(Symbol(),TimeFrame,1) ){
      
           vNovoFundo = 0;
           ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, slippage, 0, NormalizeDouble(TKCompra(Ask,TakeProfit), Digits), system1_comment, MagicNumber, 0, Green);
           if (ticket > 0) {
              Gi_468 = TRUE;
               if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) {
               
               Print("BUY order opened : ", OrderOpenPrice());
               vUltCandleVerificado = iTime(Symbol(),TimeFrame,1);
               
               }
           } else Print("Error opening BUY order : ", GetLastError());
   
           return (0);
        }
        
         

    }

    //Cruzou p/ cima vende
    if (NormalizeDouble(iClose(Symbol(),TimeFrame,1), Digits) > NormalizeDouble((longEma + vMargem * Point), Digits)) {
    
      //Identificou Novo Topo
      if(NormalizeDouble(iHigh(Symbol(),TimeFrame,1),Digits) >   vFundo  && vNovoFundo == 0 || !AbrirApenasEmFundoTopo)  {
          vNovoFundo = 1 ;
          vFundo = NormalizeDouble(iHigh(Symbol(),TimeFrame,1),Digits);
       }
      
      // verifica se candle anterior fechou verde (fechamento acima da abertura)
       if( vNovoFundo == 1 &&  iClose(Symbol(),TimeFrame,1) > iOpen(Symbol(),TimeFrame,1) && vUltCandleVerificado != iTime(Symbol(),TimeFrame,1) ){
   
           vNovoFundo = 0;
           ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, slippage, 0,NormalizeDouble(TKVenda(Bid, TakeProfit), Digits), system1_comment, MagicNumber, 0, Red);
           
           if (ticket > 0) {
              Gi_468 = TRUE;
               if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)){
               vUltCandleVerificado = iTime(Symbol(),TimeFrame,1);
                Print("SELL order opened : ", OrderOpenPrice());
                }
           } else Print("Error opening SELL order : ", GetLastError());
   
           return (0);
        }
        
        
    }

       vQtdOrdensAbertas = 0;
            double G_price_356 = 0.0;
      double Ld_284 = 0.0;
      int G_pos_436 = 0;
      int Gi_440 = f0_38();
      double G_price_324  = 0.0;
      double Ld_212 = TakeProfit;
     
      bool Gi_404;
      for (G_pos_436 = OrdersTotal() - 1; G_pos_436 >= 0; G_pos_436--) {
         OrderSelect(G_pos_436, SELECT_BY_POS, MODE_TRADES);
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
               if (OrderType() == OP_BUY || OrderType() == OP_SELL) {
                  G_price_356 += OrderOpenPrice() * OrderLots();
                  Ld_284 += OrderLots();
               }
            }
         }
      }
      if (Gi_440 > 0) G_price_356 = NormalizeDouble(G_price_356 / Ld_284, Digits);
      
      
      if (true) {
         for (G_pos_436 = OrdersTotal() - 1; G_pos_436 >= 0; G_pos_436--) {
            OrderSelect(G_pos_436, SELECT_BY_POS, MODE_TRADES);
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber ) {
               if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
                  if (OrderType() == OP_BUY) {
                     G_price_324 = G_price_356 + Ld_212 * Gd_228 * Point;
                  
                     Gd_444 = G_price_356 - G_pips_288 * Point;
                     Gi_404 = TRUE;
                  }
               }
               if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
                  if (OrderType() == OP_SELL) {
                     G_price_324 = G_price_356 - Ld_212 * Gd_228 * Point;
                   
                     Gd_444 = G_price_356 + G_pips_288 * Point;
                     Gi_404 = TRUE;
                  }
               }
            }
         }
      }
      if (Gi_468) {
         if (Gi_404 == TRUE) {
            for (int Li_292 = OrdersTotal() - 1; Li_292 >= 0; Li_292--) {
               if (f0_22(Li_292, SELECT_BY_POS)) {
                  //while (!IsTradeAllowed()) {
                  //   Sleep(150);
                  //   RefreshRates();
                  //}
                  while (!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), G_price_324, 0, Yellow)) {
                 // printf("OrderModify");
                     Sleep(900);
                     RefreshRates();
                  }
                  Gi_468 = FALSE;
               }
            }
         }
      }
        return (0);

    }
    //+------------------------------------------------------------------+
    int Crossed(double line1, double line2) {
        static int last_direction = 0;
        static int current_direction = 0;
        if (line1 > line2) current_direction = 1; //up
        if (line1 < line2) current_direction = 2; //down
        if (current_direction != last_direction) //changed
        {
            last_direction = current_direction;
            return (last_direction);
        } else {
            return (0);
        }
    }
  

double TKVenda(double Ad_0, int Ai_8) {
   if (Ai_8 == 0) return (0.0);
   return (Ad_0 - Ai_8 * Point);
}


double TKCompra(double Ad_0, int Ai_8) {
   if (Ai_8 == 0) return (0.0);
   return (Ad_0 + Ai_8 * Point);
}

double NormalizaLotes(double ad_0) 
{
   if (ad_0 > MarketInfo(Symbol(), MODE_MAXLOT)) ad_0 = MarketInfo(Symbol(), MODE_MAXLOT);
   else
      if (ad_0 < MarketInfo(Symbol(), MODE_MINLOT)) ad_0 = MarketInfo(Symbol(), MODE_MINLOT);
   return (ad_0);
}

//Calcula a quantidade de lotes  conforme o risco
double CalculaQtdLotesRisco(double vRiskPercent) 
{
   bool vTrailingStop = TRUE;
   double minlot_12 = MarketInfo(Symbol(), MODE_MINLOT);
   double maxlot_12 = MarketInfo(Symbol(), MODE_MAXLOT);
   double vMODE_POINT = MarketInfo(Symbol(), MODE_LOTSIZE) / AccountLeverage();
   double ld_28 = vRiskPercent / 100.0 * AccountBalance() / vMODE_POINT;
   double vRetorno = MathFloor(ld_28);
   while (vTrailingStop) 
   {
      vRetorno += minlot_12;
      if (vRetorno > ld_28) 
      {
         vTrailingStop = FALSE;
         vRetorno -= minlot_12;
      }
   }
   if(vRetorno > maxlot_12)  return (maxlot_12);
   else
   return (vRetorno);
}


double SomaOrderProfitDoDia() {
   int day_0 = Day();
   double ld_ret_4 = 0;
   for (int pos_12 = 0; pos_12 < OrdersHistoryTotal(); pos_12++) {
      OrderSelect(pos_12, SELECT_BY_POS, MODE_HISTORY);
      if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
      //if (TimeDay(OrderOpenTime()) == day_0) 
      ld_ret_4 += OrderProfit();
   }
   return (ld_ret_4);
}

int SomaTrades() {
   int count_0 = 0;
   for (int pos_4 = 0; pos_4 < OrdersTotal(); pos_4++) {
      OrderSelect(pos_4, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
      count_0++;
   }
   return (count_0);
}



bool TimeFilter(){

 bool _res = false;
   datetime _time_curent = TimeCurrent();
   datetime _time_start = StrToTime(DoubleToStr(Year(),0)+"."+DoubleToStr(Month(),0)+"."+DoubleToStr(Day(),0)+" "+StartHour);
   datetime _time_stop = StrToTime(DoubleToStr(Year(),0)+"."+DoubleToStr(Month(),0)+"."+DoubleToStr(Day(),0)+" "+EndHour);
   if(((Trade_in_Monday==true) && (TimeDayOfWeek(Time[0]) == 1)) ||
   ((Trade_in_Tuesday==true) && (TimeDayOfWeek(Time[0]) == 2)) ||
   ((Trade_in_Wednesday==true) && (TimeDayOfWeek(Time[0]) == 3)) ||
   ((Trade_in_Thursday==true) && (TimeDayOfWeek(Time[0]) == 4)) ||
   ((Trade_in_Friday==true) && (TimeDayOfWeek(Time[0]) == 5)))
   
   
   if(_time_start > _time_stop){
      if(_time_curent >= _time_start || _time_curent <= _time_stop) _res = true;
   }else   
      if(_time_curent >= _time_start && _time_curent <= _time_stop) _res = true;
      
      return(_res); 
  
 }        
 
 
// FD4055E1AC0A7D690C66D37B2C70E529
int f0_38() {
   int count_0 = 0;
   Gd_492 = 0.0;
   double Ld_4 = 0.0;
   for (int pos_12 = OrdersTotal() - 1; pos_12 >= 0; pos_12--) {
      OrderSelect(pos_12, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
         if (OrderType() == OP_SELL || OrderType() == OP_BUY) {
            count_0++;
            Ld_4 = OrderLots() + Ld_4;
            Gd_492 = OrderProfit() + OrderSwap() + Gd_492;
         }
      }
   }
   return (count_0);
}

// 90124A87B1714F1FF8E93A2800BD4144
int f0_22(int A_pos_0, int Ai_4, int Ai_8 = 0) {
   if (OrderSelect(A_pos_0, Ai_4, Ai_8) == FALSE) return (0);
   if (OrderMagicNumber() != MagicNumber) return (0);
   if (OrderSymbol() != Symbol()) return (0);
   if (Ai_8 != MODE_HISTORY) return (1);
   return (OrderType() <= OP_SELL);
}