//+------------------------------------------------------------------+
//|                Middleastern GBPJPY correlation trading robot.mq4 |
//|                                  Copyright © 2009, Steve Hopwood |
//|                              http://www.hopwood3.freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Steve Hopwood"
#property link      "http://www.hopwood3.freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"
#define  up "Up"
#define  down "Down"
#define  none "None"

/*
   for (int cc = OrdersTotal(); cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderMagicNumber()==MagicNumber)      
      {
            
      }//if (OrderMagicNumber()==MagicNumber)
   }//for (int cc=0; cc<OrdersTotal(); cc++)


void DisplayUserFeedback()
bool DoesTradeExist()
string GetTradeDirection()
bool SendSingleTrade(int type)
bool ShouldRobotSleep()

*/

extern double           Lot=0.01;
extern int              StopLoss=300;
extern int              TakeProfit=200;
extern int              MagicNumber=39927856;
extern string           TradeComment="ME correlation";
extern bool             CriminalIsECN=false;
extern string           tt="----Trading hours----";
extern int              TradeHourStart=0;
extern int              TradeHourStop=24;
extern int              SleepAfterTradeClosesMins=60;
extern string           ps="----Pairs----";
extern string           TradePair="GBPJPY";
extern string           CorrPair1="USDJPY";
extern string           CorrPair2="GBPUSD";
extern string     sls="----Trade management----";
extern bool       EaManagesTrades=true;
extern bool       HideStopLossEnabled=false;
extern int        HiddenStopLossPips=200;
extern bool       HideTakeProfitEnabled=false;
extern int        HiddenTakeProfitPips=200;
extern string     JSL="Jumping stop loss";
extern bool       JumpingStop=true;
extern int        JumpingStopPips=300;
extern bool       AddBEP=true;
extern int        BreakEvenProfit=20;
extern bool       HideJumpingStop=false;
extern int        PipsAwayFromVisualJS=100;
extern string     TSL="Trailing stop loss";
extern bool       TrailingStop=false;
extern int        TrailingStopPips=500;
extern bool       HideTrailingStop=false;
extern int        PipsAwayFromVisualTS=100;
extern string           oae="----Odds and ends----";
extern int              DisplayGapSize=30;

//Misc stuff
string            ScreenMessage, Gap;
int               OldTradePairBars;
int               OldCorr1Bars;
int               OldCorr2Bars;
double            MinCandleLength=100;
double            MinOpenCloseSpread=50;

void DisplayUserFeedback()
{

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "TradePair = ", TradePair, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CorrPair1 = ", CorrPair1, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CorrPair2 = ", CorrPair2, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Lot size = ", Lot, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "TakeProfit = ", TakeProfit, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "StopLoss = ", StopLoss, NL);
   if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CriminalIsECN = true          ", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CriminalIsECN = false          ", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number = ", MagicNumber, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Trade comment = ", TradeComment, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "TradeHourStart = ", TradeHourStart, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "TradeHourStop = ", TradeHourStop, NL);
   ScreenMessage=StringConcatenate(ScreenMessage, Gap, "The robot will sleep for ", SleepAfterTradeClosesMins, " mins after a trade closure",NL);
   if (EaManagesTrades)
   {
      ScreenMessage = StringConcatenate(ScreenMessage, NL, Gap, "Management features:");
      if (HideStopLossEnabled)
      {
        ScreenMessage = StringConcatenate(ScreenMessage, NL, Gap, "Hidden stop loss is enabled. Hidden stop = ", HiddenStopLossPips, "pips");
      }//if (HideStopLossEnabled)
   
      if (HideTakeProfitEnabled)
      {
        ScreenMessage = StringConcatenate(ScreenMessage, NL, Gap, "Hidden take profit is enabled. Hidden stop = ", HiddenTakeProfitPips, "pips");
      }//if (HideStopLossEnabled)
        
      if(JumpingStop==true)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,  NL, Gap, "Jumping stop set to ", JumpingStopPips);
         if (HideJumpingStop)  ScreenMessage = StringConcatenate(ScreenMessage, " (HideJumpingStop = true: PipsAwayFromVisualJS = ", PipsAwayFromVisualJS, ")");
         if(AddBEP==true)
         {
            ScreenMessage = StringConcatenate(ScreenMessage, ", also adding BreakEvenProfit (", BreakEvenProfit, " pips)");      
         }      
      }
      else
      {
         ScreenMessage = StringConcatenate(ScreenMessage, NL, Gap, "Jumping stop disabled");
      }
   
      if(TrailingStop==true)
      {
         ScreenMessage = StringConcatenate(ScreenMessage, NL, Gap, "Trailing stop on and set to ", TrailingStopPips);
         if (HideTrailingStop)  ScreenMessage = StringConcatenate(ScreenMessage, " (HideTrailingStop = true: PipsAwayFromVisualTS = ", PipsAwayFromVisualTS, ")");
      }
      else
      {
         ScreenMessage = StringConcatenate(ScreenMessage, NL, Gap, "Trailing stop disabled");
      }
   }//if (EaManagesTrades)   
   
   //ScreenMessage = StringConcatenate(ScreenMessage, Gap, "--", NL);
   Comment(ScreenMessage);

}//void DisplayUserFeedback()

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   
/* extern string     sls="----Trade management----";
extern bool       HideJumpingStop=false;
extern int        PipsAwayFromVisualJS=100;
extern string     TSL="Trailing stop loss";
extern bool       TrailingStop=false;
extern int        TrailingStopPips=500;
extern bool       HideTrailingStop=false;
extern int        PipsAwayFromVisualTS=100;
extern bool       TrailAfterBreakevenOnly=false;
*/
  
   //Adjust settings for 4 digit crim
   if (Digits == 2 || Digits == 4)
   {
      TakeProfit/= 10;
      StopLoss/= 10;
      MinCandleLength/= 10;
      MinOpenCloseSpread/= 10;
      HiddenStopLossPips/= 10;
      HiddenTakeProfitPips/= 10;
      JumpingStopPips/= 10;
      BreakEvenProfit/= 10;
      PipsAwayFromVisualJS/= 10;
      TrailingStopPips/= 10;
      PipsAwayFromVisualTS/= 100;
   }//if (Digits == 2 || Digits == 4)
   
   //Set up chart suffix
   string AddChar = StringSubstr(Symbol(),6,4);
   TradePair="GBPJPY" + AddChar;
   CorrPair1="USDJPY" + AddChar;
   CorrPair2="GBPUSD" + AddChar;
   
   
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }

   //start();
   //return;
   
   OldTradePairBars = Bars;
   OldCorr1Bars = iBars(CorrPair1, 0);
   OldCorr2Bars = iBars(CorrPair2, 0);
   
   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   
//----
   return(0);
}

bool DoesTradeExist()
{
   if (OrdersTotal() == 0) return(false);
   
   for (int cc = OrdersTotal(); cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
      {
         if (EaManagesTrades) ManageTrade();
         return(true);   
      }//if (OrderMagicNumber()==MagicNumber)
   }//for (int cc=0; cc<OrdersTotal(); cc++)

   //Got this far, so no trade is open
   return(false);

}//bool DoesTradeExist()

string GetTradeDirection()
{
   //Test the conditions for sending a trade
   
   
   //Candle length
   double point = MarketInfo(CorrPair1, MODE_POINT);
   double CL = iHigh(CorrPair1, 0, 1) - iLow(CorrPair1, 0, 1);    
   if (CL < (MinCandleLength * point) ) return(none);
   //CL = iHigh(CorrPair1, 0, 2) - iLow(CorrPair1, 0, 2);
   //if (CL < (MinCandleLength * point) ) return(none);
   
   point = MarketInfo(CorrPair2, MODE_POINT);
   CL = iHigh(CorrPair2, 0, 1) - iLow(CorrPair2, 0, 1);
   if (CL < (MinCandleLength * point) ) return(none);
   //CL = iHigh(CorrPair2, 0, 2) - iLow(CorrPair2, 0, 2);
   //if (CL < (MinCandleLength * point) ) return(none);
   
   //Open/close distance must be at least MinOpenCloseSpread
   point = MarketInfo(TradePair, MODE_POINT);
   CL = MathAbs(iOpen(TradePair, 0, 1) - iClose(TradePair, 0, 1) );
   if (CL < MinOpenCloseSpread * point) return(none);
   
   if (iClose(CorrPair1, 0, 1) > iOpen(CorrPair1, 0, 1) && iClose(CorrPair2, 0, 1) > iOpen(CorrPair2, 0, 1) ) return(up);
   if (iClose(CorrPair1, 0, 1) < iOpen(CorrPair1, 0, 1) && iClose(CorrPair2, 0, 1) < iOpen(CorrPair2, 0, 1) ) return(down);
   
   //Got this far, so conditions are wrong for trading
   return(none);
   
}//string GetTradeDirection()

bool SendSingleTrade(int type)
{
   // Attempts to place a trade according to type, i.e.
   // 0 = OP_BUY
   // 1 = OP_SELL
   
   // Check spread
   //if (MarketInfo(Symbol(), MODE_SPREAD) > MaxSpreadAllowed)
   //{
      //return(false);// Spread too large, so abort send
   //}//if (MarketInfo(NULL, MODE_SPREAD) > MaxSpreadAllowed)

 
   
   RefreshRates();
   
   // Buy trade
   if (type == 0)
   {
      double TradePrice=Ask;
      int colour = 32768;//green
      double SL = NormalizeDouble(TradePrice - (StopLoss * Point), Digits);
      double TP = NormalizeDouble(TradePrice + (TakeProfit * Point), Digits);
   }//if (type == 0)   
   
   
   // Sell trade
   if (type == 1)
   {
      TradePrice=Bid;      
      colour = 255;//red
      SL = NormalizeDouble(TradePrice - (StopLoss * Point), Digits);
      TP = NormalizeDouble(TradePrice + (TakeProfit * Point), Digits);
   }//if (type == 1)
   
   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   slippage*= Point;
   
   //Non ECN crook
   if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, Lot, TradePrice, slippage, SL, TP, TradeComment, MagicNumber,0, colour);
   
   //Is a 2 stage criminal
   if (CriminalIsECN)
   {
     ticket = OrderSend(Symbol(),type, Lot, TradePrice, slippage, 0, 0, TradeComment, MagicNumber,0, colour);
	  if (StopLoss != 0)
	  {
		  if (ticket > 0)
			  bool result = OrderModify(ticket, OrderOpenPrice(),	SL, TP, 0, CLR_NONE);
			  if (!result)
			  {
			      int err=GetLastError();
               Alert(Symbol(), " ", type," TP order modify failed with error(",err,"): ",ErrorDescription(err));
               Print("Order send failed with error(",err,"): ",ErrorDescription(err));      
			  }//if (!result)			  
	  }//if (Take != 0)
	  else Print("Skipping OrderModify because no SL or TP specified.");
      
   }//if (CriminalIsECN)

   //Error trapping for both
   if (ticket < 0)
   {
      err=GetLastError();
      Alert(Symbol(), " ", type," order send failed with error(",err,"): ",ErrorDescription(err));
      Print("Order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)
   
   return(true);
}//End void SendSingleTrade(type)

bool ShouldRobotSleep()
{
   // Checks the history list to find a closed trade.
   // If one exists, checks to see if it closed more than SleepAfterTradeClosesMins.
   // Returns false (sleep not needed) if so, else true (sleep needed)
   
   if (OrdersHistoryTotal() == 0) return(false);// No history trades, so sleep clearly not needed
   
   for(int cnt=0; cnt<OrdersHistoryTotal(); cnt++)
   {
      if(!OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY)) continue;
      {       
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            int TimePassed = (TimeCurrent() - OrderCloseTime()) / 60;
            if (TimePassed < SleepAfterTradeClosesMins) return(true);//Robot should sleep
         }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)            
      }//if(!OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY))
   }//for(int cnt=0; cnt<OrdersHistoryTotal(); cnt++)

   //Got this far, so sleep not needed
   return(false);

}//bool ShouldRobotSleep()


bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
{
   //Reusable code that can be called by any of the stop loss manipulation routines except HiddenStopLoss().
   //Checks to see if the market has hit the hidden sl and attempts to close the trade if so. 
   //Returns true if trade closure is successful, else returns false
   
   //Check buy trade
   if (type == OP_BUY)
   {
      double sl = NormalizeDouble(stop + (iPipsAboveVisual * Point), Digits);
      if (Bid <= sl)
      {
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Bid <= sl)  
   }//if (type = OP_BUY)
   
   //Check buy trade
   if (type == OP_SELL)
   {
      sl = NormalizeDouble(stop - (iPipsAboveVisual * Point), Digits);
      if (Ask >= sl)
      {
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Ask >= sl)  
   }//if (type = OP_SELL)
   

}//End bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )

void JumpingStopLoss() 
{
   // Jump sl by pips and at intervals chosen by user .
   double sl=OrderStopLoss(); //Stop loss

   if (OrderType()==OP_BUY)
   {
      //Check hidden js for trade closure
      if (HideJumpingStop)
      {
         bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualJS, OrderStopLoss() );
         if (TradeClosed) return;//Trade has closed, so nothing else to do
      }//if (HideJumpingStop)
      
      // First check if sl needs setting to breakeven
      if (sl==0 || sl<OrderOpenPrice())
      {
         if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
         {
            sl=OrderOpenPrice();
            if (AddBEP==true) sl=sl+(BreakEvenProfit*Point); // If user wants to add a profit to the break even
            bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
            if (result)
            {
               Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
               
            }//if (result)
            if (!result)
            {
               int err=GetLastError();
               Alert(Symbol(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
               Print(Symbol(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
            }//if (!result)
             
            return(0);
         }//if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
      } //close if (sl==0 || sl<OrderOpenPrice()

  
      // Increment sl by sl + JumpingStopPips.
      // This will happen when market price >= (sl + JumpingStopPips)
      if (Bid>= sl + ((JumpingStopPips*2)*Point) && sl>= OrderOpenPrice())      
      {
         sl=sl+(JumpingStopPips*Point);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
         if (result)
         {
            Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
            
         }//if (result)
         if (!result)
         {
            err=GetLastError();
            Print(Symbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
         }//if (!result)
             
      }// if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())      
   }//if (OrderType()==OP_BUY)
   
   if (OrderType()==OP_SELL)
   {
      //Check hidden js for trade closure
      if (HideJumpingStop)
      {
         TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualJS, OrderStopLoss() );
         if (TradeClosed) return;//Trade has closed, so nothing else to do
      }//if (HideJumpingStop)
            
      // First check if sl needs setting to breakeven
      if (sl==0 || sl>OrderOpenPrice())
      {
         if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
         {
            sl = OrderOpenPrice();
            if (AddBEP==true) sl=sl-(BreakEvenProfit*Point); // If user wants to add a profit to the break even
            result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
            if (result)
            {
               
            }//if (result)
            if (!result)
            {
               err=GetLastError();
               Alert(Symbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
               Print(Symbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
            }//if (!result)
             
            return(0);
         }//if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
      } // if (sl==0 || sl>OrderOpenPrice()
   
      // Decrement sl by sl - JumpingStopPips.
      // This will happen when market price <= (sl - JumpingStopPips)
      if (Bid<= sl - ((JumpingStopPips*2)*Point) && sl<= OrderOpenPrice())      
      {
         sl=sl-(JumpingStopPips*Point);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
         if (result)
         {
            Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
            
         }//if (result)          
         if (!result)
         {
            err=GetLastError();
            Print(Symbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
         }//if (!result)

      }// close if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())         
   }//if (OrderType()==OP_SELL)

} //End of JumpingStopLoss sub


void TrailingStopLoss()
{  
   bool result;
   double sl=OrderStopLoss(); //Stop loss
   double BuyStop=0, SellStop=0;
   
   if (OrderType()==OP_BUY) 
      {
         if (HideTrailingStop)
         {
            bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualJS, OrderStopLoss() );
            if (TradeClosed) return;//Trade has closed, so nothing else to do
         }//if (HideJumpingStop)
		   
		   if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
		   {
		       if (OrderStopLoss() == 0) sl = OrderOpenPrice();
		       if (Bid > sl +  (TrailingStopPips*Point))
		       {
		          sl= Bid - (TrailingStopPips*Point);
		          // Exit routine if user has chosen StopTrailAtPipsProfit and
		          // sl is past the profit Point already
		          result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
               if (result)
               {
                  Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
               }//if (result) 
               else
               {
                  int err=GetLastError();
                  Print(Symbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
               }//else
   
		       }//if (Bid > sl +  (TrailingStopPips*Point))
		   }//if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
      }//if (OrderType()==OP_BUY) 

      if (OrderType()==OP_SELL) 
      {
		   if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
		   {
             if (HideTrailingStop)
             {
                TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualJS, OrderStopLoss() );
                if (TradeClosed) return;//Trade has closed, so nothing else to do
             }//if (HideJumpingStop)
		   
		       if (OrderStopLoss() == 0) sl = OrderOpenPrice();
		       if (Ask < sl -  (TrailingStopPips*Point))
		       {
	               sl= Ask + (TrailingStopPips*Point);
  	               // Exit routine if user has chosen StopTrailAtPipsProfit and
		            // sl is past the profit Point already
		            result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
                  if (result)
                  {
                     Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Bid ", Bid);
                  }//if (result)
                  else
                  {
                     err=GetLastError();
                     Print(Symbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
                  }//else
    
		       }//if (Ask < sl -  (TrailingStopPips*Point))
		   }//if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
      }//if (OrderType()==OP_SELL) 

      
} // End of TrailingStopLoss sub

void HiddenStopLoss()
{
   //Called from ManageTrade if HideStopLossEnabled = true


   //Should the order close because the stop has been passed?
   //Buy trade
   if (OrderType() == OP_BUY)
   {
      double sl = NormalizeDouble(OrderOpenPrice() - (HiddenStopLossPips * Point), Digits);
      if (Bid <= sl)
      {
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Bid <= sl)      
   }//if (OrderType() == OP_BUY)
   
   //Sell trade
   if (OrderType() == OP_SELL)
   {
      sl = NormalizeDouble(OrderOpenPrice() + (HiddenStopLossPips * Point), Digits);
      if (Ask >= sl)
      {
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Ask >= sl)   
   }//if (OrderType() == OP_SELL)
   

}//End void HiddenStopLoss()

void HiddenTakeProfit()
{
   //Called from ManageTrade if HideStopLossEnabled = true


   //Should the order close because the stop has been passed?
   //Buy trade
   if (OrderType() == OP_BUY)
   {
      double tp = NormalizeDouble(OrderOpenPrice() + (HiddenTakeProfitPips * Point), Digits);
      if (Bid >= tp)
      {
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Ask >= tp)      
   }//if (OrderType() == OP_BUY)
   
   //Sell trade
   if (OrderType() == OP_SELL)
   {
      tp = NormalizeDouble(OrderOpenPrice() - (HiddenTakeProfitPips * Point), Digits);
      if (Ask <= tp)
      {
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Ask <= tp)   
   }//if (OrderType() == OP_SELL)
   

}//End void HiddenTakeProfit()


void ManageTrade()
{
   //Calls the trade management functions.
   //Called from start() by the trade counting routine, so the OrderSelect() has selected the trade
   
   // Hidden stop loss
   if (HideStopLossEnabled) HiddenStopLoss();
   
   // Hidden take profit
   if (HideTakeProfitEnabled) HiddenTakeProfit();
      
   if (JumpingStop) JumpingStopLoss();
   
   if (TrailingStop) TrailingStopLoss();

}//End void ManageTrade()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----
   
   //Is there a trade already open?
   bool TradeExists = DoesTradeExist();
   if (TradeExists)
   {
      DisplayUserFeedback();
      return;
   }//if (TradeExists)
      
   static int Tries = 0;
   
   //Trading hours
   if (TimeHour(TimeLocal()) < TradeHourStart || TimeHour(TimeLocal()) > TradeHourStop) 
   {
      Comment(Gap, "Trading suspended - outside trade hours");
      OldTradePairBars = Bars;
      OldCorr1Bars = iBars(CorrPair1, 0);
      OldCorr2Bars = iBars(CorrPair2, 0);
      Tries = 0;
      return;    
   }
   
   if (!TradeExists) bool SendToSleep = ShouldRobotSleep();// Compares closure time of history trade with current time, 
                                            // returning true for sleep or false. Will return false if no history trades
   if (SendToSleep)
   {
      Comment("Sleeping after trade closure");
      Sleep((SleepAfterTradeClosesMins*60)*1000);
   }//if (SendToSleep)
      
   //New candle?
   if (OldTradePairBars != Bars)
   {
      //Check the new candles have formed in the corellation pairs charts
      if (OldCorr1Bars == iBars(CorrPair1, 0) ) return;
      if (OldCorr2Bars == iBars(CorrPair2, 0) ) return;
      OldTradePairBars = Bars;
      OldCorr1Bars = iBars(CorrPair1, 0);
      OldCorr2Bars = iBars(CorrPair2, 0);
      string direction = GetTradeDirection();
      //Send buy
      if (direction == up)
      {
         bool TradeSuccess = SendSingleTrade(0);
         if (!TradeSuccess && Tries <= 5)
         {
            OldTradePairBars = 0;
            OldCorr1Bars = 0;
            OldCorr2Bars = 0;
            Tries++;            
         }//if (!TradeSuccess) 
      }//if (direction == up)
      
      if (direction == down)
      {
         TradeSuccess = SendSingleTrade(1);
         if (!TradeSuccess) 
         {
            OldTradePairBars = 0;
            OldCorr1Bars = 0;
            OldCorr2Bars = 0;
            Tries++;            
         }//if (!TradeSuccess)          
      }//if (direction == down)
      
      
      if (Tries == 5)
      {
         OldTradePairBars = Bars;
         OldCorr1Bars = iBars(CorrPair1, 0);
         OldCorr2Bars = iBars(CorrPair2, 0);
         Tries = 0;
      }//if (Tries == 5)
      
   }//if (OldTradePairBars != Bars)
   
   
   DisplayUserFeedback();
   
   
//----
   return(0);
}
//+------------------------------------------------------------------+