//+-------------------------------------------------------------------+
//|  Brijon Concept of Threes 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  buy "Buy"
#define  sell "Sell"
#define  none "None"
#define  ranging "Ranging"
#define  confused "Confused, and so cannot trade"
#define  trending "Trending"
#define  opentrade "There is a trade open"
#define  stopped "Trading is stopped"
#define  highline "High line"
#define  lowline "Low line"
#define  todayopenline "Today's open line"
#define  yesterdaycloseline "Yesterday's close line"
#define  squarehighline "Square high line"
#define  squarelowline "Square low line"



/*


FUNCTIONS LIST
int init()
int start()

----Trading----

void LookForTradingOpportunities()
bool CanBrijonTrade(int type)
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
bool DoesTradeExist()
bool CloseTrade(ticket)
void LookForTradeClosure()
bool CheckTradingTimes()
int GetMultiplier()


----Trend----
void GetTrend()

----Line drawing----
void DrawLine(string name, datetime time1, double val1, datetime time2, double val2, color col, int width, int style, int ray)
void CalculateThreesLines()
-Bosun-
void CalculateBosunLines()
void GetBosunPosition()
-Square-
void GetSquare()
void SquareTouchTest()


----Indicator readings----
void ReadIndicatorValues()
void GetBB(int shift)
double GetRsi(int tf, int period, int ap, int shift)
double GetMa(int tf, int period, int mashift, int method, int ap, int shift)



----Trade management module----
void TradeManagementModule()
void BreakEvenStopLoss()
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void JumpingStopLoss() 
void HiddenTakeProfit()
void HiddenStopLoss()
void TrailingStopLoss()

*/

extern string  gen="----General inputs----";
extern double  Lot=0.1;
extern int     MagicNumber=0;
extern string  TradeComment="";
extern bool    CriminalIsECN=false;
extern bool    SendAlertNotTrade=true;
extern string  td="----Trading direction----";
extern bool    TradeLong=true;
extern bool    TradeShort=true;
extern string  tpi="----Take profit----";
extern bool    UseCandleLength=false;
extern int     TakeProfit=0;
extern bool    UseSquare=false;
extern string  sli="----Stop loss----";
extern bool    UseStopLoss = false;
extern string  slii="Leave at 0 to use candle length";
extern int     StopLoss=0;
/*
extern string  rsiin="----Rsi trend-determination inputs----";
extern int     RsiTf=1440;
extern int     RsiPeriod=20;
extern string  rsap="Applied price: 0=Close; 1=Open; 2=High";
extern string  rsap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int     RsiAppliedPrice=0;
*/
extern string  tdm="----Trend detection----";
extern bool    UseD1Close=true;
extern bool    UseW1Close=false;
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 = 11;
extern string  Trade_Hours_E= "Evening Hours 12-24";
extern  int    start_houre = 12;
extern  int    end_houre = 24;
extern string  bl="----Bosun lines----";
extern string  bl1="D1 1440: W1 10080: MN1 40320";
extern int     BlTimeFrame=10080;
extern string  sq="----Square----";
extern int     SquareTimeFrame=240;
extern bool    SendSquareTouchAlert=false;
extern string  tmm="----Trade management module----";
extern string  BE="Break even settings";
extern bool    BreakEven=false;
extern int     BreakEvenPips=20;
extern int     BreakEvenProfit=5;
extern bool    HideBreakEvenStop=false;
extern int     PipsAwayFromVisualBE=5;
extern string  JSL="Jumping stop loss settings";
extern bool    JumpingStop=false;
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 bool    UsePercentageOfSquare=false;
extern double  SquarePercentToUse=50;
extern string  hsl1="Hidden stop loss settings";
extern bool    HideStopLossEnabled=false;
extern int     HiddenStopLossPips=20;
extern string  htp="Hidden take profit settings";
extern bool    HideTakeProfitEnabled=false;
extern int     HiddenTakeProfitPips=20;
extern string  mis="----Odds and ends----";
extern bool    ShowManagementAlerts=true;
extern int     DisplayGapSize=30;


//Candle variables
double         Phigh, Plow, Popen, Copen;//Previous hi-lo-open and current open
double         Yclose;//Yesterday close price

//Square
double         SquareHigh, SquareLow;

//Bosun lines
double         Bl[14];//13 levels inc pivot   
string         BlDescription[] = {"Bosun Line S6", "Bosun Line S5", "Bosun Line S4", "Bosun Line S3", "Bosun Line S2", "Bosun Line S1", "Bosun Line Pivot",
                                  "Bosun Line R1", "Bosun Line R2", "Bosun Line R3", "Bosun Line R4", "Bosun Line R5", "Bosun Line R6"};
double         NextResistance, NextSupport;

//Trading variables
int            TicketNo, OpenTrades;


//Rsi
double         RsiVal;
string         trend;

//Moving average
double         MaVal;


//Misc
string         Gap, ScreenMessage;
int            OldBars, OldD1Bars;
string         PipDescription=" pips";
bool           AlertSent;//For manual traders to make the bot only send one trade at a time
bool           SquareAlertSent;//For manual traders to receive an Alert at a touch of the square

void DisplayUserFeedback()
{
   
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), 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);
   */
      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, NL);
   if (TradeLong) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading long", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not trading long", NL);
   if (TradeShort) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading short", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not trading short", NL);
   if (SendAlertNotTrade) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Sending alerts not trades", NL);
   if (TakeProfit > 0) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TakeProfit, PipDescription,  NL);
   if (UseCandleLength) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: Using candle length", NL);
   if (UseSquare) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: Using the Square", NL);
   if (TakeProfit == 0 && !UseCandleLength) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: None", NL);
   if (StopLoss > 0) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop loss: ", StopLoss, PipDescription,  NL);
   if (StopLoss == 0 && UseStopLoss) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using previous candle length to calculate stop loss ", NL);
   if (!UseStopLoss) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not sending a stop loss ", 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, "Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL, NL );
   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,NL, Gap, "Trend detection: Trend is ", trend, NL);      
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Rsi: ", RsiVal, ": Trend is: ", trend, NL);
   if (UseD1Close) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      D1 closes: ", 
                   DoubleToStr(iClose(NULL, PERIOD_D1, 2), Digits), " ", DoubleToStr(iClose(NULL, PERIOD_D1, 1), Digits), 
                   NL);
   
   if (UseW1Close) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      W1 closes: ", 
                   DoubleToStr(iClose(NULL, PERIOD_W1, 2), Digits), " ", DoubleToStr(iClose(NULL, PERIOD_W1, 1), Digits), 
                   NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Bosun lines", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Next resistance: ", DoubleToStr(NextResistance, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "      Next support: ", DoubleToStr(NextSupport, 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 loss enabled at ", HiddenStopLossPips, PipDescription, NL);
   }//if (HideStopLossEnabled)
   
   if (HideTakeProfitEnabled)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hidden take profit enabled at ", HideTakeProfitEnabled, PipDescription, NL);
   }//if (HideTakeProfitEnabled)

   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Upper line: ", DoubleToStr(BbUpper, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Middle line: ", DoubleToStr(BbMiddle, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
   
   Comment(ScreenMessage);


}//void DisplayUserFeedback()


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----

   //Adapt to x digit criminals
   int multiplier = Get_X_Digit_Multiplier();
   
   if (multiplier > 1) PipDescription = " points";
   
   TakeProfit*= multiplier;
   StopLoss*= multiplier;
   BreakEvenPips*= multiplier;
   BreakEvenProfit*= multiplier;
   PipsAwayFromVisualBE*= multiplier;
   JumpingStopPips*= multiplier;
   PipsAwayFromVisualJS*= multiplier;
   TrailingStopPips*= multiplier;
   PipsAwayFromVisualTS*= multiplier;
   StopTrailPips*= multiplier;
   HiddenStopLossPips*= multiplier;
   HiddenTakeProfitPips*= multiplier;


   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   

   if (TradeComment == "") TradeComment = " ";
   DisplayUserFeedback();
   //OldBars = Bars;
   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
   
   
   //ObjectsDeleteAll(0);
   
   for (int cc = ObjectsTotal(); cc >= 0; cc--)
   {
      if (ObjectType(ObjectName(cc)) == OBJ_TREND)
      {
         ObjectDelete(ObjectName(cc) );
         cc++;
      }//if (ObjectType(ObjectName(cc)) == OBJ_TREND)
      
   }//for (int cc = ObjectsTotal; cc >= 0; cc--)
   
   
//----
   return(0);
}

int Get_X_Digit_Multiplier()
{
   //Returns a multiplier to adapt pips inputs etc to x digit crims
   
   int mult;
   if(Digits == 2 || Digits == 4) mult = 1;
   if(Digits == 3 || Digits == 5) mult = 10;
   if(Digits == 6) mult = 100;   
   if(Digits == 7) mult = 1000;   
   
   return(mult);

}//int Get_X_Digit_Multiplier()

////////////////////////////////////////////////////////////////////////////////////////////////
//TRADE MANAGEMENT MODULE

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)
      {
         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 <= sl)  
   }//if (type = OP_BUY)
   
   //Check buy trade
   if (type == OP_SELL)
   {
      sl = NormalizeDouble(stop - (iPipsAboveVisual * Point), Digits);
      if (Ask >= sl)
      {
         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 >= sl)  
   }//if (type = OP_SELL)
   

}//End bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )


void BreakEvenStopLoss() // Move stop loss to breakeven
{

   //Check hidden BE for trade closure
   if (HideBreakEvenStop)
   {
      bool TradeClosed = CheckForHiddenStopLossHit(OrderType(), PipsAwayFromVisualBE, OrderStopLoss() );
      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());
               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 && 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, 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
            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 (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, 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
            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 (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


   //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)
      {
         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 <= sl)      
   }//if (OrderType() == OP_BUY)
   
   //Sell trade
   if (OrderType() == OP_SELL)
   {
      sl = NormalizeDouble(OrderOpenPrice() + (HiddenStopLossPips * Point), Digits);
      if (Ask >= sl)
      {
         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 >= 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)
      {
         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, PipsAwayFromVisualTS, 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
		          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 (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, PipsAwayFromVisualTS, 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
		            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 (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. 

   // Hidden stop loss
   if (HideStopLossEnabled) HiddenStopLoss();

   // Hidden take profit
   if (HideTakeProfitEnabled) HiddenTakeProfit();

   // Breakeven
   if(BreakEven) BreakEvenStopLoss();

   // JumpingStop
   if(JumpingStop) JumpingStopLoss();

   //TrailingStop
   if(TrailingStop) TrailingStopLoss();

   

}//void TradeManagementModule()
//END TRADE MANAGEMENT MODULE
////////////////////////////////////////////////////////////////////////////////////////////////

bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
{
   
   if (IsTradeContextBusy() ) return;
   
   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)  
   
   TicketNo = ticket;
   while (!OrderSelect(ticket, SELECT_BY_TICKET) ) Sleep(100);
   
   //Got this far, so trade send succeeded
   return(true);
   
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)

bool DoesTradeExist()
{
   
   TicketNo = -1;
   
   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();
         return(true);         
      }//if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   return(false);

}//End bool DoesTradeExist()

bool CanBrijonTrade(int type)
{
   //Contains filters that might disallow a trade

   bool TradeAllowed = true;

   return(TradeAllowed);

}//End bool CanBrijonTrade(int type)


void LookForTradingOpportunities()
{


   /*
   //Look to send a new trade at the start of each new M1 candle
   static int M1Bars;   
   if (M1Bars == iBars(NULL, PERIOD_M1) ) return;
   M1Bars = iBars(NULL, PERIOD_M1);
   */

   RefreshRates();
   double take, stop, price;
   int type;
   bool SendTrade;
   double extent = High[1] - Low[1];
   string stype;
   
   
   //Cater for no trend determination choice   
   if (!UseD1Close && !UseW1Close) trend = up;
   
   //Long 
   if (Ask > Phigh && iClose(NULL, PERIOD_M1, 1) > Phigh && trend == up && TradeLong && Copen > Popen)
   //if (Open[0] > High[1])
   {
      //Consult other filters
      if (!CanBrijonTrade(OP_BUY) ) return;
      if (UseCandleLength) take = NormalizeDouble(Ask + extent, Digits);
      if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
      if (UseSquare) take = SquareHigh;
      if (take > 0)
      {
         if (take - Ask < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
      }//if (take > 0)
      
      stop = Plow;
      if (StopLoss > 0) stop = NormalizeDouble(Ask - (StopLoss * Point), Digits);
      if (stop > 0)
      {
         if (Ask - stop < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
      }//if (stop > 0)
      if (!UseStopLoss) stop = 0;
      type = OP_BUY;
      price = Ask;
      SendTrade = true;
      stype = "Buy ";
   }//if (Ask > Phigh)
   
   //Cater for no trend determination choice   
   if (!UseD1Close && !UseW1Close) trend = down;
   
   //Short
   if (Bid < Plow && iClose(NULL, PERIOD_M1, 1) < Plow && trend == down && TradeShort && Copen < Popen)
   //if (Open[0] < Low[1])
   {
      if (!CanBrijonTrade(OP_SELL) ) return;
      if (UseCandleLength) take = NormalizeDouble(Bid - extent, Digits);      
      if (TakeProfit > 0) take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
      if (UseSquare) take = SquareLow;
      if (take > 0)
      {
         if (Bid - take < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
      }//if (take > 0)
      
      stop = Phigh;
      if (StopLoss > 0) stop = NormalizeDouble(Bid + (StopLoss * Point), Digits);
      if (stop > 0)
      {
         if (stop - Bid < MarketInfo(Symbol(), MODE_STOPLEVEL) * Point) return;
      }//if (stop > 0)
      if (!UseStopLoss) stop = 0;
      
      type = OP_SELL;
      price = Bid;
      SendTrade = true;      
      stype = "Sell ";
   }//if (Bid < Plow)
   

   if (SendTrade)
   {
      while(IsTradeContextBusy() ) Sleep(100);
      if (!SendAlertNotTrade) bool result = SendSingleTrade(type, TradeComment, Lot, price, stop, take);
      if (SendAlertNotTrade)
      {
         Alert("Brijon Threes ", Symbol(), " ", stype, "trade has triggered. ",  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) );
         SendMail("Trade alert", Symbol() + " " + stype + " trade has triggered. " +  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS ));
         AlertSent=true;
      }//if (SendAlertNotTrade)
      
   }//if (SendTrade)
   
   //Actions when trade send succeeds
   if (SendTrade && result)
   {
   
   }//if (result)
   
   //Actions when trade send fails
   if (SendTrade && !result)
   {
      //M1Bars = 0;
   }//if (!result)
   
   

}//void LookForTradingOpportunities()

bool CloseTrade(int ticket)
{   
   while(IsTradeContextBusy()) Sleep(100);
   bool result = OrderClose(ticket, OrderLots(), OrderClosePrice(), 1000, CLR_NONE);

   //Actions when trade send succeeds
   if (result)
   {
      return(true);
   }//if (result)
   
   //Actions when trade send fails
   if (!result)
   {
      return(false);
   }//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)
*/

/*
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)
*/

/*
void ReadIndicatorValues()
{

   //GetBB(0);
   
   //Rsi D1 trend
   RsiVal = GetRsi(RsiTf, RsiPeriod, RsiAppliedPrice, 0);
   trend = ranging;
   if (RsiVal > 55) trend = up;
   if (RsiVal < 45) trend = down;
   
   
   //MaVal = GetMa(MaTF, MaPeriod, MaShift, MaMethod, MaAppliedPrice, 0);
   
   
}//void ReadIndicatorValues()
*/

//End Indicator module
////////////////////////////////////////////////////////////////////////////////////////////////

void LookForTradeClosure()
{
   //Close the trade if appropriate
   
   if (!OrderSelect(TicketNo, SELECT_BY_TICKET) ) return;
   
   /*
   //At the mo, trades are only set to close on a trend change, so
   //look to send a new trade at the start of each new M1 candle
   static int M1Bars;   
   if (M1Bars == iBars(NULL, PERIOD_M1) ) return;
   M1Bars = iBars(NULL, PERIOD_M1);
   */
   
   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(TicketNo);
      //Actions when trade send succeeds
      if (result)
      {
   
      }//if (result)
   
      //Actions when trade send fails
      if (!result)
      {
         //M1Bars = 0;
      }//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 DrawLine(string name, datetime time1, double val1, datetime time2, double val2, color col, int width, int style, int ray)
{
   //Plots a trendline with the given parameters
   
   ObjectDelete(name);
   
   ObjectCreate(name, OBJ_TREND, 0, time1, val1, time2, val2);
   ObjectSet(name, OBJPROP_COLOR, col);
   ObjectSet(name, OBJPROP_WIDTH, width);
   ObjectSet(name, OBJPROP_STYLE, style);
   ObjectSet(name, OBJPROP_RAY, ray);
   

}//

void CalculateThreesLines()
{
   //Draws the hi-lo of the previous candle, plus the open of current candle at an appropriate colour
//double         Phigh, Plow, Popen, Copen;//Previous hi-lo-open and current open
//#define  highline "High line"
//#define  lowline "Low line"
//#define  todayopenline "Open line"
   
   Phigh = High[1];
   Plow = Low[1];
   Popen = Open[1];
   Copen = Open[0];
   
   datetime time1, time2;
   time1 = Time[1];   
   time2 = time1 + ((Period() * 60) * 2);
   
   //Previous High
   DrawLine(highline, time1, Phigh, time2, Phigh, Blue, 2, STYLE_SOLID, false);
   
   //Previous Low
   DrawLine(lowline, time1, Plow, time2, Plow, Blue, 2, STYLE_SOLID, false);
   

   //Currenct candle Open
   color col = White;
   if (Copen > Popen) col = Gold;
   if (Copen < Popen) col = Red;
   DrawLine(todayopenline, time1, Copen, time2, Copen, col, 2, STYLE_SOLID, false);
      

   //Draw the previous D1 close line
   if (OldD1Bars != iBars(NULL, PERIOD_D1) )
   {
      Yclose = iClose(NULL, PERIOD_D1, 1);
      OldD1Bars = iBars(NULL, PERIOD_D1);
      DrawLine(yesterdaycloseline, time1, Yclose, time2, Yclose, Turquoise, 1, STYLE_DOT, true);
   }//if (OldD1Bars != iBars(NULL, PERIOD_D1) )
   

}//void CalculateThreesLines()

void GetTrend()
{
   trend = none;
   //'Naked' threes
   if (!UseD1Close && !UseW1Close)
   {
      if (Bid > Yclose) trend = up;
      if (Bid < Yclose) trend = down;
   }//if (!UseD1Close && !UseW1Close)
   
   
   //D1 close prices only
   if (UseD1Close)
   {
      if (iClose(NULL, PERIOD_D1, 1) > iClose(NULL, PERIOD_D1, 2)) trend = up;
      if (iClose(NULL, PERIOD_D1, 1) < iClose(NULL, PERIOD_D1, 2)) trend = down;
   }//if (UseD1Close)
   
   //W1 close prices only
   if (UseW1Close && !UseD1Close) 
   {
      if (iClose(NULL, PERIOD_W1, 1) > iClose(NULL, PERIOD_W1, 2)) trend = up;      
      if (iClose(NULL, PERIOD_W1, 1) < iClose(NULL, PERIOD_W1, 2)) trend = down;
      
   }//if (UseW1Close && !UseD1Close) 
   
   
   //W1 and D1 close prices
   if (UseW1Close && UseD1Close) 
   {
      if (trend == up)
      {
         if (iClose(NULL, PERIOD_W1, 1) > iClose(NULL, PERIOD_W1, 2) 
         && iClose(NULL, PERIOD_D1, 1) > iClose(NULL, PERIOD_D1, 2)) trend = up;
      }//if (trend == up)
   
      if (trend == down)
      {
         if (iClose(NULL, PERIOD_W1, 1) < iClose(NULL, PERIOD_W1, 2) 
         && iClose(NULL, PERIOD_D1, 1) < iClose(NULL, PERIOD_D1, 2)) trend = down;
      }//if (trend == down)
   
   }//if (UseW1Close && UseD1Close) 
   
   

}//End void GetTrend()

void CalculateBosunLines()
{
   //The calculations code for this comes from Bosun_Kines.mq4, coded by IgorAD and modified by Kris.
   //My thanks to both of these individuals.
   
   double close = iClose(NULL,BlTimeFrame,1);
  
   Bl[12] = close * 1.5000;
   Bl[11] = close * 1.2500;
   Bl[10] = close * 1.1250;
   Bl[9] = close * 1.0625;
   Bl[8] = close * 1.0312;
   Bl[7] = close * 1.0156;
   Bl[6] = close;
   Bl[5] = close * 0.9844;
   Bl[4] = close * 0.9688;
   Bl[3] = close * 0.9375;
   Bl[2] = close * 0.8750;
   Bl[1] = close * 0.7500;
   Bl[0] = close * 0.5000;

   //Draw the lines
   datetime time1, time2;
   time1 = Time[1] - (60 * 3);   
   time2 = time1 + ((Period() * 60) * 3);
   
   for (int cc = 0; cc <= 12; cc++)
   {
      string name = "Bosun line ";
      DrawLine(BlDescription[cc], time1, Bl[cc], time2, Bl[cc], Chartreuse, 2, STYLE_SOLID, false);
   }//for (int cc = 0; cc <= 12; cc++)
   

}//End void CalculateBosunLines()

void GetBosunPosition()
{
//double         NextResistance, NextSupport;

   RefreshRates();
   //Extremes - highly unlikely
   if (Bid < Bl[0])
   {
      NextResistance = Bl[0];
      NextSupport = 0;
      return;
   }//if (Bid < Bl[0])
   
   if (Bid > Bl[12])
   {
      NextResistance = 100000;
      NextSupport = Bl[12];
      return;
   }//if (Bid > Bl[12])
   
   for (int cc = 1; cc <= 11; cc++)
   {
      if (Bid >= Bl[cc] && Bid <= Bl[cc + 1] )
      {
         NextResistance = Bl[cc + 1];
         NextSupport = Bl[cc];
         return;
      }//if (Bid >= Bl[cc] && Bid <= Bl[cc + 1] )
      
   }//for (int cc = 1; cc <= 11; cc++)
   

}//End void GetBosunPosition()

void GetSquare()
{
   /*
   The square is a yellow box that defines the highest and lowest of the previous 3 candles,
   with a user choice of time frame
   */
   int tf = SquareTimeFrame;
   int nBars = 3;
   int shift = 1;
   if (tf > PERIOD_H1) { // adjust to H1 bars to avoid the "broker-GMT-offset syndrom" on H4 bars or higher
     nBars *= tf/PERIOD_H1;
     shift *= tf/PERIOD_H1;
     tf = PERIOD_H1;
   }
   
   int highest = iHighest(NULL, tf, MODE_HIGH, nBars, shift);
   SquareHigh = iHigh(NULL, tf, highest);
   int lowest = iLowest(NULL, tf, MODE_LOW, nBars, shift);
   SquareLow = iLow(NULL, tf, lowest);
   
   //Draw the lines
   datetime time1, time2;
   time1 = iTime(NULL, tf, nBars+shift-1);
   time2 = Time[0];
   DrawLine(squarehighline, time1, SquareHigh, time2, SquareHigh, Yellow, 3, STYLE_SOLID, false);
   DrawLine(squarelowline, time1, SquareLow, time2, SquareLow, Yellow, 4, STYLE_SOLID, false);

}//End void GetSquare()

void SquareTouchTest()
{
   //Sends al alert at a touch of the square
   
   if (Ask >= SquareHigh)
   {
      Alert("Brijon Threes ", Symbol(), " touch of the square High. ",  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) );
      SendMail("Square touch alert",  Symbol() + " touch of the square High. " +  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS ));
      SquareAlertSent = true;
   }//if (Ask >= SquareHigh)
   
   if (Bid <= SquareLow)
   {
      Alert("Brijon Threes ", Symbol(), " touch of the square Low. ",  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) );
      SendMail("Square touch alert",  Symbol() + " touch of the square Low. " +  TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS ));
      SquareAlertSent = true;
   }//if (Ask >= SquareHigh)
   

}//void SquareTouchTest()

int GetMultiplier()
{
   //Returns a multiplying factor to turn the result of price calculations into full pips
   int multiplier;
   if (Digits == 2) multiplier = 100;
   if (Digits == 3) multiplier = 1000;
   if (Digits == 4) multiplier = 10000;
   if (Digits == 5) multiplier = 100000;
   if (Digits == 6) multiplier = 1000000;//Not tested this one
   
   return(multiplier);
   

}//End int GetMultiplier()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----

   if (!IsDemo() && !SendAlertNotTrade)
   {
      Alert("Live trading with this EA is not allowed yet.");
      return;
   }//if (!IsDemo() )
   
   static bool ThereWasATradeOpen;
   static bool TradeExists;
   static bool Sleeping = true;
   
   //Define trend
   GetTrend();
   //Get position of market in relation to Bosun lines
   GetBosunPosition();
   //Square
   //extern bool    UsePercentageOfSquare=false;
   //   extern double  SquarePercentToUse=50;
   static int LastSquareUpdate;
   if (LastSquareUpdate != iTime(NULL,Period(),0))
   {      
      GetSquare();
      LastSquareUpdate = iTime(NULL,Period(),0);
      SquareAlertSent=false;
      //Adjust trailing stop pips if necessary. Chaotic place to do this, but the code has to go somewhere
      if (UsePercentageOfSquare)
      {
         //Calculate percentage of square in pips
         int multiplier = GetMultiplier();
         double extent = (SquareHigh - SquareLow) * multiplier;
         TrailingStopPips = extent * (SquarePercentToUse / 100);
      }//if (UsePercentageOfSquare)
      
   }
   //Send an alert at the touch of the square
   if (SendSquareTouchAlert && !SquareAlertSent) SquareTouchTest();
   
   if (Sleeping)
   {
      Comment("              Sleeping");
      if (OldBars != Bars)
      {
         Sleeping = false;
      }//if OldBars != Bars)
      else return;
   }//if (Sleeping)
   
   //ReadIndicatorValues();
   
   ///////////////////////////////////////////////////////////////////////////////////////////////
   //New candle
   if (OldBars != Bars)
   {
      CalculateThreesLines();//Draw hi-lo-open lines. Also D1 close bar
      CalculateBosunLines();
      AlertSent=false;//For manual traders
      OldBars = Bars;
   }//if (OldBars != Bars)
   
   
   ///////////////////////////////////////////////////////////////////////////////////////////////


   if (OrdersTotal() == 0)
   {
      TicketNo = -1;
   }//if (OrdersTotal() == 0)

   //ReadIndicatorValues();

   
      
   ///////////////////////////////////////////////////////////////////////////////////////////////
   //Find open trades
   TradeExists = DoesTradeExist();
   if (TradeExists )
   {
      ThereWasATradeOpen = true;         
      if (OrderProfit() > 0) TradeManagementModule();
      LookForTradeClosure();
   }//if (TradeExists)


   //Post trade closure Sleep
   if (!TradeExists && ThereWasATradeOpen)
   {
      ThereWasATradeOpen = false;
      Comment("              A trade has closed. I am sleeping until the next candle opens.");
      Sleeping = true;
      OldBars = Bars;
      return;
   }//if (!TradeExists && ThereWasATradeOpen)
   
   ///////////////////////////////////////////////////////////////////////////////////////////////
   
   
 
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //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 (SendAlertNotTrade && AlertSent == true)
   {
      DisplayUserFeedback();
      return;
   }//if (SendAlertNotTrade && AlertSent == true)
   
   if (TicketNo == -1)
   {
      LookForTradingOpportunities();
   }//if (TicketNo == -1)
   ///////////////////////////////////////////////////////////////////////////////////////////////      

   DisplayUserFeedback();
   
//----
   return(0);
}
//+------------------------------------------------------------------+