//+------------------------------------------------------------------+
//|                                             SDL EA V1.mq4        |
//|                                        code by BontBoy           |
//|                               code template by Alex.Piech.FinGeR |
//|                                        http://www.forex-tsd.com  |
//|                           buletproofing open/close/modify orders |
//|                                  and code cleanup by Nick Bilak  |
//|                                                                  |
//+------------------------------------------------------------------+
#include <stdlib.mqh>


extern int   MAGIC=20080812;

extern string PARAMETERS_TRADE = "PARAMETERS TRADE";
extern int    SLIPPAGE       = 5; 
extern double Lots           = 0.1;    
extern int    StopLoss       = 30;     
extern int    TakeProfit     = 30;     

extern int    SDL1_period    = 60;
extern int    SDL1_method    = 3;
extern int    SDL1_price     = 0;

extern int    SDL2_period    = 40;
extern int    SDL2_method    = 2;
extern int    SDL2_price     = 0;

extern bool   useCloseTradeRules = False;

extern bool   useProfitTrailing = True;   
extern int    TrailingStop   = 20;   
extern int    TrailingStep   = 3;    
  

extern string Name_Expert   = "SDL V2";
extern bool   UseSound      = False;         
extern string NameFileSound = "expert.wav"; 
extern color  clOpenBuy     = LightBlue;    
extern color  clOpenSell    = LightCoral;  
extern color  clModifyBuy   = Aqua;         
extern color  clModifySell  = Tomato;       
extern color  clCloseBuy    = Blue;         
extern color  clCloseSell   = Red;          

int prevBar; 
bool bx=False;
bool sx=False;
double LastTime;
string LastTrend = "";

void deinit()  {
  Comment("");
}


void start() {

   //---- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false) return;

 
   bx=False;
   sx=False;
   Comment("");

   if (LastTime!=Time[0]) {
      LastTime=Time[0];
      CheckForOpen();
      
   }

   //if (useCloseTradeRules) CheckForClose();

   //if (useProfitTrailing)  TrailingPositions();
}



void CheckForOpen() {
   bx=False;
   sx=False;

   double ldStop=0, ldTake=0;
 
   double PrevEMA1Up, PrevEMA1Dn, PrevEMA2Up, PrevEMA2Dn, CurrEMA1Up, CurrEMA1Dn, CurrEMA2Up, CurrEMA2Dn;
   
   CurrEMA1Up = iCustom(NULL,0,"Slope Direction Line RR",SDL1_period,SDL1_method,SDL1_price,0,1);
   CurrEMA1Dn = iCustom(NULL,0,"Slope Direction Line RR",SDL1_period,SDL1_method,SDL1_price,1,1);
   CurrEMA2Up = iCustom(NULL,0,"Slope Direction Line RR",SDL2_period,SDL1_method,SDL1_price,0,1);
   CurrEMA2Dn = iCustom(NULL,0,"Slope Direction Line RR",SDL2_period,SDL1_method,SDL1_price,1,1);
   
   PrevEMA1Up = iCustom(NULL,0,"Slope Direction Line RR",SDL1_period,SDL1_method,SDL1_price,0,2);
   PrevEMA1Dn = iCustom(NULL,0,"Slope Direction Line RR",SDL1_period,SDL1_method,SDL1_price,1,2);
   PrevEMA2Up = iCustom(NULL,0,"Slope Direction Line RR",SDL2_period,SDL1_method,SDL1_price,0,2);
   PrevEMA2Dn = iCustom(NULL,0,"Slope Direction Line RR",SDL2_period,SDL1_method,SDL1_price,1,2);
   
   //Is the current trend up?
   if (CurrEMA1Up < 9999 && CurrEMA2Up < 9999) {
      //Were either of the last EMAs down?
      if (PrevEMA1Dn < 9999 || PrevEMA2Dn < 9999) {
         CloseSellPosition();
         RefreshRates();
         //Check if PrevTrend isn't up
         if (!ExistPosition() && LastTrend!="Up") {
            LastTrend="Up";
            if (StopLoss!=0) ldStop=Ask-StopLoss*Point;
            if (TakeProfit!=0) ldTake=Ask+TakeProfit*Point;
            SetOrder(OP_BUY, Ask, ldStop, ldTake);
         }
      }
   }
   

   //Is the current trend down?
   if (CurrEMA1Dn < 9999 && CurrEMA2Dn < 9999) {
      //Were either of the last EMAs up?
      if (PrevEMA1Up < 9999 || PrevEMA2Up < 9999) {
         CloseBuyPosition();
         RefreshRates();
         //Check if PrevTrend isn't down
         if (!ExistPosition() && LastTrend!="Dn") {
            LastTrend="Dn";
            if (StopLoss!=0) ldStop=Bid+StopLoss*Point;
            if (TakeProfit!=0) ldTake=Bid-TakeProfit*Point;
            SetOrder(OP_SELL, Bid, ldStop, ldTake);
         }
      }
   }
   
/*   if (!ExistPosition() && Hour()>=10 && Hour()<=19) {

      {
         if (StopLoss!=0) ldStop=Ask-StopLoss*Point;
         if (TakeProfit!=0) ldTake=Ask+TakeProfit*Point;
         SetOrder(OP_BUY, Ask, ldStop, ldTake);
      }
      
      
      {
         if (StopLoss!=0) ldStop=Bid+StopLoss*Point;
         if (TakeProfit!=0) ldTake=Bid-TakeProfit*Point;
         SetOrder(OP_SELL, Bid, ldStop, ldTake);
      }
}
*/
}

void CloseSellPosition() {
   bool clRes=false;
   int total=OrdersTotal();
  for (int i=0; i<total; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC && OrderType()==OP_SELL) {
         while (!clRes) {
            RefreshRates();
            clRes=OrderClose(OrderTicket(), Lots, Ask, SLIPPAGE, Violet);
            Sleep(6000);
         }
      }
    }
   }
}

void CloseBuyPosition() {
   bool byRes=false;
   int total=OrdersTotal();
  for (int i=0; i<total; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC && OrderType()==OP_BUY) {
         while (!byRes) {
            RefreshRates();
            byRes=OrderClose(OrderTicket(), Lots, Bid, SLIPPAGE, Aqua);
            Sleep(6000);
         }
      }
    }
   }
}

void CheckForClose() {
  bool bres;
  int total=OrdersTotal();

  for (int i=0; i<total; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) {
        
        if (OrderType()==OP_BUY  && bx ) {
          bres=false;
          while (!bres) {
            RefreshRates();
            bres=OrderClose(OrderTicket(), Lots, Bid, SLIPPAGE, Aqua);
            Sleep(6000);
	         if (!bres) Print("Error closing order : ",ErrorDescription(GetLastError()));
	       }
          return;
        }
      
        if (OrderType()==OP_SELL && sx) {
          bres=false;
          while (!bres) {
            RefreshRates();
            bres=OrderClose(OrderTicket(), Lots, Ask, SLIPPAGE, Violet);
            Sleep(6000);
	         if (!bres) Print("Error closing order : ",ErrorDescription(GetLastError()));
	       }
          return;
        }
      }
    }
  }
}





//+------------------------------------------------------------------+
//| is MAGIC trade open ?                                            | 
//+------------------------------------------------------------------+
bool ExistPosition() {
  bool Exist=False;
  for (int i=0; i<OrdersTotal(); i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) Exist=True;
    }
  }
  return(Exist);
}


//Are there any BUY positions open?
bool ExistBuyPosition() {
   bool Exist=false;
   for (int i=0; i<OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
         if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC && OrderType()==OP_BUY) Exist=true;
      }
   }
   return(Exist);
}

//Are there any SELL positions open?
bool ExistSellPosition() {
   bool Exist=false;
   for (int i=0; i<OrdersTotal(); i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
         if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC && OrderType()==OP_SELL) Exist=true;
      }
   }
   return(Exist);
}


void SetOrder(int op, double pp, double ldStop, double ldTake) {
   int res; double prc=pp;
   color  clOpen;
   string lsComm=GetCommentForOrder();
   if (op==OP_BUY) clOpen=clOpenBuy; else clOpen=clOpenSell;
   res=0;
   while (res<=0) {
      RefreshRates();
      if (op==OP_BUY) prc=Ask; 
      if (op==OP_SELL) prc=Bid; 
      res=OrderSend(Symbol(),op,Lots,prc,SLIPPAGE,ldStop,ldTake,lsComm,MAGIC,0,clOpen);
      Sleep(6000);
	   if (res<0) Print("Error opening order : ",ErrorDescription(GetLastError()));
	}
   
}


string GetCommentForOrder() {
  return(Name_Expert);
}

void TrailingPositions() {
   int total=OrdersTotal();
  for (int i=0; i<total; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
        if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC ) {
          if (OrderType()==OP_BUY) {
            if ((Bid-OrderOpenPrice())>TrailingStop*Point) {
             
              if (OrderStopLoss()<Bid-(TrailingStop+TrailingStep-1)*Point) {
                  RefreshRates();
                  ModifyStopLoss(Bid-TrailingStop*Point, clModifyBuy);
              }
            }
          }
          if (OrderType()==OP_SELL) {
            if (OrderOpenPrice()-Ask>TrailingStop*Point) {
              if (OrderStopLoss()>Ask+(TrailingStop+TrailingStep-1)*Point || OrderStopLoss()==0) {
                  RefreshRates();
                  ModifyStopLoss(Ask+TrailingStop*Point, clModifySell);
              }
            }
          }
       }
    }
  }
}




void ModifyStopLoss(double ldStop, color clModify) {

   bool   bres;
   double ldOpen=OrderOpenPrice();
   double ldTake=OrderTakeProfit();

   bres=OrderModify(OrderTicket(), ldOpen, ldStop, ldTake, 0, clModify);
   if (!bres) Print("Error closing order : ",ErrorDescription(GetLastError()));
 
   if (bres && UseSound) PlaySound(NameFileSound);
}




