//+------------------------------------------------------------------+
//|                                                     TEMPLATE.mq4 |
//|                                                              RBI |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "RBI"
#property link      ""

//---INDICATOR IMPUTS
extern string  _____SECTION1_____= "INDCATOR IMPUTS";
extern int     MA_TF= 0;
extern int     MA_Period= 5;

//---BOX IMPUTS
extern string  _____CONDITIONS_____= "BOX IMPUTS";
extern string  StartTime= "06:00";
extern string  EndTime= "09:15";
extern string  orderExpireTime= "12:00";
extern bool    DrawBox=  true;
extern color   BoxColor=  LightBlue;
extern bool    UseBoxForSL= true;
extern int     Order1BoxSLPercent= 100;
extern int     Order2BoxSLPercent= 100;

//---ORDER IMPUTS
extern string  _____SECTION2_____= "ORDER IMPUTS";
extern bool    UseRiskLotCalc= True;
extern string  Note1 = "METHODS: Balance based = bal, Equity based = eqt";
extern string  RiskCalcMethod= "bal";
extern double  Trade1Lots=  0.1;
extern double  T1RiskPercent = 2.0;
extern int     TP1= 60;
extern int     SL1= 30;
extern double  Trade2Lots=  0.0; //Turns on trade 2 if above zero, even when using RiscCalc
extern double  T2RiskPercent = 2.0;
extern int     TP2= 60;
extern int     SL2= 30;
extern int     Slip= 3;
extern int     MagicNumber= 162616;
extern double  SignalBufferLong= 5.0;
extern double  SignalBufferShort= 5.0;

//---TRADE MANAGEMENT IMPUTS
//TRAILING STOP
extern string  _____SECTION3_____= "TRAILING STOP IMPUTS";
extern bool    UseTrail= true;
extern int     Target_Increment= 15;
extern int     Stop_Increment= 15;
extern int     Initial_Jump= 30;
//BREAK EVEN
extern string  _____SECTION4_____= "BREAK-EVEN STOP IMPUTS";
extern bool    Use_BE= true;
extern int     BE_Stop= 15; 
 
//---FILTER IMPUTS
extern string  _____SECTION5_____= "TRADE FILTER IMPUTS";
extern int     MaxSpread= 5;
extern int     MaxTrades= 1;
extern bool    One_Trade_Bar= true;
extern bool    Use_Slow_MAFilter= false;
extern bool    Stop_Inside_Box= false; //Filters all trades if MA is inside Box
extern int     MaxBoxSize= 100;
extern bool    UseFilterComments= true;

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
   //TRADE GLOBALS
   int      ticket,tck2;
   int      tradeBar1,tradeBar2;
   
   //TRADE LIMIT GLOBALS
   int   tradenum1, tradenum2;
   
   //TRADE MANAGMENT GLOBALS
   //TICKET 1
   double   PriceReached1;
   double   trailTarget1;
   double   nSL1;
   
   double   beTarget1;
   double   beSL1;
   //TICKET 2
   double   PriceReached2;
   double   beTarget2;
   double   beSL2;
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int start()
  {
//----

   //+-----------------------------------+//---MARKET INFORMATION---//+-----------------------------------+
   double curSpread= MarketInfo(Symbol(),MODE_SPREAD)/10;
   
   //+-----------------------------------+//---INDICATORS---//+-----------------------------------+
   double EMA = iMA(NULL,MA_TF,MA_Period,0,MODE_EMA,PRICE_CLOSE,0);

   //+-----------------------------------+//---TREND DEFINITION//+-----------------------------------+
   int trend = 0;
   //... NOT USED
   
   //+-----------------------------------+//---ORDER INFORMATION---//+-----------------------------------+
   bool tckOrder = OrderSelect(ticket,SELECT_BY_TICKET);
   if(tckOrder){ 
      double lastResult = OrderProfit();
      double ordrOpenP = OrderOpenPrice();
      int lastCloseT = OrderCloseTime();
   }

   //+-----------------------------------+//---CONDITIONS---//+-----------------------------------+
   int tradeDirection;
   
   //BOX DEFINITION
   double buySignal, sellSignal;
   datetime ordExpire= StrToTime(TimeToStr(TimeCurrent(), TIME_DATE) + " " + orderExpireTime);
   datetime boxEnd= StrToTime(TimeToStr(TimeCurrent(), TIME_DATE) + " " + EndTime);
   
   if(TimeCurrent()>= ordExpire || TimeCurrent()< boxEnd){
      ticket=0;
      tck2=0;
      tradenum1=0;
      tradenum2=0;
      lastResult=0;
   }// END DAY RESET
   else{
      double boxHeight= BoxDefinition(Symbol(), StartTime, EndTime, "height", DrawBox, BoxColor, buySignal , sellSignal);
   }//--Box Def
   
   if(boxHeight>0){
      if(Ask-SignalBufferLong*(Point*10)>=buySignal){//Activate BUY
         tradeDirection = 1;
      }
      else if(Bid+SignalBufferShort*(Point*10)<=sellSignal){//Activate SELL
         tradeDirection = -1;
      }
   }//--Conditions End
   //Comment("B ", buySignal," S ", sellSignal," EMA ", EMA);
   
   //+-----------------------------------+//---ORDER DEFINITION---//+-----------------------------------+
   
   double TradeSize1,TradeSize2;
   int TkPft1, TkPft2,StLss1,StLss2;
   
   //TAKEPROFIT DEFINITION
   if(false){//Change condition
      //Insert alternative
   }
   else{
      TkPft1 = TP1;
      TkPft2 = TP2;
   }
   
   //STOPLOSS DEFINITION
   if(UseBoxForSL){
      StLss1 = boxHeight/(Point*10)*(Order1BoxSLPercent/100)+SignalBufferLong;
      StLss2 = boxHeight/(Point*10)*(Order2BoxSLPercent/100)+SignalBufferLong;
   }
   else{
      StLss1 = SL1;
      StLss2 = SL2;
   }
   
   //LOT DEFINITION
   if(UseRiskLotCalc){
      TradeSize1 = RiskCalc (StLss1, T1RiskPercent, RiskCalcMethod);
      TradeSize2 = RiskCalc (StLss2, T2RiskPercent, RiskCalcMethod);
   }
   else{
      TradeSize1 = Trade1Lots;
      TradeSize2 = Trade2Lots;
   }
   //+-----------------------------------+//---FILTERS---//+-----------------------------------+
   
   string filterComment;
   
   if(tradeDirection!=0){
   
      //---MA FILTER
      if(Use_Slow_MAFilter){
         if(buySignal<EMA && tradeDirection>0){
            tradeDirection=0;
           filterComment = "MA filter";
         }
         else if(sellSignal>EMA && tradeDirection<0){
            tradeDirection=0;
            filterComment = "MA filter";
         }
      }
      
      //STOP INSIDE BOX MA FILTER
      if(Stop_Inside_Box){   
         if(buySignal>EMA && sellSignal<EMA){
            tradeDirection=0;
           filterComment = "Inside Filter";
         }
      }
            
       //LAST RESULT FILTER
      if(lastResult>5){
         tradeDirection=0;
         filterComment = "Last Result filter";
      }
      
      //NUMBER OF TRADES FILTER
      if(MaxTrades<=tradenum1){
         tradeDirection=0;
         filterComment = "MaxTrade Filter";
      }
   
      //OPEN ORDER FILTER
      if(tckOrder && lastCloseT==0){
         tradeDirection=0;
      }
   
      //SPREAD FILTER
      if(MaxSpread<curSpread){
         tradeDirection=0;
         filterComment = "Spread Filter";
      }

      //ONE TRADE PER BAR FILTER
      if(One_Trade_Bar && tradeBar1==Bars){
         tradeDirection=0;
         filterComment = "One Trade Per Bar Filter";
      }
      
      //MAX BOX SIZE FILTER
      if(MaxBoxSize*(Point*10)<=boxHeight){
         tradeDirection=0;
         filterComment = "MaxBoxSize Filter";
      }

   }//--Filter End
   
   if(UseFilterComments){
      Comment(filterComment);
   }
   
   //+-----------------------------------+//---ORDERS---//+-----------------------------------+
   if(tradeDirection!=0){
      ticket = PlaceOrder(tradeDirection, TradeSize1, Slip, StLss1, TkPft1, MagicNumber, "BOX BO - Trade1",tradenum1,tradeBar1);
      if(TradeSize2>0){
         tck2 = PlaceOrder(tradeDirection, TradeSize2, Slip, StLss2, TkPft2, MagicNumber, "BOX BO - Trade2",tradenum2,tradeBar2);
      }
   }
   
   //+-----------------------------------+//---TRAILING STOP---//+-----------------------------------+
   if(UseTrail){
      EvalTrail(ticket, Target_Increment, Stop_Increment, Initial_Jump, trailTarget1, PriceReached1, nSL1);
   }
   
   //+-----------------------------------+//---BE STOP---//+-----------------------------------+
   if(Use_BE){
      EvalBE(ticket, BE_Stop, beTarget1, PriceReached1, beSL1);   ///One for each ticket(order)managed
      if(TradeSize2>0){
         EvalBE(tck2, BE_Stop, beTarget2, PriceReached2, beSL2);
      }
   }       
//----
   return(0);
  }
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int PlaceOrder(int OrdType, double Lots, int Slip, int StLoss, int TkProfit, int Magic, string Strategy, int& tradecount, int& tradeBar){
//Places a Corresponding Market order and returns ticket #, if failed returns -1
//INCREMENTS TradeBar 
   
   int ticket;
   string Journal;
   
   if(OrdType == 0) return(0);

   else if(OrdType>0){ //BUY ORDER
      Journal = StringConcatenate(Strategy," Buy Order");
      RefreshRates();
      ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slip,Ask-StLoss*(Point*10),Ask+TkProfit*(Point*10),Journal,Magic,0,Green);
      if(ticket<0) Print("OrderBUY error #",GetLastError());
      tradeBar=Bars;
      tradecount++;
      return(ticket); 
   }
   else{ //SELL ORDER
      Journal = StringConcatenate(Strategy," Sell Order");
      RefreshRates();
      ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slip,Bid+StLoss*(Point*10),Bid-TkProfit*(Point*10),Journal,Magic,0,Red);
      if(ticket<0)Print("OrderSELL error #",GetLastError());
      tradeBar=Bars; 
      tradecount++;
      return(ticket);
   }
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double RiskCalc (int SL, double RiskPct, string Type){
// Calculates Lot Size Based on a given risk and Account Balance, Type based on either account Bal or Available equity
   
   if(SL == 0) return(0);
   
   double Acct;
   double acctBal = AccountBalance();
   double acctEqt = AccountEquity();
   //double MinLot = acc
  
   if(Type == "eqt"){
      Acct = acctEqt;
   }
   else{
      Acct = acctBal;
   }
   
   double Lot = NormalizeDouble((((Acct/100)*RiskPct)/SL/10),2);
   if(Lot< 0.01){
      Lot = 0;
      Print("Risk Size too Small : LOT<0.01");
   }
   return(Lot);
}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

void EvalTrail(int Ticket, int Target_Increment, int Stop_Increment, int Initial_Jump, double& trailTarget, double& PriceReached, double& nSL){
   
   bool tckOrder = OrderSelect(Ticket,SELECT_BY_TICKET);
   int ordType = OrderType();
   double ordLots = OrderLots();
   double orderOpen = OrderOpenPrice();
   double orderSL = OrderStopLoss();
   datetime closeTime = OrderCloseTime();
   double Spread = MarketInfo(Symbol(),MODE_SPREAD)*Point;
   
   //INCREMENTAL MODE
   if(tckOrder && closeTime==0){ //terminates if tck doesn't exist or if closed
      //BUY ORDER CONTROL
      if(ordType==0){
         if(trailTarget==0){
            trailTarget = orderOpen + (Initial_Jump*(Point*10));
         }
         if(Bid>PriceReached){//Price Reached incr.
            PriceReached=Bid;
         }
         if(PriceReached>=trailTarget){// Stop and Target Incremement
            if(nSL==0){ 
               nSL = orderSL;
            }
            nSL+=(Stop_Increment*(Point*10));
            trailTarget+= (Target_Increment*(Point*10));
         }
         // BUY ORDER CLOSE
         if(Bid<=nSL && nSL!=0){// Close Order
            RefreshRates();
            OrderClose(Ticket, ordLots, Bid, Slip,Yellow);
            PriceReached = 0;
            trailTarget = 0;
            nSL = 0;
         }
      }  
      //SELL ORDER CONTROL
      else if(ordType>0){
         if(trailTarget==0){
            trailTarget = orderOpen - (Initial_Jump*(Point*10));
            PriceReached=100000;// so that price starts automatically above Price Reached
         }
         if(Ask<=PriceReached){//Price Reached incr.
            PriceReached=Ask;
         }
         if(PriceReached<=trailTarget){// Stop and Target Incremement
            if(nSL==0){ 
               nSL = orderSL;
            }
            nSL-=(Stop_Increment*(Point*10));
            trailTarget-= (Target_Increment*(Point*10));
         }
         // SELL ORDER CLOSE
         if(Ask>=nSL && nSL!=0){// Close Order
            RefreshRates();
            OrderClose(Ticket, ordLots, Ask, Slip,Yellow);
            PriceReached = 0;
            trailTarget = 0;
            nSL = 0;
         }
      }
   }
   else{ //RESETS
      PriceReached = 0;
      trailTarget = 0;
      nSL = 0;
   }
}

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

void EvalBE(int Ticket, int BE_Stop, double& BE_Target, double& PriceReached, double& BE_SL){
   
   bool tckOrder = OrderSelect(Ticket,SELECT_BY_TICKET);
   int ordType = OrderType();
   double ordLots = OrderLots();
   double orderOpen = OrderOpenPrice();
   double orderSL = OrderStopLoss();
   datetime closeTime = OrderCloseTime();
   double Spread = MarketInfo(Symbol(),MODE_SPREAD)*Point;
   
   //---LAST CLOSE TIMER---//
   if(closeTime!=0){
      int timerLCb = TimeCurrent() - closeTime;
   }
   else timerLCb = 0;    
      
      //BUY ORDER CONTROL
   if(tckOrder && closeTime==0){
      if(ordType==0){
         if(BE_Target==0){
            BE_Target = orderOpen + (BE_Stop*(Point*10));
         }
         if(Bid>PriceReached){//Price Reached incr.
            PriceReached=Bid;
         }
         if(PriceReached>=BE_Target){// B/E SET
            if(BE_SL==0){ 
               BE_SL = orderOpen;
            }
         }
         // BUY ORDER CLOSE
         if(Bid<=BE_SL && BE_SL!=0){// Close Order - - should be bid ?
            RefreshRates();
            OrderClose(Ticket, ordLots, Bid, Slip, Yellow);
            PriceReached = 0;
            BE_Target = 0;
            BE_SL = 0;
         }
      }  
      //SELL ORDER CONTROL
      else if(ordType>0){
         if(BE_Target==0){
            BE_Target = orderOpen - (BE_Stop*(Point*10));
            PriceReached=100000;// so that price starts automatically Below Price Reached
         }
         if(Ask<=PriceReached){//Price Reached incr.
            PriceReached=Ask;
         }
         if(PriceReached<=BE_Target){// B/E SET
            if(BE_SL==0){ 
               BE_SL = orderOpen;
            }
         }
         // SELL ORDER CLOSE
         if(Ask>=BE_SL && BE_SL!=0){// Close Order - - should be ask ?
            RefreshRates();
            OrderClose(Ticket, ordLots, Ask, Slip,Yellow);
            PriceReached = 0;
            BE_Target = 0;
            BE_SL = 0;
         }
      }
   }
   else{ //RESETS
      PriceReached = 0;
      BE_Target = 0;
      BE_SL = 0;
   }
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

double BoxDefinition(string Symb, string StartTime, string EndTime, string ReturnType, bool Draw, color BoxColor,double& BoxHigh, double& BoxLow){
// Calculates and Returns Box information, if curHour< than EndHour Returns 0;
// Optional - Draws Box on Chart

   int BoxLength,OffsetCalc;
   double dtOffset;
   double BoxHeight, info;
   datetime dtTimeBegin, dtTimeEnd;
   
   int curTime= TimeCurrent();
   int TF=Period();
   dtTimeBegin = StrToTime(TimeToStr(curTime, TIME_DATE) + " " + StartTime);
   dtTimeEnd = StrToTime(TimeToStr(curTime, TIME_DATE) + " " + EndTime);
   OffsetCalc = curTime - dtTimeEnd;
   dtOffset = OffsetCalc/60/TF;
   
   if(dtTimeBegin>dtTimeEnd){ //sets Start time 1 day back if Start>End
      dtTimeBegin = dtTimeBegin - 86400; // number of seconds in a day
   }
    
   BoxLength= MathAbs(dtTimeEnd - dtTimeBegin)/60/TF;

   string stime = TimeToStr(dtTimeBegin);
   string etime = TimeToStr(dtTimeEnd);
   
   if(OffsetCalc>0){
      BoxHigh= High[iHighest(Symb,TF,MODE_HIGH,BoxLength,dtOffset)];
      BoxLow= Low[iLowest(Symb,TF,MODE_LOW,BoxLength,dtOffset)];
      BoxHeight= BoxHigh - BoxLow;  
      if(ReturnType=="high"){
         info = BoxHigh;
      }
      else if(ReturnType=="low"){
         info = BoxLow;
      }
      else if(ReturnType=="height"){
         info = BoxHeight;
      }
      if(Draw){
         string BoxID = "BoxID";
         ObjectCreate(BoxID, OBJ_RECTANGLE ,0,0,0,0);
         ObjectSet(BoxID, OBJPROP_TIME1 , dtTimeBegin);
         ObjectSet(BoxID, OBJPROP_TIME2 , dtTimeEnd);
         ObjectSet(BoxID, OBJPROP_PRICE1, BoxHigh);  
         ObjectSet(BoxID, OBJPROP_PRICE2, BoxLow);
         ObjectSet(BoxID, OBJPROP_STYLE, STYLE_SOLID);
         ObjectSet(BoxID, OBJPROP_COLOR, BoxColor);
         ObjectSet(BoxID, OBJPROP_BACK, True);
      }
   }
   return(info);
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+