#property copyright "FXRodoxFudidaoMaster"
#property link      "FXRodoxFudidaoMaster"

#include <WinUser32.mqh>

#import "shell32.dll"
   int ShellExecuteA(int a0, string a1, string a2, string a3, string a4, int a5);
#import

#define  NL    "\n"

extern int TakeProfit = 30;
extern int StopLoss = 10;
extern int MagicNumber = D'03.07.2016 00:31:30';
extern int PipStep = 6;
extern int MaxOrders = 4;
extern int TrailingStop = 30;
extern int TimeToWait = 12;
extern double Lots = 0.01;
extern bool UseRiskPercent = TRUE;
extern double RiskPercent = 0.2;
extern double MaxOrderLot = 0.0;
extern double MaxSpread = 18.0;


int Time_Frame = 0;
double gda_132[50];
int vTimeCurrent[50];
bool gi_140 = TRUE;

int g_slippage_152 = 3;
bool gi_156 = TRUE;
int gi_160 = -1;
int vSTOPLEVEL;
string gs_unused_168 = "";
double vTamanhoPonto;
bool gi_184 = FALSE;

int init() 
{
   Time_Frame =  TimeCurrent();
   vSTOPLEVEL = MarketInfo(Symbol(), MODE_STOPLEVEL);
   if (vSTOPLEVEL > TrailingStop && TrailingStop != 0) TrailingStop = vSTOPLEVEL;
   vTamanhoPonto = TamanhoPonto();
   return (0);
}



int deinit() 
{
   return (0);
}

int start() 
{
   string str_concat_0;
   string ls_unused_12;
   string ls_unused_20;
   string ls_unused_28;
  
   f0_7(vTimeCurrent);
   vTimeCurrent[0] = TimeCurrent();
   f0_4(vTimeCurrent);
   int li_36 = f0_9(vTimeCurrent);
   f0_14(gda_132);
   gda_132[0] = Bid;
   
   if (TrailingStop != 0) f0_11();
   
   //Caso o spreed seja maior que o parametrizado foge
   if (Ask - Bid > MaxSpread * vTamanhoPonto) return (0);
   
   if (f0_13() < MaxOrders) f0_2(gda_132, PipStep, li_36);
   
   string Message;

   Message = "                ROBO RODOX FUDIDAO V1.2" + NL +
             "                            Tempo Atual       " +  TimeToStr(TimeCurrent(), TIME_SECONDS) + NL +  
             "                            TakeProfit        " + TakeProfit            + NL +            
             "                            StopLoss          " + StopLoss              + NL +    
             "                            TrailingStop      " + TrailingStop              + NL +   
             "                            TimeToWait        " + TimeToWait              + NL +   
             "                            Lots              " + Lots              + NL +   
             "                            UseRiskPercent    " + UseRiskPercent              + NL +   
             "                            RiskPercent       " + RiskPercent              + NL +   
             "                            MaxOrderLot       " + MaxOrderLot              + NL +   
             "                            MaxSpread         " + MaxSpread              + NL +   
             "";
   
    Comment(Message);  
    
   return (0);
}

// tamanho de ponto na moeda de cota��o
double TamanhoPonto(string a_symbol_0 = "0") 
{
   if (a_symbol_0 == "0") a_symbol_0 = Symbol();
   int digits_8 = MarketInfo(a_symbol_0, MODE_DIGITS);
   double vretorno = 0.0;
   double vMODE_POINT = MarketInfo(a_symbol_0, MODE_POINT);
   if (digits_8 == 5 || digits_8 == 3) vretorno = 10.0 * vMODE_POINT;
   else vretorno = vMODE_POINT;
   return (vretorno);
}

void f0_11() 
{
   double ld_0;
   int vTrailingStop = TrailingStop;
   for (int pos_12 = 0; pos_12 < OrdersTotal(); pos_12++) 
   {
      if (OrderSelect(pos_12, SELECT_BY_POS) != FALSE) 
      {
         if (OrderSymbol() == Symbol()) 
         {
            if (OrderMagicNumber() >= MagicNumber && OrderMagicNumber() <= MagicNumber) 
            {
               if (OrderType() == OP_BUY) 
               {
                  ld_0 = Bid - vTamanhoPonto * vTrailingStop;
                  if (!(OrderStopLoss() < ld_0 && OrderOpenPrice() < Bid - vTrailingStop * vTamanhoPonto)) continue;
                  ModificaOrdem(ld_0, OrderTicket());
                  continue;
               }
               ld_0 = Ask + vTamanhoPonto * vTrailingStop;
               if (OrderStopLoss() > ld_0 && OrderOpenPrice() > Ask + vTrailingStop * vTamanhoPonto) ModificaOrdem(ld_0, OrderTicket());
            }
         }
      }
   }
}

void ModificaOrdem(double a_price_0, int a_ticket_8) 
{
   vSTOPLEVEL = MarketInfo(Symbol(), MODE_STOPLEVEL);
   if (!OrderModify(a_ticket_8, OrderOpenPrice(), a_price_0, OrderTakeProfit(), 0, Red))
      if (gi_156) GravaErro();
}

void f0_4(int &pTimeCurrent[50]) 
{
   int arr_size_4 = ArraySize(pTimeCurrent);
   int vTrailingStop = TimeCurrent() - (pTimeCurrent[f0_9(pTimeCurrent) - 1]);
   while (vTrailingStop > TimeToWait) 
   {
      pTimeCurrent[f0_9(pTimeCurrent) - 1] = 0;
      vTrailingStop = TimeCurrent() - (pTimeCurrent[f0_9(pTimeCurrent) - 1]);
      if (f0_9(pTimeCurrent) < 2) break;
   }
}

int f0_9(int &pTimeCurrent[50]) 
{
   int arr_size_4 = ArraySize(pTimeCurrent);
   for (int index_8 = 0; index_8 < arr_size_4; index_8++)
      if (!(pTimeCurrent[index_8] > 0)) return (index_8);
   return (arr_size_4 - 1);
}

void f0_14(double &ada_0[50]) 
{
   int li_4 = ArraySize(ada_0);
   for (int vTrailingStop = li_4; vTrailingStop > 0; vTrailingStop--) ada_0[vTrailingStop] = ada_0[vTrailingStop - 1];
   ada_0[0] = 0;
}

void f0_7(int &aia_0[50]) 
{
   int li_4 = ArraySize(aia_0);
   for (int vTrailingStop = li_4; vTrailingStop > 0; vTrailingStop--) aia_0[vTrailingStop] = aia_0[vTrailingStop - 1];
   aia_0[0] = 0;
}

void f0_2(double &ada_0[50], int ai_4, int ai_8) 
{
   double vQtdLotes;
   double vMODE_POINT = ada_0[ArrayMaximum(ada_0, ai_8)] - ada_0[ArrayMinimum(ada_0, ai_8)];
   if (vMODE_POINT > ai_4 * vTamanhoPonto) {
      if (UseRiskPercent) vQtdLotes = CalculaQtdLotes();
      else vQtdLotes = Lots;
      if (Bid == ada_0[ArrayMaximum(ada_0, ai_8)]) EnviaOrdem(TakeProfit, StopLoss, vQtdLotes, OP_BUY);
      if (Bid == ada_0[ArrayMinimum(ada_0, ai_8)]) EnviaOrdem(TakeProfit, StopLoss, vQtdLotes, OP_SELL);
   }
}

int f0_13() 
{
   int li_ret_0;
   for (int pos_4 = 0; pos_4 < OrdersTotal(); pos_4++) 
   {
      if (OrderSelect(pos_4, SELECT_BY_POS) != FALSE) 
      {
         if (OrderSymbol() == Symbol())
            if (OrderMagicNumber() >= MagicNumber && OrderMagicNumber() <= MagicNumber) li_ret_0++;
      }
   }
   return (li_ret_0);
}

//Envia a Ordem para a Corretora
int EnviaOrdem(int vTakeProfit, int vStopLoss, double vQtdLotes, int vOperacao, int ai_20 = 0) 
{
   int li_24;
   double price_28;
   double price_36;
   double price_44;
   color color_52;
   string ls_56 = "xyz";
   
   //Caso o spreed seja maior que o parametrizado foge
   double vspread = MarketInfo(Symbol(), MODE_SPREAD);
   if (vspread > MaxSpread ) return (0);
   
   if (vOperacao % 2 == 0) 
   {
      if (vOperacao == OP_BUYLIMIT) price_28 = Ask + li_24 * vTamanhoPonto;
      else price_28 = Ask + li_24 * vTamanhoPonto;
      if (vStopLoss != 0) price_36 = price_28 - (vStopLoss + li_24) * vTamanhoPonto;
      if (vTakeProfit != 0) price_44 = price_28 + (vTakeProfit + li_24) * vTamanhoPonto;
      color_52 = CLR_NONE;
   }
   if (vOperacao % 2 == 1) 
   {
      if (vOperacao == OP_SELLLIMIT) price_28 = Bid + li_24 * vTamanhoPonto;
      else price_28 = Bid + li_24 * vTamanhoPonto;
      if (vStopLoss != 0) price_36 = price_28 - ((-vStopLoss) - li_24) * vTamanhoPonto;
      if (vTakeProfit != 0) price_44 = price_28 - (vTakeProfit - li_24) * vTamanhoPonto;
      color_52 = CLR_NONE;
   }
   double price_64 = price_36;
   double price_72 = price_44;
   if (gi_140) price_36 = 0;
   if (gi_140) price_44 = 0;
   int ticket_80 = OrderSend(Symbol(), vOperacao, vQtdLotes, price_28, g_slippage_152, price_36, price_44, ls_56 + "-" + Symbol() + "-" + MagicNumber, MagicNumber + ai_20, 0, color_52);
   bool bool_84 = OrderSelect(ticket_80, SELECT_BY_TICKET);
   if (bool_84 == TRUE) if (!OrderModify(OrderTicket(), OrderOpenPrice(), price_64, price_72, 0, Blue)) if (gi_156) GravaErro();
   return (0);
}

//Calcula a quantidade de lotes 
double CalculaQtdLotes() 
{
   double vQtdLotes = Lots;
   if (UseRiskPercent) vQtdLotes = CalculaQtdLotesRisco(MathAbs(RiskPercent));
   if (vQtdLotes > MaxOrderLot && MaxOrderLot != 0.0) vQtdLotes = MaxOrderLot;
   vQtdLotes = f0_6(vQtdLotes);
   return (vQtdLotes);
}


//Calcula a quantidade de lotes  conforme o risco
double CalculaQtdLotesRisco(double vRiskPercent) 
{
   bool vTrailingStop = TRUE;
   double minlot_12 = MarketInfo(Symbol(), MODE_MINLOT);
   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;
      }
   }
   return (vRetorno);
}

double f0_6(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);
}

void GravaErro() 
{
   string ls_0;
   if (gi_156) 
   {
      if (gi_160 > 0) 
      {
         ls_0 = "Error:" + GetLastError() + " OrderType:" + OrderType() + " Ticket:" + OrderTicket();
         ls_0 = TimeToStr(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) + " " + ls_0;
         FileWrite(gi_160, ls_0);
      }
   }
}

int MACDSignal(int ai_0) {
   double l_icustom_4 = iCustom(Symbol(), Time_Frame, "SupportingMACD", 12, 26, 9, 0, ai_0);
   double l_icustom_12 = iCustom(Symbol(), Time_Frame, "SupportingMACD", 12, 26, 9, 0, ai_0 + 1);
   double l_icustom_20 = iCustom(Symbol(), Time_Frame, "SupportingMACD", 12, 26, 9, 1, ai_0);
   double l_icustom_28 = iCustom(Symbol(), Time_Frame, "SupportingMACD", 12, 26, 9, 1, ai_0 + 1);
   if (l_icustom_4 > l_icustom_20 && l_icustom_12 <= l_icustom_28) return (1);
   if (l_icustom_4 < l_icustom_20 && l_icustom_12 >= l_icustom_28) return (1);
   return (0);
}