//+------------------------------------------------------------------+
//|   Steve Hopwood's London session breakout auto trading robot.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+

/*+------------------------------------------------------------------+
 *
 * Version history:
 *
 * V2.0: 
 *     - designed to work with "London BreakoutV8.1.mq4" indicator "exported" GobalVariables:
 *       grabs "MaxBoxSizeInPips", "StartTime", "EndTime", and "SessionEndTime"
 *
 * V1: original version from SteveHopwood at forexfactory.com
 *     - designed to work with "London BreakoutV8.mq4" indicator "exported" GobalVariables:
 *
 *+------------------------------------------------------------------+
 */



#property show_inputs
#include <WinUser32.mqh>
#include <stdlib.mqh>


#define  EA_VERSION    "V2.0"

#define  NL    "\n"
#define  Status_initializing "????? I N I T I A L I Z I N G ?????"
#define  Status_trading "+++++ T R A D I N G +++++"
#define  Status_not_trading "!!!!! N O T   T R A D I N G !!!!!"
#define  Status_finished "----- F I N I S H E D   F O R   T O D A Y -----"

/*

void DisplayUserFeedback()

start()

----Trading functions----
void SendSingleTrade(int type)
void GetTradingStatus()
bool DoesTradeExist(int type)
GetAggregatePosition()
int LossesCount()


----Trade management-----
void ManageTrades()
void ShouldHalfTradeClose()
void OneCancelsTheOther()




----Misc----


*/




extern string     bs="----Basic stuff----";
extern double     Lot=0.02;
extern int        MagicNumber=8682371;
extern string     TradeComment="----London breakout";
//extern bool       AllowReEntries=false;
extern string     mta="----MaxTradesAllowedForTheDay = 0";
extern string     mtaa="----means no limit on trades";
extern int        MaxTradesAllowedForTheDay=0;
extern string     mla="----MaxLossesAllowedPerPair = 0";
extern string     mlaa="----means no limit on losses";
extern int        MaxLossesAllowedPerPair=2;
extern string     objPrefix = "LB-";  // Prefix of London Breakout Indicator objects;
extern string     tm="----Trade management----";
extern bool       UseSelectedManagementFunctions=true;
extern string     hcf="----Half-close function";
extern bool       AllowHalfClose=true;
extern int        BreakEvenProfitInPips=5; // in pips, not Points
extern string     oco="----OCO will delete remaining pending";
extern string     oco1="----when its partner fills";
extern bool       OneCancelsTheOther=false;
/*
extern string     tt="----Trading hours. Use local time----";
extern string     Trade_Hours= "Set Morning & Evening Hours 24hr";
extern string     Trade_Hours_M= "Morning Hours 0-12";
extern  int       start_hourm = 7;
extern  int       end_hourm = 12;
extern string     Trade_Hours_E= "Evening Hours 12-24";
extern  int       start_houre = 12;
extern  int       end_houre = 16;
extern string     wei="----Week ending inputs----";
extern bool       FridayStopTrading=true;
extern bool       SaturdayStopTrading=false;
extern int        StopTradingHour = 12;
*/
//extern string     mrt="----Martingale----";
//extern string     mrt1="DO NOT USE THIS. IT WILL BLOW YOUR ACCOUNT";
//extern string     mrt2="MARTINGALE IS AN ACCOUNT KILLER";
//extern bool       UseMartingale=true;
//extern int        MaxMartingaleSteps=3;
extern string     oae="----Odds and ends----";
extern int        DisplayGapSize=10;


//Entry, stop and tp
double  LongPendingEntryPrice;
double  LongTP;
double  LongSL;
double  ShortPendingEntryPrice;
double  ShortTP;
double  ShortSL;

string  StartTime;         // time for start of price establishment window
string  EndTime;           // time for end of price establishment window
string  SessionEndTime;    // end of daily session; tomorrow is another day!
int     MaxBoxSizeInPips;  // box size limit to show Red "NO TRADE" box

double     LondonOpens;
double     LondonCloses;

//Open trades\trade direction.
int               NoOfTrades;
string            TradingStatus;

//Trading hours
bool              ClosedForFriday;
bool              ClosedForSaturday;

//Hi-lo variables
//double            bhighest, blowest;//Box highest and lowest


//Open trades\trade direction.
bool              TradeOpen;
int               TicketNo, LongTicketNo, ShortTicketNo;

//Aggregates
int               open, won, lost, total;

//Misc stuff
string            comment, Gap;
bool              RobotDisabled;
string            DisabledMessage;
int               Spread, Decimals;
double pip;
int digits;


//+------------------------------------------------------------------+
void DisplayUserFeedback()
//+------------------------------------------------------------------+
{

   comment = StringConcatenate(Gap, WindowExpertName(), " ", EA_VERSION, NL);
   comment = StringConcatenate(comment, Gap, "Lot size = ", Lot, NL);
   comment = StringConcatenate(comment, Gap, "Magic number = ", MagicNumber, NL);
   comment = StringConcatenate(comment, Gap, "Trade comment = ", TradeComment, NL);
   comment = StringConcatenate(comment, Gap, "Local time: ", TimeToStr(TimeLocal()), " Broker time: ", TimeToStr(TimeCurrent()), NL);
   comment = StringConcatenate(comment, Gap, "Long Entry: ", DoubleToStr(LongPendingEntryPrice, Digits), ", TP: ", DoubleToStr(LongTP, Digits), ", SL: ", DoubleToStr(LongSL, Digits), NL);
   comment = StringConcatenate(comment, Gap, "Short Entry: ", DoubleToStr(ShortPendingEntryPrice, Digits), ", TP: ", DoubleToStr(ShortTP, Digits), ", SL: ", DoubleToStr(ShortSL, Digits), NL);
   comment = StringConcatenate(comment, Gap, "Trading Hours: ", DoubleToStr(LondonOpens/100,2), " - ", DoubleToStr(LondonCloses/100,2), NL);
   if (UseSelectedManagementFunctions)
   {
      comment = StringConcatenate(comment, Gap, "Using management functions:",NL);
      if (AllowHalfClose) comment = StringConcatenate(comment,     Gap, "     Using half - close",NL);
      else                comment = StringConcatenate(comment,     Gap, "     NOT Using half - close",NL);
      comment =                     StringConcatenate(comment,     Gap, "     Break even profit: ", BreakEvenProfitInPips, "pips", NL);
      if (OneCancelsTheOther) comment = StringConcatenate(comment, Gap, "     OCO ON:   Closing parter pending trade when one fills", NL);
      else                    comment = StringConcatenate(comment, Gap, "     OCO OFF: NOT Closing parter pending trade when one fills", NL);
   }//if (UseSelectedManagementFunctions)
   
   /*comment = StringConcatenate(comment, Gap, "AM trade hour start = ", start_hourm, NL);
   comment = StringConcatenate(comment, Gap, "AM trade hour end = ", end_hourm, NL);
   comment = StringConcatenate(comment, Gap, "PM trade hour start = ", start_houre, NL);
   comment = StringConcatenate(comment, Gap, "PM trade hour end = ", end_houre, NL);
   if (FridayStopTrading) comment= StringConcatenate(comment, Gap, "Friday close = ", DoubleToStr(StopTradingHour, 2), NL);
   if (SaturdayStopTrading) comment= StringConcatenate(comment, Gap, "Saturday close = ", DoubleToStr(StopTradingHour, 2), NL);
   comment = StringConcatenate(comment, Gap, "MaxTradesAllowedForTheDay = ", MaxTradesAllowedForTheDay, NL);
   if (AllowReEntries) comment = StringConcatenate(comment, Gap, "Allowing re-entries outside the box",NL);
   else comment = StringConcatenate(comment, Gap, "Not allowing re-entries outside the box",NL);
   comment = StringConcatenate(comment, Gap, "MaxLossesAllowedPerPair = ", MaxLossesAllowedPerPair, NL);
   */
   /*if (UseMartingale)
   {
      comment = StringConcatenate(comment, Gap, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", NL);
      comment = StringConcatenate(comment, Gap, "YOU HAVE ELECTED TO USE MARTINGALE. YOU ARE AN IDIOT. TURN IT OFF NOW", NL);
      comment = StringConcatenate(comment, Gap, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", NL);      
   }//if (UseMartingale)
   */

   comment = StringConcatenate(comment, Gap, EA_VERSION, " " , TradingStatus, NL);

   Comment(comment);
}//void DisplayUserFeedback()


//+------------------------------------------------------------------+
int init()
//+------------------------------------------------------------------+
{

   TradingStatus = Status_initializing;

   getpip();

   if (!IsDemo() )
   {
      if (MagicNumber == 8682371)
      {
         MessageBox("You cannot run this robot until changed the MagicNumber input from the default of 8682371." + NL 
                    + "Please reload the robot with a new MagicNumber input.");
         Comment("                This robot can do nothing. Please reload it");
         DisabledMessage = "You need to change the MagicNumber input";
         RobotDisabled = true;
         return;
      }//if (MagicNumber == 4872635)
      
      //Insufficient length
      string mn = DoubleToStr(MagicNumber,0);
      if (StringLen(mn) < 5)
      {
         MessageBox("Your MagicNumber input needs to be at least 5 Digits long, Your MagicNumber is " + mn + NL 
                    + "Please reload the robot with the MagicNumber input containing at least 5 Digits - the more the better.");
         Comment("                This robot can do nothing. Please reload it");
         DisabledMessage = "You need to make the MagicNumber input at 5 Digits long - more is better";
         RobotDisabled = true;
         return;
      }//if (StringLen(mn) < 5)     
      
   }//if (!IsDemo)
   
   
    int Step = MarketInfo(Symbol(),MODE_LOTSTEP);
    
    if(Step == 0.01) Decimals = 2;
    if(Step == 0.10) Decimals = 1;
    if(Step == 1.00) Decimals = 0;
    
   Gap=""; for (int cc=0; cc< DisplayGapSize; cc++) Gap = StringConcatenate(Gap, " ");
   
   GetPosition();   
   
      
   Comment(".........Waiting for a tick");
   DisplayUserFeedback();
   
   return(0);
    
  }
  
//+------------------------------------------------------------------+
int deinit()
//+------------------------------------------------------------------+
  {

    Comment("");
    
    return(0);

  }
  

//+------------------------------------------------------------------+
void GetPosition()
//+------------------------------------------------------------------+
{

   NoOfTrades = 0;
   if (OrdersTotal() == 0 ) return;
   
   for(int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
       if(!OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) ) continue;
         
       if(OrderMagicNumber() == MagicNumber)
       {
           NoOfTrades++;
       }//if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         
   }//for(int cc = 0; cc <= OrdersTotal(); cc++)
 
 
}//void GetPosition(string Symbol())


//+------------------------------------------------------------------+
bool DoesTradeExist(int type)
//+------------------------------------------------------------------+
{
   //Searches for open trades
   
   if (OrdersTotal() == 0) return(false); //nothing to do

   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {      
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() ) 
      {
         if (type == 0  && (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP) )
         {
            return(true);
         }//if (type == OP_BUY  && (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP) )   
         
         if (type == 1  && (OrderType() == OP_SELL || OrderType() == OP_SELLSTOP) )
         {
            return(true);
         }//if (type == OP_BUY  && (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP) )   
      }//if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())       
   }//for (int cc = OrdersTotal() - 1; cc >= 0, cc--)  
   
   return(false);
   
}//void DoesTradeExist(int type)


//+------------------------------------------------------------------+
void SendSingleTrade(int type)
//+------------------------------------------------------------------+
{
   // Attempts to place a trade according to type, i.e.
   // 0 = OP_BUY
   // 1 = OP_SELL
   
   // Check spread
   
   RefreshRates();
   
   double StopLoss, TradePrice, TakeProfit;
   int ticket;   
   
   double LotsToSend = Lot;
   //Martingale code
   /*if (UseMartingale && lost > 0)
   {
   
   }//if (UseMartingale && lost > 0)
   */
   

   //Buy stop trade
   if (type == OP_BUYSTOP)
   {
      ticket = OrderSend(Symbol(), OP_BUYSTOP, Lot, LongPendingEntryPrice, 0, LongSL, LongTP, TradeComment, MagicNumber, 0,Green);
      if (ticket < 0)
      {
         int err=GetLastError();
         Alert("Pending long order send failed with error(",err,"): ",ErrorDescription(err));
         Print("Order send failed with error(",err,"): ",ErrorDescription(err));
         Sleep(500);         
      }//if (ticket < 0)
      else Sleep(500);

   }//if (type == 4)

   
   //Sell stop trade
   if (type == OP_SELLSTOP)
   {
      ticket = OrderSend(Symbol(), OP_SELLSTOP, Lot, ShortPendingEntryPrice, 0, ShortSL, ShortTP, TradeComment, MagicNumber, 0,Green);
      if (ticket < 0)
      {
         err=GetLastError();
         Alert("Pending Short order send failed with error(",err,"): ",ErrorDescription(err));
         Print("Order send failed with error(",err,"): ",ErrorDescription(err));
         Sleep(500);
         return(false);
      }//if (ticket < 0)
      
   }//if (type == 4)
   
   
   
   
}//void SendSingleTrade(int type)



//+------------------------------------------------------------------+
void GetAggregatePosition()
//+------------------------------------------------------------------+
{
   //returns the total trades for the pair - open, won, lost, also the ticket nos for open trades
   
   open = 0;
   won = 0;
   lost = 0;
   total = 0;
   LongTicketNo = 0;
   ShortTicketNo = 0;
   
   
   //Open trades
   if (OrdersTotal() > 0)
   {
      for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
      {      
         if (!OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) ) continue;
         if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() && OrderCloseTime() == 0)
         {
            open++;
            if (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP) LongTicketNo = OrderTicket();
            if (OrderType() == OP_SELL || OrderType() == OP_SELLSTOP) ShortTicketNo = OrderTicket();
         }//if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())       
      }//for (int cc = OrdersTotal() - 1; cc >= 0, cc--)  
   }//if (OrdersTotal() > 0)
   
   //History tab
   if (OrdersHistoryTotal() == 0) 
   {
      total = open + lost + won;
      return;
   }//if (OrdersHistoryTotal() == 0) 
   
   for (cc = OrdersHistoryTotal() - 1; cc >= 0; cc--)
   {      
      OrderSelect(cc, SELECT_BY_POS, MODE_HISTORY);
      if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())       
      {
         if (OrderProfit() < 0) lost++;
         if (OrderProfit() > 0) won++;         
      }//if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())       
   }//for (int cc = OrdersTotal() - 1; cc >= 0, cc--)  
   
   total = open + lost + won;
      
   
   
}//void GetAggregatePosition()

//+------------------------------------------------------------------+
int LossesCount()
//+------------------------------------------------------------------+
{
    int Cnt=0;
    for(int i = OrdersHistoryTotal()-1; i>=0; i--)
    {
      OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
      if (TimeDayOfWeek(OrderCloseTime()) == TimeDayOfWeek(TimeCurrent()) )
      {
         if(OrderProfit()>=0) break;
         Cnt++;
      }//if (TimeDayOfWeek(OrderCloseTime() == TimeDayOfWeek(TimeCurrent())
         
    }//for(int i = OrdersHistoryTotal()-1; i>=0; i--)
    return(Cnt);
}//End int LossesCount()

//+------------------------------------------------------------------+
void GetTradingStatus()
//+------------------------------------------------------------------+
{
   //The initial trade stops are the extent of the box
   
   if (MaxBoxSizeInPips > 0 && ShortSL - LongSL > MaxBoxSizeInPips * pip) TradingStatus = Status_not_trading;

}//End void GetTradingStatus()

//+------------------------------------------------------------------+
void ShouldHalfTradeClose()
//+------------------------------------------------------------------+
{
   //Only called if selected trade is in profit/
   //Closes half the trade at profit of tp / 2
   
   //Long
   if (OrderType() == OP_BUY)
   {
      double HcPrice = NormalizeDouble((OrderTakeProfit() + OrderOpenPrice()) / 2, Digits);//Half close price
      if (Ask > HcPrice)
      {
        bool result = OrderClose(OrderTicket(),OrderLots() / 2, OrderClosePrice(),5*pip,Red);
        if (!result)
        {
             int err=GetLastError();
             Alert("LB EA: ", Symbol(), " #",OrderTicket(), " part-close failed with error(",err,"): ",ErrorDescription(err));
             return;
        }//if (!result)
        //Get new ticket number
        Sleep(100);
        result = DoesTradeExist(OP_BUY);//Re-selects the half-closed trade
        if (OrderStopLoss() < OrderOpenPrice() )
        {
           double SL = OrderOpenPrice();
           result = OrderModify(OrderTicket(), OrderOpenPrice(), SL, OrderTakeProfit(), 0, Green);
           if (!result)
            {
                err=GetLastError();
                Alert("LB EA: ", Symbol(), " #",OrderTicket(), " Stop loss move failed with error(",err,"): ",ErrorDescription(err));
                return;
            }//if (!result)     
        }//if (OrderStopLoss() < OrderOpenPrice() )
     }//if (Ask > HcPrice)      
   }//if (OrderType() == 0)
   
   //Short
   if (OrderType() == OP_SELL)
   {
      HcPrice = NormalizeDouble((OrderOpenPrice() + OrderTakeProfit()) / 2, Digits);//Half close price
      if (Bid < HcPrice)
      {
         result = OrderClose(OrderTicket(),OrderLots() / 2, OrderClosePrice(),5*pip,Red);
         if (!result)
         {
             err=GetLastError();
             Alert("LB EA: ", Symbol(), " #",OrderTicket(), " part-close failed with error(",err,"): ",ErrorDescription(err));
             return;
         }//if (!result)
        //Get new ticket number
        Sleep(100);
        result = DoesTradeExist(OP_SELL);//Re-selects the half-closed trade
        OrderSelect(TicketNo, SELECT_BY_TICKET);
        if (OrderStopLoss() < OrderOpenPrice() )
        {
           SL = OrderOpenPrice();
           result = OrderModify(OrderTicket(), OrderOpenPrice(), SL, OrderTakeProfit(), 0, Green);
           if (!result)
            {
                err=GetLastError();
                Alert("LB EA: ", Symbol(), " #",OrderTicket(), " Stop loss move failed with error(",err,"): ",ErrorDescription(err));
                return;
            }//if (!result)     
        }//if (OrderStopLoss() < OrderOpenPrice() ) 
      }//if (Bid < HcPrice)      
   }//if (OrderType() == 1)
   

}//End void ShouldHalfTradeClose()

//+------------------------------------------------------------------+
void ManageTrades()
//+------------------------------------------------------------------+
{
   //Called if there are any open trades
   for (int cc = OrdersTotal() - 1; cc >=0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderMagicNumber() ==  MagicNumber && OrderSymbol() == Symbol() )
      {
         TicketNo = OrderTicket();
         
         //Partial trade closure
         OrderSelect(TicketNo, SELECT_BY_TICKET);//Should not need re-selecting, but just in case
         
         
         //Half close
         if (AllowHalfClose)
         {
            if (OrderCloseTime() == 0 && OrderProfit() > 0 && OrderLots() == Lot)
            {
               ShouldHalfTradeClose();
            }//if (OrderCloseTime() == 0 && OrderProfit() > 0)
         }//if (AllowHalfClose)

         //OCO
         if (OneCancelsTheOther)
         {
            OneCancelsTheOther();
         }//if (OneCancelsTheOther)
         
         
         //Pick up on any failed stop move to breakeven
         if (OrderType() == OP_BUY)
         {
            if (OrderLots() < Lot && OrderStopLoss() < OrderOpenPrice() )
            {
               OrderModify(TicketNo, OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() + (BreakEvenProfitInPips * pip), Digits), OrderTakeProfit(), OrderExpiration(), Green);
            }//if (OrderLots() < Lot && OrderStopLoss() < OrderOpenPrice() )            
         }//if (OrderType() == OP_BUY)
         
         if (OrderType() == OP_SELL)
         {
            if (OrderLots() < Lot && OrderStopLoss() > OrderOpenPrice() )
            {
               OrderModify(TicketNo, OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() - (BreakEvenProfitInPips * pip), Digits), OrderTakeProfit(), OrderExpiration(), Green);
            }//if (OrderLots() < Lot && OrderStopLoss() < OrderOpenPrice() )            
         }//if (OrderType() == OP_SELL)
         
      }
   }//for (int cc = OrdersTotal() - 1; cc >=0)

}//End void ManageTrades()

//+------------------------------------------------------------------+
void OneCancelsTheOther()
//+------------------------------------------------------------------+
{
   //Deletes a pending trade when its partner has filled

   OrderSelect(LongTicketNo, SELECT_BY_TICKET);
   if (OrderType() == OP_BUY) OrderDelete(ShortTicketNo);
   if (OrderType() == OP_SELL) OrderDelete(LongTicketNo);

   OrderSelect(ShortTicketNo, SELECT_BY_TICKET);
   if (OrderType() == OP_BUY) OrderDelete(ShortTicketNo);
   if (OrderType() == OP_SELL) OrderDelete(LongTicketNo);

}//End void OneCancelsTheOther()



//+------------------------------------------------------------------+
void CloseAllTrades()
//+------------------------------------------------------------------+
{
   bool result;
   int err;
   
   Alert("LB EA: ", Symbol(), " CLOSING ALL ORDERS NOW !!!");

   for (int cc = OrdersTotal() - 1; cc >=0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;

      if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() && OrderCloseTime() == 0) {

        switch (OrderType()) {
          // close open trades
          case OP_BUY:  result = OrderClose(OrderTicket(),OrderLots(),Bid,5*pip,Red); break;
          case OP_SELL: result = OrderClose(OrderTicket(),OrderLots(),Ask,5*pip,Red); break;
            // delete pending orders
          default:      result = OrderDelete(OrderTicket()); break;
        }

        if (!result)
        {
          err=GetLastError();
          Alert("LB EA: ", Symbol(), " FAILED with error(",err,"): ",ErrorDescription(err));
          return;
        }//if (!result)
    }
   }
}


//+------------------------------------------------------------------+
int start()
//+------------------------------------------------------------------+
{
    
      if (RobotDisabled )
      {
         Comment("The robot has been suspended. Reason: ", DisabledMessage);
         return;
      }//if (RobotDisabled )


      // import_LB_Indi_LEVELS -- available since "London BreakoutV8.mq4" indicator
      LongPendingEntryPrice = GlobalVariableGet(objPrefix+Symbol()+"-LongEntry");
      ShortPendingEntryPrice = GlobalVariableGet(objPrefix+Symbol()+"-ShortEntry");
      LongTP = GlobalVariableGet(objPrefix+Symbol()+"-LongTP");
      ShortTP = GlobalVariableGet(objPrefix+Symbol()+"-ShortTP");
      LongSL = GlobalVariableGet(objPrefix+Symbol()+"-LongSL");
      ShortSL = GlobalVariableGet(objPrefix+Symbol()+"-ShortSL");

      //import_LB_Indi_SETTINGS -- available since "London BreakoutV9.mq4" indicator
      StartTime          = time_int_to_string(GlobalVariableGet(objPrefix+Symbol()+"-StartTime"));
      EndTime            = time_int_to_string(GlobalVariableGet(objPrefix+Symbol()+"-EndTime"));
      SessionEndTime     = time_int_to_string(GlobalVariableGet(objPrefix+Symbol()+"-SessionEndTime"));
      MaxBoxSizeInPips   = GlobalVariableGet(objPrefix+Symbol()+"-MaxBoxSizeInPips");


      // setup session open/close times
      LondonOpens  = time_string_to_int(EndTime);
      LondonCloses = time_string_to_int(SessionEndTime);
//Alert (objPrefix+Symbol()+"-SessionEndTime"+" "+SessionEndTime);

      /*
      //Check Friday close
      if (FridayStopTrading)
      {
         ClosedForFriday = false;
         if (TimeHour(TimeLocal() ) >= StopTradingHour && TimeDayOfWeek(TimeLocal() ) == 5)
         {
            ClosedForFriday = true;
            DisplayUserFeedback();
            return;
         }//if (TimeHour(TimeLocal()) >= StopTradingHour && DayOfWeek() == 5)
      }//if (FridayStopTrading)
     
      //Check Saturday close for Aitipodeans
      if (SaturdayStopTrading)
      {
         ClosedForSaturday = false;
         if (TimeHour(TimeLocal() ) >= StopTradingHour && TimeDayOfWeek(TimeLocal() ) == 6)
         {
            ClosedForSaturday = true;
            DisplayUserFeedback();
            return;
         }//if (TimeHour(TimeLocal()) >= StopTradingHour && DayOfWeek() == 5)
      }//if (Saturday)
      */

   
         
       if (!IsTradeAllowed())
       {
            Comment("Trading disabled by the criminal pillock. Please wait for him to get out of bed.");
            return;
       }//if (!IsTradeAllowed)
       


      //Trading hours
      bool TradeHour = false;
      int now = TimeHour(TimeLocal())*100 + TimeMinute(TimeLocal());
      if (LondonOpens <= LondonCloses && (now >= LondonOpens && now <  LondonCloses)) TradeHour = true;
      if (LondonOpens >  LondonCloses && (now <  LondonOpens || now >= LondonCloses)) TradeHour = true;
      if (!TradeHour)
      {
        //Alert (finished+LondonCloses);
         if (TradingStatus != Status_finished) {
           CloseAllTrades();
         }
         TradingStatus = Status_finished;
         DisplayUserFeedback();
         return;
      }//if (!TradeHour)


      GetAggregatePosition();            

      if (OrdersTotal() > 0 && UseSelectedManagementFunctions) {
        //-----------------------
          ManageTrades();
        //-----------------------
      }
      

      //Max trades filter
      if (MaxTradesAllowedForTheDay > 0)// 0 means unlimited trades
      {                
          if (total >= MaxTradesAllowedForTheDay) 
          {
            TradingStatus = Status_finished;
            DisplayUserFeedback();
            return;
         }//if (total >= MaxTradesAllowedForTheDay) 
          
      }//if (MaxTradesAllowedForTheDay > 0)

      //Max loss filter
      if (MaxLossesAllowedPerPair > 0)
      {
         int lost = LossesCount();
         if (lost >= MaxLossesAllowedPerPair) 
         {
            TradingStatus = Status_finished;
            DisplayUserFeedback();
            return;
         }//if (lost >= MaxLossesAllowedPerPair) 
      }//if (MaxLossesAllowedPerPair > 0)
   
   
      
      GetTradingStatus();
      if (TradingStatus == Status_not_trading)
      {
         DisplayUserFeedback();
         return;
      }
   
  
      if (IsTradeAllowed())
      {                    
         TradingStatus = Status_trading;

         RefreshRates();
      
         //Make sure the robot does not repeatedly resend pendings deleted by oco
         if (LongTicketNo > 0)
         {
            OrderSelect(LongTicketNo, SELECT_BY_TICKET);
            if (OrderType() == OP_BUY && OrderCloseTime() == 0) return;            
         }//if (LongTicketNo > 0)
         
         if (ShortTicketNo > 0)
         {
            OrderSelect(ShortTicketNo, SELECT_BY_TICKET);
            if (OrderType() == OP_SELL && OrderCloseTime() == 0) return;            
         }//if (ShortTicketNo > 0)
         
         
         //If market is in the box, then check to see if trades need sending, and send them if so
         if (Ask < LongPendingEntryPrice && Bid > ShortPendingEntryPrice)
         {
            //Long 
            bool TradeExists = DoesTradeExist(0);
            if (!TradeExists) SendSingleTrade(OP_BUYSTOP);
            //Short
            TradeExists = DoesTradeExist(1);
            if (!TradeExists) SendSingleTrade(OP_SELLSTOP);
         }//if (Ask < l_high[cc] && Bid > l_low[cc])
      
         /*
         //If market is outside the box, look for reentry opportunities after a retrace
         //Long 
         if (AllowReEntries)
         {
            double extent = bhighest - blowest;
            if (Ask < LongEntryPrice && Ask >= bhighest)
            {
               TradeExists = DoesTradeExist(Symbol(), 0);
               if (!TradeExists) SendSingleTrade(OP_BUYSTOP, Symbol(), bhighest, blowest);                  
            }//if (Ask < LongEntry && Ask >= bhighest)
      
            //Short
            double ShortEntryPrice = GetEntryPrice(extent, 1, Symbol(), blowest);
            if (Bid > ShortEntryPrice && Bid <= blowest)
            {
               TradeExists = DoesTradeExist(Symbol(), 1);
               if (!TradeExists) SendSingleTrade(OP_SELLSTOP, Symbol(), bhighest, blowest);
            }//if (Bid > ShortEntryPrice && Digits <= blowest)
         }//if (AllowReEntries)
         */

      
      }//if (IsTradeAllowed() )
            
      
    
    DisplayUserFeedback();
      
    return(0);

}//End start()

//+------------------------------------------------------------------+
void getpip()
//+------------------------------------------------------------------+
{
   if(Digits==2 || Digits==4) pip = Point;
   else if(Digits==3 || Digits==5) pip = 10*Point;
   else if(Digits==6) pip = 100*Point;
      
	if (Digits == 3 || Digits == 2) digits = 2;
	else digits = 4;
} /* getpip*/


//--------------------------------------------------------------------------------------
int time_string_to_int(string ts)
//--------------------------------------------------------------------------------------
// convert a time string "hh:mm" into an integer hhmm
{
  int t;
  t = StrToTime("1970.01.01 " + ts)/60;
  return (MathRound(t/60)*100+(t%60));
}

//--------------------------------------------------------------------------------------
string time_int_to_string(int t)
//--------------------------------------------------------------------------------------
// convert a time integer hhmm into a string "hh:mm"
{
  if (t>9999) return (StringSubstr(TimeToStr(t),11,5)); // time value includes DATE -- compatible with Indicator < V9
  return ((t/100)+":"+(t%100)); // time is in hhmm integer format (e.g 1400 for "14:00")
}

//end

