//+------------------------------------------------------------------+
//|                                                atrorders-exp.mq4 |
//|                                   |
//+------------------------------------------------------------------+

#include <stdlib.mqh>

extern int expertId = 101006;

extern int TakeProfit = 30;
extern int StopLoss = 65;  
extern int TrailingStop = 20;  

extern double Lots = 0.1;   

extern string Start="01:00";
extern string Stop="23:00";
extern int    shift=0;
extern int    ATRperiod=10;
extern int    ATRincrease=2;
extern int    ScreenAlert=true;
extern bool   EmailAlert=true;
extern int    Delta=15; // (how many pips to put the stop orders away from the market price )

extern int    slippage=2;   	//slippage for market order processing

extern int    OrderTriesNumber=2; //to repeate sending orders when got some error

extern string    EAName="atrorders"; 

bool enter,exit;
int tries,co,mkt,pnd,le;
double atr1,atr2,atr3,atr11,atr21;

void start()  {

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

   if (mkt>0 && pnd>0) CloseTrades();

   if (mkt==0 && pnd>0 && exit) CloseTrades();
   
   CheckForOpen();
   
   if (mkt>0) TrailStop();

}



int CalculateCurrentOrders(string symbol)  {
   int ord;
   mkt=0; pnd=0; 
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==symbol && OrderMagicNumber()==expertId) {
         ord++;
         if (OrderType()==OP_BUY) { 
            mkt++;
         }
         if (OrderType()==OP_SELL) {
            mkt++;
         }
         if (OrderType()==OP_BUYSTOP) { 
            pnd++;
         }
         if (OrderType()==OP_SELLSTOP) {
            pnd++;
         }
      }
     }
//---- return orders volume
   return(ord);
}

void CheckSignals() {
   enter=false;    exit=false;
   
   atr1=nd(iATR(NULL,0,ATRperiod,0));
   atr2=nd(iATR(NULL,0,ATRperiod,1));
   if (atr1-atr2>=ATRincrease*Point) enter=true;
   if (atr1-atr2<ATRincrease*Point) exit=true;
   
   if (CurTime()>=StrToTime(Stop)) exit=true;

}

void CheckForOpen() {
   if (CurTime()<StrToTime(Start) || CurTime()>=StrToTime(Stop)) return;
   int    res;
   double spread=Ask-Bid;
   co=CalculateCurrentOrders(Symbol());
   if (mkt==0 && pnd>0 && le!=Time[0] && enter)  {
      CloseTrades();
   }
 
   if (mkt==0 && pnd==0 && le!=Time[0] && enter)  {
      res = OpenPending(OP_BUYSTOP,Lots,Bid+spread+Delta*Point,TakeProfit,"");
      res = OpenPending(OP_SELLSTOP,Lots,Bid-Delta*Point,TakeProfit,"");
      le=Time[0];
   }

}
  
  

int OpenPending(int mode,double lot,double price,int TP,string cmt) {
   int    res,tr,col;
   double opr=price,sl,tp;
   tries=0;
   while (res<=0 && tries<OrderTriesNumber) {
      tr=0; while (tr<5 && !IsTradeAllowed()) { tr++; Sleep(2000); }
      RefreshRates();
      if (mode==OP_SELLSTOP) {
         if (opr>=Bid-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point) opr=Bid-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point-Point;
         if (StopLoss>4) sl=opr+StopLoss*Point;
         if (TP>4) tp=opr-TP*Point;
         col=Red;
      } 
      if (mode==OP_BUYSTOP) {
         if (opr<=Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point) opr=Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point+Point;
         if (StopLoss>4) sl=opr-StopLoss*Point;
         if (TP>4) tp=opr+TP*Point;
         col=Blue;
      }
      res=OrderSend(Symbol(),mode,lot,nd(opr),slippage,nd(sl),nd(tp),cmt+"_"+EAName+"_"+expertId,expertId,0,col);
      tries++;
   }
   if (res<=0) Print("Error opening order : ",ErrorDescription(GetLastError()));
   return(res);
}



void TrailStop() {
   bool bres;
   double StopLoss;
   if ( TrailingStop > 2 ) {
      for (int i = 0; i < OrdersTotal(); i++) {
         if ( OrderSelect (i, SELECT_BY_POS) == false )  continue;
         if ( OrderSymbol() != Symbol() || OrderMagicNumber() != expertId )  continue;
         if ( OrderType() == OP_BUY ) {
            if ( Ask < OrderOpenPrice()+TrailingStop*Point )  continue;
            StopLoss = Ask-TrailingStop*Point;
            if ( StopLoss > OrderStopLoss() ) {
                  bres=OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, White);
					   if (!bres) Print("Error Modifying BUY order : ",ErrorDescription(GetLastError()));
            }
         }
   
         if ( OrderType() == OP_SELL ) {
            if ( Bid > OrderOpenPrice()-TrailingStop*Point )  continue;
            StopLoss = Bid+TrailingStop*Point;
            if ( StopLoss < OrderStopLoss() ) {
                  bres=OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, Gold);
					   if (!bres) Print("Error Modifying SELL order : ",ErrorDescription(GetLastError()));
            }
         }
      }
   }
   return;
}



void CloseTrades()  {
   bool bres; int tr,total=OrdersTotal();
   for(int i=0;i<total;i++)  {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)  continue;
      if(OrderMagicNumber()!=expertId || OrderSymbol()!=Symbol()) continue;
      //---- check order type 
      if(OrderType()==OP_SELLSTOP) 
         bres=OrderDelete(OrderTicket());
      else if(OrderType()==OP_BUYSTOP) 
         bres=OrderDelete(OrderTicket());
   }
   co=CalculateCurrentOrders(Symbol());
   if (pnd>0) CloseTrades();
}

double nd(double d) {
   return(NormalizeDouble(d,Digits));
}


