//+-------------------------------------------------------------------+
//|       NanningBob V1 Trend auto trading robot by Steve Hopwood.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"
#define  buy "Looking for a Buy trigger"
#define  sell "Looking for a Sell trigger"
#define  notrade "Not looking for a trade trigger"
#define  convergencehappening "Cannot trade - the lines are converging"
#define  globalprefix "NB V1 trend "
#define  opentrade "There is a trade open"
#define  stoplossline "Stop loss line"
#define  hiddenstoplossline "Hidden stop loss line"
#define  takeprofitline "Take profit line"

/*
#define  ranging "Ranging"
#define  confused "Confused, and so cannot trade"
#define  trending "Trending"
#define  stopped "Trading is stopped"
*/


/*


FUNCTIONS LIST
int init()
int start()

----Trading----

void LookForTradeSetup()
void LookForTradeTrigger()
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
bool DoesTradeExist()
void CountOpenTrades() Not used
bool CloseTrade(ticket)
void LookForTradeClosure()
bool CheckTradingTimes()
void CalculateLotSize()
void SetHiddenStop(int type, double price)
bool CheckTradingStatusStillValid()

----Indicator readings----
void ReadIndicatorValues()
void GetTMA()
double GetMa(int tf, int period, int mashift, int method, int ap, int shift)
double GetLow()
double GetHigh()

bool GetConvergence()


----Trade management module----
void TradeManagementModule()
void BreakEvenStopLoss()
bool CheckForHiddenStopLossHit(int type)
void JumpingStopLoss() 
void HiddenTakeProfit()
void HiddenStopLoss()
void TrailingStopLoss()

*/
extern string  eau="----EA use----";
extern bool    AutoTrader=false;
extern bool    NB_V1_Trend_Waiting_EA=true;
extern string  gen="----General inputs----";
extern double  Lot=0.01;
extern int     VisualStopLoss=100;
extern int     MagicNumber=0;
extern string  TradeComment="";
extern bool    CriminalIsECN=true;
extern int     TouchBufferPips=10;
extern string  sls="----Stop loss----";
extern string  ps="Previous swing";
extern bool    UseSwing=true;
extern double  HiddenSwingStopLossMultiplier=1;
extern int     PipsAddToStopLoss=30;
extern int     MinStopLoss=50;
extern string  tma="TMA";
extern bool    UseTma=false;
extern double  HiddenTmaStopLossMultiplier=1;
extern string  cvf="----Convergence filter----";
extern bool    UseConvergenceFilter=false;
extern string  ts="----Trading allowed----";
extern bool    StopTrading=false;
extern bool    TradeLong=true;
extern bool    TradeShort=true;
extern string  tps="----Take Profit stuff----";
extern int     TakeProfit=0;
extern bool    MoveTpLineWithTMA=true;
extern string  tpsll="Take profit and stop loss lines";
extern color   TpLineColour=Green;
extern color   SlLineColour=Red;
extern string  tt="----Trading hours----";
extern string  Trade_Hours= "Set Morning & Evening Hours";
extern string  Trade_Hoursi= "Use 24 hour, local time clock";
extern string  Trade_Hours_M= "Morning Hours 0-12";
extern  int    start_hourm = 0;
extern  int    end_hourm = 12;
extern string  Trade_Hours_E= "Evening Hours 12-24";
extern  int    start_houre = 12;
extern  int    end_houre = 24;
extern string  mas="----Moving Averages & Fractals----";
extern string  mas1="Leave these alone unless";
extern string  mas2="you know what you are doing.";
extern string  w1ma="W1 moving average";
extern int     W1Tf=0;
extern int     W1Period=240;
extern string  five="5 x 5 moving average";
extern int     MA5x5Tf=0;
extern int     MA5xPeriod=5;
extern int     MA5xShift=5;
extern string  fra="Fractals - measures the swing";
extern int     FractalTF=0;
extern string  tmm="----Trade management module----";
bool    DoNotOverload5DigitCriminals=false;//Removed the extern - not necessary in this program
extern string  BE="Break even settings";
extern bool    BreakEven=true;
extern int     BreakEvenPips=15;
extern int     BreakEvenProfit=3;
extern bool    HideBreakEvenStop=false;
extern int     PipsAwayFromVisualBE=5;
extern string  JSL="Jumping stop loss settings";
extern bool    JumpingStop=true;
extern int     JumpingStopPips=30;
extern bool    AddBEP=false;
extern bool    JumpAfterBreakevenOnly=false;
extern bool    HideJumpingStop=false;
extern int     PipsAwayFromVisualJS=10;
extern string  TSL="Trailing stop loss settings";
extern bool    TrailingStop=false;
extern int     TrailingStopPips=50;
extern bool    HideTrailingStop=false;
extern int     PipsAwayFromVisualTS=10;
extern bool    TrailAfterBreakevenOnly=false;
extern bool    StopTrailAtPipsProfit=false;
extern int     StopTrailPips=0;
//extern string  hsl1="Hidden stop loss settings";
bool    HideStopLossEnabled=true;//Removed the extern so that the user has no choice but I do not have to edit umpteen lines of code
extern string  htp="Hidden take profit settings";
extern bool    HideTakeProfitEnabled=false;
extern int     HiddenTakeProfitPips=20;
extern string  mis="----Odds and ends----";
extern bool    ShowManagementAlerts=false;
extern int     DisplayGapSize=30;


//Trading variables
int            TicketNo, OpenTrades;
string         GvName;//Stores the name of the global variable that holds the trading status
string         TradingStatus;// 0 = waiting to buy; 1 = waiting to sell; -1 = not looking for a trade
double         HiddenStopLoss;

//Trend
string         trend;

//Moving averages
double         W1MaVal, Ma5Val;
double         TmaUpper, TmaMiddle, TmaLower;

//Date/Time
datetime       ConvertedStartTime;

//Misc
string         Gap, ScreenMessage;
string         PipDescription=" pips";
bool           RobotSuspended;

void DisplayUserFeedback()
{
   
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   //Code for time to bar-end display from Candle Time by Nick Bilak
   double i;
   int m,s,k;
   m=Time[0]+Period()*60-CurTime();
   i=m/60.0;
   s=m%60;
   m=(m-m%60)/60;
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, m + " minutes " + s + " seconds left to bar end", NL);

//extern bool    AutoTrader=true;
//extern bool    NB_V1_Trend_Waiting_EA=false;
      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "----------------------------------------------------------------------", NL);
   if (AutoTrader) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Auto-trading mode", NL);
   if (NB_V1_Trend_Waiting_EA) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Manual trading mode - waiting for the trade trigger", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "----------------------------------------------------------------------", NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TakeProfit, PipDescription,  NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop lss: ", VisualStopLoss, PipDescription,  NL);   
   if (UseConvergenceFilter) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using convergence filter", NL);
   if (!UseConvergenceFilter) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not using convergence filter", NL);
   if (StopTrading) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading is stopped", NL);
   if (!StopTrading)
   {
      if (TradeLong) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Long trading allowed", NL);
      if (TradeShort) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Short trading allowed", NL);
   }//if (!StopTrading)
   if (MoveTpLineWithTMA)  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Moving tp with TMA", NL);
   if (!MoveTpLineWithTMA)  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not moving tp with TMA", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TouchBufferPips: ", TouchBufferPips, NL);

   //Stop loss
   if (UseSwing)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using the swing to calculate the stop loss. PipsAddToStopLoss: ", PipsAddToStopLoss, NL);
   }//if (UseSwing)
   if (UseTma)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using Tma to calculate the stop loss. HiddenTmaStopLossMultiplier: ", HiddenTmaStopLossMultiplier, NL);
   }//if (UseTma)
   
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MinStopLoss: ", MinStopLoss, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
   if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = true", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = false", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Long trade swap: ", MarketInfo(Symbol(), MODE_SWAPLONG), NL );
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Short trade swap: ", MarketInfo(Symbol(), MODE_SWAPSHORT), NL );
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL, NL );
   double swap = MarketInfo(Symbol(), MODE_SWAPLONG);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours", NL);
   if (start_hourm == 0 && end_hourm == 12 && start_houre && end_houre == 24) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            24H trading", NL);
   else
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_hourm: ", DoubleToStr(start_hourm, 2), 
                      ": end_hourm: ", DoubleToStr(end_hourm, 2), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_houre: ", DoubleToStr(start_houre, 2), 
                      ": end_houre: ", DoubleToStr(end_houre, 2), NL);
                      
   }//else
   
   
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "W1 Moving average: ", DoubleToStr(W1MaVal, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TMA Upper line: ", DoubleToStr(TmaUpper, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TMA Middle line: ", DoubleToStr(TmaMiddle, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TMA Lower line: ", DoubleToStr(TmaLower, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "5MA: ", DoubleToStr(Ma5Val, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trend is: ", trend, NL);
   if (TradingStatus != opentrade) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading status is: ", TradingStatus, NL);
   if (TradingStatus == opentrade) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading status is: ", TradingStatus, ": Hidden stop loss is ", DoubleToStr(HiddenStopLoss, Digits), NL);
   

   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   
   if (BreakEven)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Breakeven is set to ", BreakEvenPips, PipDescription);
      ScreenMessage = StringConcatenate(ScreenMessage,": BreakEvenProfit = ", BreakEvenProfit, PipDescription);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL); 
   }//if (BreakEven)

   if (JumpingStop)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Jumping stop is set to ", JumpingStopPips, PipDescription);
      if (AddBEP) ScreenMessage = StringConcatenate(ScreenMessage,": BreakEvenProfit = ", BreakEvenProfit, PipDescription);
      if (JumpAfterBreakevenOnly) ScreenMessage = StringConcatenate(ScreenMessage, ": JumpAfterBreakevenOnly = true");
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
   }//if (JumpingStop)
   

   if (TrailingStop)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trailing stop is set to ", TrailingStopPips, PipDescription);
      if (TrailAfterBreakevenOnly) ScreenMessage = StringConcatenate(ScreenMessage, ": TrailAfterBreakevenOnly = true");
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
   }//if (TrailingStop)

   if (HideStopLossEnabled)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hidden stop multiplier is ", HiddenTmaStopLossMultiplier, NL);
   }//if (HideStopLossEnabled)
   
   if (HideTakeProfitEnabled)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hidden take profit enabled at ", HideTakeProfitEnabled, PipDescription, NL);
   }//if (HideTakeProfitEnabled)

    
   Comment(ScreenMessage);


}//void DisplayUserFeedback()


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----

   //Adapt to x digit criminals
   int multiplier;
   if(Digits == 2 || Digits == 4) multiplier = 1;
   if(Digits == 3 || Digits == 5) multiplier = 10;
   if(Digits == 6) multiplier = 100;   
   if(Digits == 7) multiplier = 1000;   
   
   if (multiplier > 1) PipDescription = " points";
   
   TakeProfit*= multiplier;
   VisualStopLoss*= multiplier;
   MinStopLoss*= multiplier;
   PipsAddToStopLoss*= multiplier;
   TouchBufferPips*= multiplier;
   BreakEvenPips*= multiplier;
   BreakEvenProfit*= multiplier;
   PipsAwayFromVisualBE*= multiplier;
   JumpingStopPips*= multiplier;
   PipsAwayFromVisualJS*= multiplier;
   TrailingStopPips*= multiplier;
   PipsAwayFromVisualTS*= multiplier;
   StopTrailPips*= multiplier;
   HiddenTakeProfitPips*= multiplier;


   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   
   GvName = globalprefix + Symbol();
   //Pick up after a restart
   TradingStatus = notrade;
   if (GlobalVariableCheck(GvName) && !StopTrading)
   {
      int type = GlobalVariableGet(GvName);
      if (TradeLong) TradingStatus = buy;
      if (type == 1 && TradeShort) TradingStatus = sell;      
   }//if (GlobalVariableCheck(GvName) > -1)  

   if (TradeComment == "") TradeComment = " ";
   ReadIndicatorValues();//For initial display in case user has turned of constant re-display
   DisplayUserFeedback();
   
   //Ea is being used as a waiting ea
   if (NB_V1_Trend_Waiting_EA)
   {
      int retval = MessageBox(Symbol() + ": do you wish to continue to use this robot?", "Question", MB_YESNO|MB_ICONQUESTION);
      if (retval == IDNO) RobotSuspended = true;
      else RobotSuspended = false;
      TradingStatus = sell;
      if (trend == up) TradingStatus = buy;
   }//if (NB_V1_Trend_Waiting_EA)
      
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
//----
   return(0);
}


////////////////////////////////////////////////////////////////////////////////////////////////
//TRADE MANAGEMENT MODULE

//bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
bool CheckForHiddenStopLossHit(int type)
{
   //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
   
   double stop = ObjectGet(hiddenstoplossline, OBJPROP_PRICE1);

   //Check buy trade
   if (type == OP_BUY)
   {
      if (Bid <= stop)
      {
         while(IsTradeContextBusy()) Sleep(100);
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            if (ShowManagementAlerts==true) 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 <= stop)  
   }//if (type = OP_BUY)
   
   //Check buy trade
   if (type == OP_SELL)
   {
      if (Ask >= stop)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) 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 >= stop)  
   }//if (type = OP_SELL)
   

}//End bool CheckForHiddenStopLossHit(int type)


void BreakEvenStopLoss() // Move stop loss to breakeven
{

   //Check hidden BE for trade closure
   if (HideBreakEvenStop)
   {
      bool TradeClosed = CheckForHiddenStopLossHit(OrderType() );
      if (TradeClosed) return;//Trade has closed, so nothing else to do
   }//if (HideBreakEvenStop)


   bool result;

   if (OrderType()==OP_BUY)
         {
            if (Bid >= OrderOpenPrice () + (Point*BreakEvenPips) && 
                OrderStopLoss()<OrderOpenPrice())
            {
               while(IsTradeContextBusy()) Sleep(100);
               result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
               if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
               if (result)
               {
                  if (HideBreakEvenStop)
                  {
                     OrderSelect(TicketNo, SELECT_BY_TICKET);               
                     HiddenStopLoss = NormalizeDouble(OrderStopLoss() + (PipsAwayFromVisualBE * Point), Digits);
                     ObjectMove(hiddenstoplossline,0,TimeCurrent(), HiddenStopLoss );
                  }//if (HideBreakEvenStop)
               }//if (result)
               
               Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
               if (!result)
               {
                  int err=GetLastError();
                  if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
                  Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
               }//if !result && ShowManagementAlerts)      
               //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
               //{
               //   bool PartCloseSuccess = PartCloseTradeFunction();
               //   if (!PartCloseSuccess) SetAGlobalTicketVariable();
               //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
            }
   	   }               			         
          
   if (OrderType()==OP_SELL)
         {
           if (Ask <= OrderOpenPrice() - (Point*BreakEvenPips) &&
              (OrderStopLoss()>OrderOpenPrice()|| OrderStopLoss()==0)) 
            {
               while(IsTradeContextBusy()) Sleep(100);
               result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
               if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
               Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
               if (result)
               {
                  if (HideBreakEvenStop)
                  {
                     OrderSelect(TicketNo, SELECT_BY_TICKET);               
                     HiddenStopLoss = NormalizeDouble(OrderStopLoss() - (PipsAwayFromVisualBE * Point), Digits);
                     ObjectMove(hiddenstoplossline,0,TimeCurrent(), HiddenStopLoss );
                  }//if (HideJumpingStop)
               }//if (result)
               
               if (!result && ShowManagementAlerts)
               {
                  err=GetLastError();
                  if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
                  Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
               }//if !result && ShowManagementAlerts)      
              //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
              // {
              //    PartCloseSuccess = PartCloseTradeFunction();
              //    if (!PartCloseSuccess) SetAGlobalTicketVariable();
              // }//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
            }    
         }
      

} // End BreakevenStopLoss sub

void JumpingStopLoss() 
{
   // Jump sl by pips and at intervals chosen by user .
   // Also carry out partial closure if the user requires this

   // Abort the routine if JumpAfterBreakevenOnly is set to true and be sl is not yet set
   if (JumpAfterBreakevenOnly && OrderType()==OP_BUY)
   {
      if(OrderStopLoss()<OrderOpenPrice()) return(0);
   }
  
   if (JumpAfterBreakevenOnly && OrderType()==OP_SELL)
   {
      if(OrderStopLoss()>OrderOpenPrice() || OrderStopLoss() == 0 ) return(0);
   }
  
   double sl=OrderStopLoss(); //Stop loss

   if (OrderType()==OP_BUY)
   {
      //Check hidden js for trade closure
      if (HideJumpingStop)
      {
         bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY);
         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
            while(IsTradeContextBusy()) Sleep(100);
            bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
            if (result)
            {
               if (ShowManagementAlerts==true) Alert("Jumping stop set at breakeven ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
               Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", Bid);
               //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
               //{
                  //bool PartCloseSuccess = PartCloseTradeFunction();
                  //if (!PartCloseSuccess) SetAGlobalTicketVariable();
               //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
            }//if (result)
            if (!result)
            {
               int err=GetLastError();
               if (ShowManagementAlerts) Alert(OrderSymbol(), "Ticket ", OrderTicket(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
               Print(OrderSymbol(), " 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);
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
            Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
            if (HideJumpingStop)
            {
               HiddenStopLoss = NormalizeDouble(sl + (PipsAwayFromVisualJS * Point), Digits);
               ObjectMove(hiddenstoplossline,0,TimeCurrent(), HiddenStopLoss );
            }//if (HideJumpingStop)
            
            //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
            //{
               //PartCloseSuccess = PartCloseTradeFunction();
               //if (!PartCloseSuccess) SetAGlobalTicketVariable();
            //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
         }//if (result)
         if (!result)
         {
            err=GetLastError();
            if (ShowManagementAlerts) Alert(OrderSymbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
            Print(OrderSymbol(), " 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);
         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
            while(IsTradeContextBusy()) Sleep(100);
            result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
            if (result)
            {
               //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
               //{
                 // PartCloseSuccess = PartCloseTradeFunction();
                  //if (!PartCloseSuccess) SetAGlobalTicketVariable();
               //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
            }//if (result)
            if (!result)
            {
               err=GetLastError();
               if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
               Print(OrderSymbol(), " 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);
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
            Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
            if (HideJumpingStop)
            {
               HiddenStopLoss = NormalizeDouble(sl - (PipsAwayFromVisualJS * Point), Digits);
               ObjectMove(hiddenstoplossline,0,TimeCurrent(), HiddenStopLoss );
            }//if (HideJumpingStop)
            //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
            //{
              // PartCloseSuccess = PartCloseTradeFunction();
               //if (!PartCloseSuccess) SetAGlobalTicketVariable();
            //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
         }//if (result)          
         if (!result)
         {
            err=GetLastError();
            if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
            Print(OrderSymbol(), " 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 HiddenStopLoss()
{
   //Called from ManageTrade if HideStopLossEnabled = true. This is enforced in this robot

   double stop = ObjectGet(hiddenstoplossline, OBJPROP_PRICE1);
   //Safety check
   if (stop == 0) return;
   
   //Should the order close because the stop has been passed?
   //Buy trade
   if (OrderType() == OP_BUY)
   {
            
      if (Ask <= stop)
      {
         while(IsTradeContextBusy()) Sleep(100);
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5000, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            if (ShowManagementAlerts==true) 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 <= stop)
   }//if (OrderType() == OP_BUY)
   
   //Sell trade
   if (OrderType() == OP_SELL)
   {
      
      if (Bid >= stop)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5000, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) 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 >= stop)   
   }//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)
      {
         while(IsTradeContextBusy()) Sleep(100);
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            if (ShowManagementAlerts==true) 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)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) 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 (Bid <= tp)   
   }//if (OrderType() == OP_SELL)
   

}//End void HiddenTakeProfit()

void TrailingStopLoss()
{
      if (TrailAfterBreakevenOnly && OrderType()==OP_BUY)
      {
         if(OrderStopLoss()<OrderOpenPrice()) return(0);
      }
     
      if (TrailAfterBreakevenOnly && OrderType()==OP_SELL)
      {
         if(OrderStopLoss()>OrderOpenPrice()) return(0);
      }
     
   
   
   bool result;
   double sl=OrderStopLoss(); //Stop loss
   double BuyStop=0, SellStop=0;
   
   if (OrderType()==OP_BUY) 
      {
         if (HideTrailingStop)
         {
            bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY);
            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
		          if (StopTrailAtPipsProfit && sl>= OrderOpenPrice() + (StopTrailPips*Point)) return;
		          while(IsTradeContextBusy()) Sleep(100);
		          result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
               if (result)
               {
                  Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
                  if (HideTrailingStop)
                  {
                     HiddenStopLoss = NormalizeDouble(sl + (PipsAwayFromVisualTS * Point), Digits);
                     ObjectMove(hiddenstoplossline,0,TimeCurrent(), HiddenStopLoss );
                  }//if (HideTrailingStop)
            
               }//if (result) 
               else
               {
                  int err=GetLastError();
                  Print(OrderSymbol(), " 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_SELL);
                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
		            if (StopTrailAtPipsProfit && sl<= OrderOpenPrice() - (StopTrailPips*Point)) return;
		            while(IsTradeContextBusy()) Sleep(100);
		            result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
                  if (result)
                  {
                     Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Bid ", Bid);
                     if (HideTrailingStop)
                     {
                        HiddenStopLoss = NormalizeDouble(sl - (PipsAwayFromVisualTS * Point), Digits);
                        ObjectMove(hiddenstoplossline,0,TimeCurrent(), HiddenStopLoss );
                     }//if (HideTrailingStop)
            
                  }//if (result)
                  else
                  {
                     err=GetLastError();
                     Print(OrderSymbol(), " 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 TradeManagementModule()
{

   // Call the working subroutines one by one. 

   //Cut down 5 digit order modify calls for 5 digit crims, if required
   static int NoOfTicks = 9;
   int ndigits = MarketInfo(Symbol(), MODE_DIGITS);
   if (DoNotOverload5DigitCriminals && ( ndigits == 3 || ndigits == 5) )
   {
      NoOfTicks++;
   }//if (DoNotOverload5DigitCriminals && ( digits == 3 || digits == 5) )
   
   if (!DoNotOverload5DigitCriminals || ndigits == 2 || ndigits == 4)
   {
      NoOfTicks = 10;
   }//if (!DoNotOverload5DigitCriminals || digits == 2 || digits == 4)
   
   
   // Global variable to pick up on failed part-closes
   //if (GlobalVariablesTotal()>0) GlobalVariablesExist=true;
   //if (GlobalVariablesExist && GlobalVariablesTotal()>0) TryPartCloseAgain();
   //if (GlobalVariablesExist && GlobalVariablesTotal()==0) GlobalVariablesExist=false;
   
   // Hidden stop loss
   if (HideStopLossEnabled) HiddenStopLoss();
   
   if (NoOfTicks >= 10)
   {
      NoOfTicks = 0;//Reset the counter
            
      // Hidden take profit
      if (HideTakeProfitEnabled) HiddenTakeProfit();
   
      // Breakeven
      if(BreakEven) BreakEvenStopLoss();
   
      // JumpingStop
      if(JumpingStop) JumpingStopLoss();
   
      //TrailingStop
      if(TrailingStop) TrailingStopLoss();

      //Adjust hidden and visual sl line if stop has been adjusted
      OrderSelect(TicketNo, SELECT_BY_TICKET);
      double target = ObjectGet(stoplossline, OBJPROP_PRICE1);
      if (target != OrderStopLoss()) 
      {
         ObjectMove(stoplossline,0,TimeCurrent(),OrderStopLoss() );
         
      }//if (target != OrderStopLoss()) 
      
      
   }//if (NoOfTicks >= 10)
   

}//void TradeManagementModule()
//END TRADE MANAGEMENT MODULE
////////////////////////////////////////////////////////////////////////////////////////////////

bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
{
   
   
   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   int expiry = 0;
   //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);

   if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, MagicNumber, expiry, col);
   
   
   //Is a 2 stage criminal
   if (CriminalIsECN)
   {
      bool result;
      int err;
      ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, MagicNumber, expiry, col);
      if (ticket > 0)
      {
	     
	     if (take > 0 && stop > 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           result = OrderModify(ticket, OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE);
           if (!result)
           {
               err=GetLastError();
               Print(Symbol(), " SL/TP  order modify failed with error(",err,"): ",ErrorDescription(err));               
           }//if (!result)			  
        }//if (take > 0 && stop > 0)
      
	     if (take != 0 && stop == 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           result = OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
           if (!result)
           {
               err=GetLastError();
               Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
           }//if (!result)			  
        }//if (take == 0 && stop != 0)

        if (take == 0 && stop != 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           result = OrderModify(ticket, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
           if (!result)
           {
               err=GetLastError();
               Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
           }//if (!result)			  
        }//if (take == 0 && stop != 0)

      }//if (ticket > 0)
        
      
      
   }//if (CriminalIsECN)
   
   //Error trapping for both
   if (ticket < 0)
   {
      string stype;
      if (type == OP_BUY) stype = "OP_BUY";
      if (type == OP_SELL) stype = "OP_SELL";
      if (type == OP_BUYLIMIT) stype = "OP_BUYLIMIT";
      if (type == OP_SELLLIMIT) stype = "OP_SELLLIMIT";
      if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
      if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
      err=GetLastError();
      Alert(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   //Got this far, so trade send succeeded
   TicketNo = ticket;
   TradingStatus = opentrade;
   DisplayUserFeedback();
   Sleep(60000);
   while (!OrderSelect(ticket, SELECT_BY_TICKET) ) Sleep(100);
   return(true);
   
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)

bool DoesTradeExist()
{
   
   TicketNo = 0;
  
   if (OrdersTotal() == 0) return(false);
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      
      if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
      {
         TicketNo = OrderTicket();
         TradingStatus = opentrade;
         //Check hidden/visual stop loss and tp lines exist
         if (ObjectFind(stoplossline) == -1)
         {
            ObjectCreate(stoplossline,1,0,TimeCurrent(),OrderStopLoss());
            ObjectSet(stoplossline,OBJPROP_COLOR,SlLineColour);
            ObjectSet(stoplossline,OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet(stoplossline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(stoplossline) == -1)
         
         if (ObjectFind(hiddenstoplossline) == -1)
         {
            if (OrderType() == OP_BUY) SetHiddenStop(OP_BUY, OrderOpenPrice() );
            if (OrderType() == OP_SELL) SetHiddenStop(OP_SELL, OrderOpenPrice() );
            ObjectCreate(hiddenstoplossline,1,0,TimeCurrent(), HiddenStopLoss);
            ObjectSet(hiddenstoplossline,OBJPROP_COLOR,SlLineColour);
            ObjectSet(hiddenstoplossline,OBJPROP_STYLE,STYLE_DASH);
            ObjectSet(hiddenstoplossline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(hiddenstoplossline) == -1)
         
         if (ObjectFind(takeprofitline) == -1)
         {
            ObjectCreate(takeprofitline,1,0,TimeCurrent(),OrderTakeProfit());
            ObjectSet(takeprofitline,OBJPROP_COLOR,TpLineColour);
            ObjectSet(takeprofitline,OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet(takeprofitline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(takeprofitline) == -1)
         
         //Make the robot adjust the tp/sl if the user has moved the line
         double target = ObjectGet(takeprofitline, OBJPROP_PRICE1);
         if (OrderTakeProfit() != target)
         {
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), target, OrderExpiration(), CLR_NONE);
         }//if (OrderTakeProfit() != target)
         
         target = ObjectGet(stoplossline, OBJPROP_PRICE1);
         if (OrderStopLoss() != target)
         {
            OrderModify(OrderTicket(), OrderOpenPrice(), target, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
         }//if (OrderTakeProfit() != target)
         
         //Read the hidden stop loss
         HiddenStopLoss = ObjectGet(hiddenstoplossline, OBJPROP_PRICE1);
         
         
         return(true);         
      }//if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   //Got this far, so no trade open, so make sure there are no tp/sl lines
   ObjectDelete(stoplossline);
   ObjectDelete(takeprofitline);
   ObjectDelete(hiddenstoplossline);

   return(false);

}//End bool DoesTradeExist()

double GetLow()
{

   double v;
   
   for (int cc = 1; cc <= Bars; cc++)
   {
      v = iFractals(NULL, FractalTF, MODE_LOWER, cc);
      if (v != 0) return(v);
   }//for (int cc = 1; cc <= Bars; cc++)
   

}//double GetLow()

double GetHigh()
{

   double v;
   
   for (int cc = 1; cc <= Bars; cc++)
   {
      v = iFractals(NULL, FractalTF, MODE_UPPER, cc);
      if (v != 0) return(v);
   }//for (int cc = 1; cc <= Bars; cc++)
   

}//double GetHigh()

void SetHiddenStop(int type, double price)
{

   double pips;
   
   if (type == OP_BUY)
   {
      if (UseSwing)
      {
         HiddenStopLoss = GetLow();
         pips = price - HiddenStopLoss;
         pips*= HiddenSwingStopLossMultiplier;
         pips+= PipsAddToStopLoss * Point;
         if (pips < MinStopLoss * Point) pips = MinStopLoss * Point;
      }//if (UseSwing)
      
      if (UseTma)
      {
         pips = price - TmaLower;
         pips*= HiddenTmaStopLossMultiplier;         
      }//if (UseTma)
      
      HiddenStopLoss = NormalizeDouble(price - pips, Digits);
      
   }//if (type == OP_BUY)
   
   
   if (type == OP_SELL)
   {
      if (UseSwing)
      {
         HiddenStopLoss = GetHigh();
         pips = HiddenStopLoss - price;
         pips*= HiddenSwingStopLossMultiplier;
         pips+= PipsAddToStopLoss * Point;
         if (pips < MinStopLoss * Point) pips = MinStopLoss * Point;
      }//if (UseSwing)
      
      if (UseTma)
      {
         pips = TmaUpper - price;
         pips*= HiddenTmaStopLossMultiplier;         
      }//if (UseTma)
      
      HiddenStopLoss = NormalizeDouble(price + pips, Digits);
      
   }//if (type == OP_SELL)
   
   
}//End void SetHiddenStop(int type, double price)


void LookForTradeTrigger()
{

   RefreshRates();
   double take, stop, price;
   int type;
   bool SendTrade;
   double MinStopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
   double Spread = MarketInfo(Symbol(), MODE_SPREAD);
   
   //Long 
   if (TradingStatus == buy && TradeLong)
   {
      if (Ask > Ma5Val && Ma5Val < TmaMiddle)
      {
         if (IsTradeContextBusy() ) Sleep(100);
         RefreshRates();
         //if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         if (VisualStopLoss > 0) stop = NormalizeDouble(Ask - (VisualStopLoss * Point), Digits);
         SetHiddenStop(OP_BUY, Ask);
         take = TmaUpper;
         
         if (TakeProfit > 0)
         {
            take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         }//if (TakeProfit > 0)
         
         
         type = OP_BUY;
         price = Ask;
         SendTrade = true;
      }//if (Ask > Ma5Val and Ma5Val < TmaMiddle)
      
   }//if (TradingStatus == buy)
   

   //Short
   if (TradingStatus == sell && TradeShort)
   {
      if (Bid < Ma5Val && Ma5Val > TmaMiddle)
      {
         if (IsTradeContextBusy() ) Sleep(100);
         RefreshRates();
         //if (TakeProfit > 0) take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
         if (VisualStopLoss > 0) stop = NormalizeDouble(Bid + (VisualStopLoss * Point), Digits);
         SetHiddenStop(OP_SELL, Bid);
         take = TmaLower;
         
         if (TakeProfit > 0)
         {
            take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
         }//if (TakeProfit > 0)
         
         type = OP_SELL;
         price = Bid;
         SendTrade = true;      
      }//if (Ask < 0)
   }//if (TradingStatus == sell)

   if (SendTrade)
   {
      bool result = SendSingleTrade(type, TradeComment, Lot, price, stop, take);
   }//if (SendTrade)
   
   //Actions when trade send succeeds
   if (SendTrade && result)
   {
      GlobalVariableDel(GvName);
      TradingStatus = opentrade;
   }//if (result)
   
   //Actions when trade send fails
   if (SendTrade && !result)
   {
   
   }//if (!result)
   
   

}//void LookForTradeTrigger()

bool CloseTrade(int ticket)
{   
   while(IsTradeContextBusy()) Sleep(100);
   bool result = OrderClose(ticket, OrderLots(), OrderClosePrice(), 1000, CLR_NONE);

   //Actions when trade send succeeds
   if (result)
   {
   
   }//if (result)
   
   //Actions when trade send fails
   if (!result)
   {
   
   }//if (!result)
   

}//End bool CloseTrade(ticket)

////////////////////////////////////////////////////////////////////////////////////////////////
//Indicator module

/*
void GetBB(int shift)
{
   //Reads BB figures into BbUpper, BbMiddle, BbLower
   
   
   BbUpper = iBands(NULL, 0, BbPeriod, BbDeviation, 0, PRICE_OPEN, MODE_UPPER, shift);
   BbLower = iBands(NULL, 0, BbPeriod, BbDeviation, 0, PRICE_OPEN, MODE_LOWER, shift);
   BbMiddle = iBands(NULL, 0, BbPeriod, BbDeviation, 0, PRICE_OPEN, MODE_MAIN, shift);
   
   BbExtent = BbUpper - BbLower;
   
}//void GetBb(int shift)
*/

/*
double GetRsi(int tf, int period, int ap, int shift)
{
   return(iRSI(NULL, tf, period, ap, shift) );
}//End double GetRsi(int tf, int period, int ap, int shift)
*/

void GetTMA()
{
   TmaMiddle = iMA(NULL, 0, 56, 0, MODE_LWMA, PRICE_CLOSE, 0);
   double range = iATR(NULL,0,100,10)*2.0;
   TmaUpper  = TmaMiddle + range;
   TmaLower  = TmaMiddle - range;

}//End void GetTMA()


double GetMa(int tf, int period, int mashift, int method, int ap, int shift)
{
   return(iMA(NULL, tf, period, mashift, method, ap, shift) );
}//End double GetMa(int tf, int period, int mashift, int method, int ap, int shift)

bool GetConvergence()
{
   double PrevTmaMiddle = iMA(NULL, 0, 56, 0, MODE_LWMA, PRICE_CLOSE, 1);
   if (trend == up)
   {
      if (PrevTmaMiddle > TmaMiddle) return(true);
   }//if (trend == up)
   
   if (trend == down)
   {
      if (PrevTmaMiddle < TmaMiddle) return(true);   
   }//if (trend == down)
   
   
   //Got this far, so no convergence
   return(false);
   
}//bool GetConvergence()


void ReadIndicatorValues()
{
/*
extern string  five="5 x 5 moving average";
extern int     MA5x5Tf=0;
extern int     MA5xPeriod=5;
extern int     MA5xShift=5;
*/

   W1MaVal = GetMa(W1Tf, W1Period, 0, MODE_SMMA, PRICE_MEDIAN, 0);
   Ma5Val = GetMa(MA5x5Tf, MA5xPeriod, MA5xShift, MODE_SMMA, PRICE_MEDIAN, 0);
   GetTMA();
   
   
   //Adjust tp if there is an open trade and the TMA has moved
   static int OldH1Bars;
   if (MoveTpLineWithTMA && OrderSelect(TicketNo, SELECT_BY_TICKET) && OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      double target = ObjectGet(takeprofitline, OBJPROP_PRICE1);
      OldH1Bars = iBars(NULL, PERIOD_H1);
        
      if (OrderCloseTime() == 0)
      {
         if (OrderType() == OP_BUY)
         {
            if (TmaUpper != target)
            {
               ObjectMove(takeprofitline,0,TimeCurrent(),TmaUpper);
            }//if (TmaUpper != target)            
         }//if (OrderType() == OP_BUY)
         
         if (OrderType() == OP_SELL)
         {
            if (TmaLower != target)
            {
               ObjectMove(takeprofitline,0,TimeCurrent(), TmaLower);
            }//if TmaLower != target)            
         }//if (OrderType() == OP_SELL)
         
      }//if (OrderCloseTime == 0)
      
   }//if (MoveTpLineWithTMA && OrderSelect(TicketNo, SELECT_BY_TICKET) )
   
   
   //Determine trend and alter trading status on a change of trend direction
   trend = none;
   if (TmaMiddle > W1MaVal) trend = up;
   if (TmaMiddle < W1MaVal) trend = down;
   
   if (trend == up && TradingStatus == sell)
   {
      TradingStatus = notrade;
      GlobalVariableDel(GvName);
   }//if (trend == up && TradingStatus == sell)
   
   if (trend == down && TradingStatus == buy)
   {
      TradingStatus = notrade;
      GlobalVariableDel(GvName);
   }//if (trend == up && TradingStatus == sell)
   
   //Convergence filter
   if (UseConvergenceFilter)
   {
      bool Converging = GetConvergence();
      if (Converging) TradingStatus = convergencehappening;
   }//if (UseConvergenceFilter)
   
   
}//void ReadIndicatorValues()

//End Indicator module
////////////////////////////////////////////////////////////////////////////////////////////////

void LookForTradeClosure()
{
   //Close the trade if the new candle opens inside the bands
   
   if (!OrderSelect(TicketNo, SELECT_BY_TICKET) ) return;
   
   bool CloseTrade;
   
   if (OrderType() == OP_BUY)
   {
      if (trend == down) CloseTrade = true;
   }//if (OrderType() == OP_BUY)
   
   
   if (OrderType() == OP_SELL)
   {
      if (trend == up) CloseTrade = true;
   }//if (OrderType() == OP_SELL)
   
   if (CloseTrade)
   {
      bool result = CloseTrade(int TicketNo);
      //Actions when trade send succeeds
      if (result)
      {
         ObjectDelete(stoplossline);
         ObjectDelete(takeprofitline);
         ObjectDelete(hiddenstoplossline);
         TradingStatus = notrade;
      }//if (result)
   
      //Actions when trade send fails
      if (!result)
      {
   
      }//if (!result)
   

   }//if (CloseTrade)
   
   
}//void LookForTradeClosure()


bool CheckTradingTimes()
{
   int hour = TimeHour(TimeLocal() );
   
   if (end_hourm < start_hourm)
	{
		end_hourm += 24;
	}
	

	if (end_houre < start_houre)
	{
		end_houre += 24;
	}
	
	bool ok2Trade = true;
	
	ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);

	// adjust for past-end-of-day cases
	// eg in AUS, USDJPY trades 09-17 and 22-06
	// so, the above check failed, check if it is because of this condition
	if (!ok2Trade && hour < 12)
	{
 		hour += 24;
		ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);		
		// so, if the trading hours are 11pm - 6am and the time is between  midnight to 11am, (say, 5am)
		// the above code will result in comparing 5+24 to see if it is between 23 (11pm) and 30(6+24), which it is...
	}


   // check for end of day by looking at *both* end-hours

   if (hour >= MathMax(end_hourm, end_houre))
   {      
      ok2Trade = false;
   }//if (hour >= MathMax(end_hourm, end_houre))

   return(ok2Trade);

}//bool CheckTradingTimes()

/*
void CountOpenTrades()
{
   OpenTrades = 0;
   TicketNo = 0;
   

   if (OrdersTotal() == 0) return;
   
   for (int cc = 0; cc <= OrdersTotal(); cc++)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
         OpenTrades++;
         TicketNo = OrderTicket();   
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
   }//for (int cc = 0; cc < OrdersTotal() - 1; cc++)
   
   
}//End void CountOpenTrades();
*/

void LookForTradeSetup()
{

   //Sets up the appropriate global variable if the market has come within TouchBufferPips of the 
   //TMA upper/lower lines. This allows the robot to carry on where it left off after a restart
   double target;
   TradingStatus = notrade;

   if (trend == up)
   {
      //if (Ask <= TmaLower + (TouchBufferPips * Point) )
      if (Low[0] <= TmaLower + (TouchBufferPips * Point) )
      {
         TradingStatus = buy;
         GlobalVariableSet(GvName, 0);
      }//if (Low[0] <= TmaLower + (TouchBufferPips * Point) )
   }//if (trend == up)

   if (trend == down)
   {
      //if (Bid >= TmaUpper - (TouchBufferPips * Point) )
      if (High[0] >= TmaUpper - (TouchBufferPips * Point) )
      {
         TradingStatus = sell;
         GlobalVariableSet(GvName, 1);
      }//if (High[0] >= TmaUpper - (TouchBufferPips * Point) )
   }//if (trend == down)

}//void LookForTradeSetup()

bool CheckTradingStatusStillValid()
{

   if (TradingStatus == buy)
   {
      if (Ma5Val > TmaMiddle)
      {
         TradingStatus = notrade;
         GlobalVariableDel(GvName);
         return(false);
      }//if (Ma5Val > TmaMiddle)            
   }//if (TradingStatus == buy)


   if (TradingStatus == sell)
   {
      if (Ma5Val < TmaMiddle)
      {
         TradingStatus = notrade;
         GlobalVariableDel(GvName);
         return(false);
      }//if (Ma5Val < TmaMiddle)            
   }//if (TradingStatus == sell)



   //Got this far, so trading status is still valid
   return(true);
   
}//End bool CheckTradingStatusStillValid()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----

   if (RobotSuspended)
   {
      Comment("......................This robot is suspended.................");
      return;
   }//if (RobotSuspended)

   
   static bool TradeExists;
   
   if (OrdersTotal() == 0)
   {
      TicketNo = 0;
      ObjectDelete(stoplossline);
      ObjectDelete(takeprofitline);
      ObjectDelete(hiddenstoplossline);
   }//if (OrdersTotal() == 0)

   ReadIndicatorValues();

   
   //Hourly check that there is still a global in place, to try to ensure that the bot is displaying the correct
   //trading status
   static int OldH1Bars;
   if (OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      OldH1Bars = iBars(NULL, PERIOD_H1);
      if (!GlobalVariableCheck(GvName) ) TradingStatus = notrade;
   }//if (OldH1Bars != iBars(NULL, PERIOD_H1)
   
      
   ///////////////////////////////////////////////////////////////////////////////////////////////
   //Find open trades
   if (OrdersTotal() > 0)
   {
      int OldTicket;//For manual trading
      if (TicketNo != 0) OldTicket = TicketNo;
      TradeExists = DoesTradeExist();
      if (TradeExists)
      {
         TradeManagementModule();
         LookForTradeClosure();
      }//if (TradeExists)
      if (!TradeExists)
      {
         ObjectDelete(stoplossline);
         ObjectDelete(hiddenstoplossline);
         ObjectDelete(takeprofitline);
         //TradingStatus = notrade;
      }//if (TradeExists)
      //Suspend trading if the ea is being used manually and a trade has closed
      if (NB_V1_Trend_Waiting_EA && OldTicket > 0 && TicketNo == 0)
      {
         RobotSuspended = true;
         Alert(Symbol() + " NB V1 trend EA has finished managing a trade and suspended itself");
      }//if (NB_V1_Trend_Waiting_EA)
      
   }//if (OrdersTotal() > 0)

   ///////////////////////////////////////////////////////////////////////////////////////////////
   //Set NB V1 trade direction
   if (NB_V1_Trend_Waiting_EA)
   {
      if (trend == up)
      {
         TradingStatus = buy;
      }//if (trend == up)
      
      if (trend == down)
      {
         TradingStatus = sell;
      }//if (trend == down)
      
   
   }//if (NB_V1_Trend_Waiting_EA)   
 
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trading times
   bool TradeTimeOk = CheckTradingTimes();
   if (!TradeTimeOk)
   {
      Comment("Outside trading hours\nstart_hourm-end_hourm: ", start_hourm, "-",end_hourm, "\nstart_houre-end_houre: ", start_houre, "-",end_houre);
      return;
   }//if (hour < start_hourm)
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ///////////////////////////////////////////////////////////////////////////////////////////////         
   //Trading
   if (TicketNo == 0 && !StopTrading)
   {
      //Look for a trading setup
      if (AutoTrader && TradingStatus != buy && TradingStatus != sell) LookForTradeSetup();

      //Trade trigger.
      //First, check that the setup is still valid
      if (TradingStatus == buy || TradingStatus == sell) 
      {
         bool StillValid = CheckTradingStatusStillValid();
         if (!StillValid) return;
         LookForTradeTrigger();
      }//if (TradingStatus == buy || TradingStatus == sell) 
      
      
   }//if (TicketNo == 0)
   ///////////////////////////////////////////////////////////////////////////////////////////////      

   DisplayUserFeedback();
   
//----
   return(0);
}
//+------------------------------------------------------------------+