//+------------------------------------------------------------------+
//|                                                The New Beast.mq4 |
//|                      Copyright © 2010, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"

//Trading styles
#define  normal "Normal "
#define  aggressive "Aggressive "
#define  gspe "Gspe "
//Trending
#define  up "Market is trending up"
#define  down "Market is trending down"
#define  ranging "Market is ranging"
//Reentry for Recovery
//#define  reentrylinename "Re entry line"
//Breakeven for reentry
#define  breakevenlinename "Break even line"
//'Normal' pending global variable prefixes
#define  NormalPendingLong "TB Normal Pending Long "
#define  NormalPendingShort "TB Normal Pending short "
//'gspe' pending global variable prefixes
#define  gspePendingLong "TB gspe Pending Long "
#define  gspePendingShort "TB gspe Pending short "



//From iExposure for Recovery
#define SYMBOLS_MAX 1024
#define DEALS          0
#define BUY_LOTS       1
#define BUY_PRICE      2
#define SELL_LOTS      3
#define SELL_PRICE     4
#define NET_LOTS       5
#define PROFIT         6



/*
macman contacted me to develop a robot to trade his idea of pending retrace trades once the market has moved outside
the Sixths Gold lines. This robot is the culmination of the development of this robot.

With development, I noticed that drawdown could be significantly reduced if we used the invisible hi-lo of the
period over which the Sixths are calculated. I added more lines to the Sixths:
   - Magenta solid lines at the hi-lo of the previous x H1 candles.
   - Magenta dashed lines in between the Gold and Magenta lines
   
There are three trading methods:
   1) Normal: waits for a touch of the Magenta line, then sends a pending trade in the direction of the coming retrace
      at the dashed Magenta line
   2) Aggressive: sends an immediate retrace-direction trade at the touch of a Magenta line
   3) gspe: this is an attempt to trade the continuation of the trend from within Bob's 'killing zone'
      - market is in a small box above the middle white line, send a pending buy at the top green line
      - market is in a small box below the middle white line, send a pending sell at the bottom gold line

This is a highly successful trading robot - far and away the best I have coded. We need to keep our activities secret
from the criminals as far as possible, so 'pending' trades are not sent to the platform. They are stored in memory in 
Arrays. Details of the trades are stored in files to cater for platform restarts. There are no magic numbers or comments
sent with the trades; these are stored in memory and in files, and displayed on screen during feedback display.

Recovery and Hedging run Normal and Aggressive trades together. gspe trades are treated separately.

TB makes a lot of use of Global Variables to store trade information.
   - open trades in GV's with the ticket no of the trade turned into a string and used as the name of the gv
   - 'pending' trades are stored in NormalPendingLongGvName, NormalPendingShortGvName, gspePendingLongGvName, gspePendingShortGvName
  
Individual trade management functions are called from within MonitorTrades()

gspe trades are closed at the next dashed magenta line

References to the re-entry line have disappeard during the evolution of TB, even though it continued to draw one.
I have removed all re-entry line drawing by commenting out the code; it can be replaced easily if this becomes desirable

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FUNCTIONS LIST

int init()
int start()
void DisplayUserFeedback()

----Trading----
void GetSixths()
bool SendSingleTrade(int type, double lotsize, double price)
bool IsTradingAllowed(int magic)
void CloseAllTrades()
bool DoesTradeExist(int type, int magic)

----Open trades----
void ReadOpenTradesIntoMemory()
void MonitorOpenTrades()
void HaveAnyTradesClosed()

----Re-entry line----
void AddReEntryLine(double price)

----TRADING STYLES MODULE----
void StartAggressive()
void StartNormal()
void StartGspe()

----Time stuff----
bool CheckTradingTimes()

----Hedging----
void HedgingModule(int magic)
bool IsTradeAlreadyHedged(int ticket)
double GetRsi(int tf, int period, int shift)

----Trade management module----
void TradeManagementModule(int magic)
void BreakEvenStopLoss()
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void JumpingStopLoss() 
void HiddenTakeProfit()
void HiddenStopLoss()
void TrailingStopLoss()
void BreakEvenAtGold()
void CloseAtGold()

----Recovery----
void RecoveryModule()
void CheckRecoveryTakeProfit()
int Analyze()
int SymbolsIndex(string SymbolName)

*/

extern string  gen="----General inputs----";
extern int     BarCount=0;
extern bool    StopTrading=false;
extern bool    TradeLong=true;
extern bool    TradeShort=true;
extern int     MaxTradesAllowed=5;
extern bool    CriminalIsECN=false;
extern double  Lot=0.02;
extern int     MinPipsFromLastEntry=50;
extern int     CloseLosingTradesAfterHours=0;
extern string  ts="----Trading style----";
extern bool    Normal=true;
extern int     NormalPipsBuffer=5;
extern bool    Aggressive=true;
extern int     AggressivePipsBuffer=0;
extern bool    Gspe=true;
extern string  gls="----Gold line stuff----";
extern bool    BreakEvenAtGold=false;
extern int     GoldLineBEP=10;
extern bool    CloseTradeAtGold=true;
/*
extern string  tpi="----Take profit----";
extern bool    UseTplTp=false;
extern color   TakeProfitLineColour=Blue;
*/
extern string  rec="----Recovery----";
extern bool    UseRecovery=true;
extern int     Start_Recovery_at_trades=3;  //DC
extern bool    Use1.1.3.3Recovery=false;
extern bool    Use1.1.2.4Recovery=true;
extern color   ReEntryLineColour=Yellow;
extern color   BreakEvenLineColour=Aqua;
extern int     ReEntryLinePips=0;
extern int     RecoveryBreakEvenProfitPips=10;
extern string  tmm="----Trade management module----";
extern bool    DoNotOverload5DigitCriminals=false;
extern string  BE="Break even settings";
extern bool    BreakEven=true;
extern int     BreakEvenPips=40;
extern int     BreakEvenProfit=30;
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=true;
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";
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  hed="----Hedging----";
extern bool    UseHedging=true;
extern int     HedgeAtLossPips=500;
extern double  HedgeLotsMiltiplier=2;
extern string  atrh="Atr hedging";
extern bool    UseAtrHedging=false;
extern int     HedgeAtrPeriod=20;
extern int     HedgeAtrTf=1440;
extern int     HedgeAtrMultiplier=1;
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  mis="----Odds and ends----";
extern bool    ShowManagementAlerts=true;
extern int     DisplayGapSize=30;



//6ths variables.
double         BottomGoldLine;//Bottom, gold line
double         BottomGreenLine;//Bottom, green line
double         MiddleWhiteLine;//Middle, white line
double         TopGreenLine;//Top, green line
double         TopGoldLine;//Top, gold line
double         TopLine, BottomLine;//Top/bottom Magenta lines
double         HalfTopLine, HalfBottomLine;//Dashed magenta lines in between Top/Bottom and Gold lines
int            OldH1Bars;//Tells TB when to check for a repositioning of the Sixths lines

//Trading
int            NormalMagicNumber=1;//Magic number for Normal trades
string         NormalTradeComment=normal;//Trade comment for Normal trades
int            AggressiveMagicNumber=2;//Magic number for Normal trades
string         AggressiveTradeComment=aggressive;//Trade comment for Normal trades
int            gspeMagicNumber=3;//Magic number for Normal trades
string         gspeTradeComment=gspe;//Trade comment for Normal trades
string         trend;//Used in cunjunction with D1 Rsi to determine trend direction for Hedging
double         RsiVal;//For determining trend direction for Hedging
bool           ForceAllTradeDeletion;//Set when hedging is in place and basket upl is positive, so make TB keep trying if whole-position closure fails
//Open trades
int            TN[10];//Ticket numbers
double         TP[10];//Trade open price
double         TM[10];//Trade magic number
int            OpenTrades;//Keeps a tally of the number of open, filled trades
string         GvName;//Will be the ticket number of an individual trade that becomes the name of a Global Variable that stores the magic number for the trade
int            ot;//OrdersTotal() to tell TB to reread trades into memory
   
//Pending trades
//'Normal' trading
string         NormalPendingLongGvName, NormalPendingShortGvName;
int            NormalPendingTradeType;
double         NormalPendingTradePrice;
//'gspe' trading
string         gspePendingLongGvName, gspePendingShortGvName;
int            gspePendingTradeType;
double         gspePendingTradePrice;
int            GspePips=15;//To create a box around the middle line for allowing green line pendings to be sent


//Odds and ends
string         Gap;//For indenting DisplayUserFeedback() comments to take them clear of trade notifications
string         ScreenMessage;//Used in feedback display to contain all the comments within one string

//Hedging      
double         BasketUpl;//Keeps tally of upl so hedged positions can be closed at breakeven
bool           HedgingInProgress;//Set to true if the position is hedged

//Recovery
bool           RecoveryInProgress, TpMoved;
string         ExtSymbols[SYMBOLS_MAX];
int            ExtSymbolsTotal=0;
double         ExtSymbolsSummaries[SYMBOLS_MAX][7];
int            ExtLines=-1;
string         ExtCols[8]={"Symbol",
                           "Deals",
                           "Buy lots",
                           "Buy price",
                           "Sell lots",
                           "Sell price",
                           "Net lots",
                           "Profit"};
int            ExtShifts[8]={ 10, 80, 130, 180, 260, 310, 390, 460 };
int            ExtVertShift=14;
double         buy_price=0.0;
double         sell_price=0.0;

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);

      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot: ", Lot, NL);      
   
   
   if (TradeLong == true) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading long ", NL);
   if (TradeShort == true) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading short ", 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 );
   
   //Trading styles
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   if (Normal) 
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Taking Normal trades: ", ": NormalPipsBuffer = ", NormalPipsBuffer, 
                      ": Magic number = ", NormalMagicNumber, ": NormalTradeComment = ", NormalTradeComment ,NL);
   }//if (Normal) 
   
   if (Aggressive) 
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Taking Aggressive trades: ", ": AggressivePipsBuffer = ", AggressivePipsBuffer, 
                      ": Magic number = ", AggressiveMagicNumber, ": AggressiveTradeComment = ", AggressiveTradeComment ,NL);
   }//if (Normal) 
   
   if (Gspe) 
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Taking gspe trades: ", 
                      ": Magic number = ", gspeMagicNumber, ": GspeTradeComment = ", gspeTradeComment ,NL);
   }//if (Normal) 
   
   //if (TradeGspe) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading gspe", NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, 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, "            end_houre: ", DoubleToStr(start_hourm, 2), 
                      ": end_houre: ", DoubleToStr(end_hourm, 2), NL);
                      
   }//else

   //Display pending trades
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
   if (GlobalVariableCheck(NormalPendingLongGvName) )
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Normal Buy stop ", 
                      DoubleToStr(GlobalVariableGet(NormalPendingLongGvName), Digits), NL);
   }//if (GlobalVariableCheck(NormalPendingLongGvName) )
   
   if (GlobalVariableCheck(NormalPendingShortGvName) )
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Normal Sell stop ", 
                      DoubleToStr(GlobalVariableGet(NormalPendingShortGvName), Digits), NL);
   }//if (GlobalVariableCheck(NormalPendingShortGvName) )
   
   if (GlobalVariableCheck(gspePendingLongGvName) )
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "gspe Buy stop ", 
                      DoubleToStr(GlobalVariableGet(gspePendingLongGvName), Digits), NL);
   }//if (GlobalVariableCheck(gspePendingLongGvName) )
   
   if (GlobalVariableCheck(gspePendingShortGvName) )
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "gspe Sell stop ", 
                      DoubleToStr(GlobalVariableGet(gspePendingShortGvName), Digits), NL);
   }//if (GlobalVariableCheck(gspePendingShortGvName) )
   
   
   
   //Display open trades
   if (OpenTrades > 0)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Open trades", NL);   
      for (int cc = OpenTrades; cc > 0; cc--)
      {
         string type = "Normal";
         if (TM[cc] == 2) type = "Aggressive";
         if (TM[cc] == 3) type = "Gspe";
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, TN[cc], "  ", DoubleToStr(TP[cc], Digits), 
                         ": Magic ", DoubleToStr(TM[cc], 0), ": Type ", type, NL);
      }//for (int cc = OpenTrades; cc > 0; cc--)
      
   }//if (OpenTrades > 0)
   

   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BarCount = ", BarCount, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Recovery starts at ", Start_Recovery_at_trades, " filled trades", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "ReEntryLinePips = ", ReEntryLinePips, NL);
   if (StopTrading) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading suspended", NL);


   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Open trade management: ", NL);
   if (BreakEvenAtGold) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            BreakEvenAtGold = true. GoldLineBEP = ", GoldLineBEP, NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            BreakEvenAtGold = False", NL);
   if (CloseTradeAtGold) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            CloseTradeAtGold = true.", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            CloseTradeAtGold = False", NL);


   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   if (BreakEven)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Breakeven is set to ", BreakEvenPips, " with BreakEvenProfit = ", BreakEvenProfit, NL);
   }//if (BreakEven)
   
   if (JumpingStop)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Jumping stop is set to ", JumpingStopPips);
      if (AddBEP) ScreenMessage = StringConcatenate(ScreenMessage,": BreakEvenProfit = ", BreakEvenProfit);
      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, " pips", NL);
   }//if (TrailingStop)

   if (UseHedging)
   {
      if (!UseAtrHedging) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hedging is enabled ", " with HedgeAtLossPips = ", HedgeAtLossPips, ": HedgeLotsMiltiplier = ", HedgeLotsMiltiplier, NL);
      if (UseAtrHedging)  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hedging is enabled ", 
                                          " using Atr: (Period ", HedgeAtrPeriod, ": Time frame ", HedgeAtrTf,
                                          ": Atr multiplier ", HedgeAtrMultiplier, " )", NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Rsi D1 trend: ", trend, ": Val = ", RsiVal, NL);      
   }//if (UseHedging)


   Comment(ScreenMessage);


}//void DisplayUserFeedback()

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   //Automatic calculation of ReEntryLinePips for Recovery
   if (ReEntryLinePips == 0)
   {
      //Reset ReEntryLinePips according to pair volatility. My thanks to Max for this
      if (StringSubstr(Symbol(), 0, 6) == "AUDCAD") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "AUDCHF") { ReEntryLinePips =180;}
      if (StringSubstr(Symbol(), 0, 6) == "AUDJPY") { ReEntryLinePips =180;}
      if (StringSubstr(Symbol(), 0, 6) == "AUDNZD") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "AUDUSD") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "CADCHF") { ReEntryLinePips =180;}
      if (StringSubstr(Symbol(), 0, 6) == "CADJPY") { ReEntryLinePips =200;}
      if (StringSubstr(Symbol(), 0, 6) == "CHFJPY") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "EURAUD") { ReEntryLinePips =200;}
      if (StringSubstr(Symbol(), 0, 6) == "EURCAD") { ReEntryLinePips =200;}
      if (StringSubstr(Symbol(), 0, 6) == "EURCHF") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "EURGBP") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "EURJPY") { ReEntryLinePips =200;}
      if (StringSubstr(Symbol(), 0, 6) == "EURNZD") { ReEntryLinePips =250;}
      if (StringSubstr(Symbol(), 0, 6) == "EURUSD") { ReEntryLinePips =180;}
      if (StringSubstr(Symbol(), 0, 6) == "GBPCHF") { ReEntryLinePips =200;}
      if (StringSubstr(Symbol(), 0, 6) == "GBPJPY") { ReEntryLinePips =250;}
      if (StringSubstr(Symbol(), 0, 6) == "GBPUSD") { ReEntryLinePips =200;}
      if (StringSubstr(Symbol(), 0, 6) == "NZDJPY") { ReEntryLinePips =180;}
      if (StringSubstr(Symbol(), 0, 6) == "NZDUSD") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "SGDJPY") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "USDCHF") { ReEntryLinePips =180;}
      if (StringSubstr(Symbol(), 0, 6) == "USDCAD") { ReEntryLinePips =150;}
      if (StringSubstr(Symbol(), 0, 6) == "USDJPY") { ReEntryLinePips =180;}
      if (StringSubstr(Symbol(), 0, 6) == "USDNOK") { ReEntryLinePips =1500;}
      if (StringSubstr(Symbol(), 0, 6) == "USDSEK") { ReEntryLinePips =1500;}
   }//if (ReEntryLinePips == 0)
   
   //In case this is a symbol not in the list
   if (ReEntryLinePips == 0) ReEntryLinePips = 200;
   ////////////////////////////////////////////////////////////////////////////////////////////////////
   
   
   ////////////////////////////////////////////////////////////////////////////////////////////////////
   //Adapt the pips inputs to x digit criminals
   double 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;   
 
   GspePips*= multiplier;
   //TpLinePipsFromWhite*= multiplier;
   RecoveryBreakEvenProfitPips*= multiplier;
   ReEntryLinePips*= multiplier;
   NormalPipsBuffer*= multiplier;
   AggressivePipsBuffer*= multiplier;
   MinPipsFromLastEntry*= multiplier;
   BreakEvenPips*= multiplier;
   BreakEvenProfit*= multiplier;
   PipsAwayFromVisualBE*= multiplier;
   JumpingStopPips*= multiplier;
   PipsAwayFromVisualJS*= multiplier;
   TrailingStopPips*= multiplier;
   PipsAwayFromVisualTS*= multiplier;
   StopTrailPips*= multiplier;
   HiddenStopLossPips*= multiplier;
   HiddenTakeProfitPips*= multiplier;
   HedgeAtLossPips*= multiplier;
   ////////////////////////////////////////////////////////////////////////////////////////////////////
   
   
   ////////////////////////////////////////////////////////////////////////////////////////////////////
   //Automatically calculate BarCount if the user has this input set to zero. BarCount tells TB
   //haw far back in time to look for the hi-lo on the H1 chart.
   if (BarCount == 0)
   {
      if (StringSubstr(Symbol(), 0, 6) == "AUDCAD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "AUDCHF") { BarCount = 210; }
      if (StringSubstr(Symbol(), 0, 6) == "AUDJPY") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "AUDNZD") { BarCount = 20; }
      if (StringSubstr(Symbol(), 0, 6) == "AUDSGD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "AUDUSD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "CADCHF") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "CADJPY") { BarCount = 180; }
      if (StringSubstr(Symbol(), 0, 6) == "CHFJPY") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "CHFSGD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "EURAUD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "EURCAD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "EURCHF") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "EURGBP") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "EURJPY") { BarCount = 180; }
      if (StringSubstr(Symbol(), 0, 6) == "EURNZD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "EURSGD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "EURUSD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "GBPAUD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "GBPCAD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "GBPCHF") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "GBPJPY") { BarCount = 180; }
      if (StringSubstr(Symbol(), 0, 6) == "GBPUSD") { BarCount = 155; }
      if (StringSubstr(Symbol(), 0, 6) == "NZDCAD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "NZDCHF") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "NZDJPY") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "NZDUSD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "SGDJPY") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "USDCAD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "USDCHF") { BarCount = 180; }
      if (StringSubstr(Symbol(), 0, 6) == "USDHKD") { BarCount = 170; }
      if (StringSubstr(Symbol(), 0, 6) == "USDJPY") { BarCount = 180; }
      if (StringSubstr(Symbol(), 0, 6) == "USDSGD") { BarCount = 170; }
      
      
      //Now accommodate different time frames
      multiplier = 1;
      if (Period() == PERIOD_M1) multiplier = 60;
      if (Period() == PERIOD_M5) multiplier = 12;
      if (Period() == PERIOD_M15) multiplier = 4;
      if (Period() == PERIOD_M30) multiplier = 2;
      if (Period() == PERIOD_H1) multiplier = 1;
      if (Period() == PERIOD_H4) multiplier = 0.25;
      if (Period() == PERIOD_D1) multiplier = 0.25 / 6;
   
      double dBarCount = BarCount;
      //dBarCount*= multiplier;
      //BarCount = dBarCount;   
      
      //Andy's formula
      BarCount = MathRound(dBarCount/Period()*60);
      
    }//if (BarCount == 0)
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   //Screen display for feedback. Moves the comments away from the left of the chart so they do not
   //clash with trade notifications
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   ////////////////////////////////////////////////////////////////////////////////////////////////////
   

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   //Global variable file names
   //'Normal' trading
   NormalPendingLongGvName = NormalPendingLong + Symbol();
   NormalPendingShortGvName = NormalPendingShort + Symbol();
   
   //Read 'pending' trades in the event of a restart
   //Long
   NormalPendingTradeType=-1;//Initialise the variable
   if (GlobalVariableCheck(NormalPendingLongGvName) )
   {
      NormalPendingTradePrice = GlobalVariableGet(NormalPendingLongGvName);
      NormalPendingTradeType = OP_BUY;
   }//if (GlobalVariableCheck(NormalPendingLongGvName) )
   
   //Short
   if (GlobalVariableCheck(NormalPendingShortGvName) )
   {
      NormalPendingTradePrice = GlobalVariableGet(NormalPendingShortGvName);
      NormalPendingTradeType = OP_SELL;
   }//if (GlobalVariableCheck(NormalPendingShortGvName) )
   
   //'gspe' trading
   gspePendingLongGvName = gspePendingLong + Symbol();
   gspePendingShortGvName = gspePendingShort + Symbol();
   
   //Read 'pending' trades in the event of a restart
   gspePendingTradeType=-1;//Initialise the variable
   gspePendingTradePrice=-1;
   //Long
   if (GlobalVariableCheck(gspePendingLongGvName) )
   {
      gspePendingTradePrice = GlobalVariableGet(gspePendingLongGvName);
      gspePendingTradeType = OP_BUY;
   }//if (GlobalVariableCheck(gspePendingLongGvName) )
   
   //Short
   if (GlobalVariableCheck(gspePendingShortGvName) )
   {
      gspePendingTradePrice = GlobalVariableGet(gspePendingShortGvName);
      gspePendingTradeType = OP_SELL;
   }//if (GlobalVariableCheck(gspePendingShortGvName) )
   
   ////////////////////////////////////////////////////////////////////////////////////////////////////
   
   Comment("..................Waiting for the first tick");
   GetSixths();
   //OldH1Bars = iBars(NULL, PERIOD_H1);//No need to redraw at beginning of start()
   ReadOpenTradesIntoMemory();//Reads the ticket numbers and magic numbers of open trades into memory
   ot = OrdersTotal();
   
   DisplayUserFeedback();
   //start();
   

}//End int init()

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   
   //Delete the Sixths lines
   ObjectDelete("zerosixth");
   ObjectDelete("onesixth");
   ObjectDelete("twosixth");
   ObjectDelete("threesixth");
   ObjectDelete("foursixth");
   ObjectDelete("fivesixth");
   ObjectDelete("sixsixth");
   ObjectDelete("halfbottomsixth");
   ObjectDelete("halftopsixth");
   
   
//----
   return(0);
}
  
void GetSixths()
{

   double value = High[iHighest(NULL,0,MODE_HIGH,BarCount,1)] - Low[iLowest(NULL,0,MODE_LOW,BarCount,1)];      //value top of the chart - value bottom
   double sixth = value/6;
   double valueS = (value*(MathPow(10,Digits)));
   double sixthS = (sixth*(MathPow(10,Digits)));
   
   TopLine = High[iHighest(NULL,0,MODE_HIGH,BarCount,1)];
   if (High[0] > TopLine) TopLine = NormalizeDouble(High[0], Digits);
   HalfTopLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth+sixth+(sixth / 2), Digits);
   BottomLine = Low[iLowest(NULL,0,MODE_LOW,BarCount,1)];
   if (Low[0] < BottomLine) BottomLine = NormalizeDouble(Low[0], Digits);
   HalfBottomLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+(sixth / 2),Digits);
   BottomGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth, Digits);
   BottomGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth, Digits);
   MiddleWhiteLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth, Digits);
   TopGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth, Digits);
   TopGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth+sixth, Digits);

   
   //Calculate ReEntryLinePips
   //if (ReEntryLinePips == 0) CalculateReEntryLinePips();

   if (IsTesting() && !IsVisualMode() ) return;
   
   //if (!IsTesting() && !IsVisualMode() ) 
   //{
      //Draw the lines
      double tl = ObjectGet("fivesixth", OBJPROP_PRICE1);
      double bl = ObjectGet("onesixth", OBJPROP_PRICE1);
      
      if(tl != TopGoldLine || bl != BottomGoldLine) 
      {
         if (ObjectFind("zerosixth") == -1)
         {
            ObjectCreate("zerosixth",1,0,TimeCurrent(),BottomLine);
            ObjectSet("zerosixth",OBJPROP_COLOR,Magenta);
            ObjectSet("zerosixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("zerosixth",OBJPROP_WIDTH,2);     
         }//if (ObjectFind("zerosixth") == -1)
         else ObjectMove("zerosixth",0,TimeCurrent(),BottomLine);
      
         if (ObjectFind("halfbottomsixth") == -1)
         {
            ObjectCreate("halfbottomsixth",1,0,TimeCurrent(),HalfBottomLine);
            ObjectSet("halfbottomsixth",OBJPROP_COLOR,Magenta);
            ObjectSet("halfbottomsixth",OBJPROP_STYLE,STYLE_DASH);
            ObjectSet("halfbottomsixth",OBJPROP_WIDTH,1);     
         }//if (ObjectFind("halfbottomsixth") == -1)
         else ObjectMove("halfbottomsixth",0,TimeCurrent(),HalfBottomLine);
      
         if (ObjectFind("onesixth") == -1)
         {
            ObjectCreate("onesixth",1,0,TimeCurrent(),BottomGoldLine);
            ObjectSet("onesixth",OBJPROP_COLOR,Gold);
            ObjectSet("onesixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("onesixth",OBJPROP_WIDTH,2);     
         }//if (ObjectFind("onesixth") == -1)
         else ObjectMove("onesixth",0,TimeCurrent(),BottomGoldLine);
      
         if (ObjectFind("twosixth") == -1)
         {
            ObjectCreate("twosixth",1,0,TimeCurrent(),BottomGreenLine);
            ObjectSet("twosixth",OBJPROP_COLOR,Green);
            ObjectSet("twosixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("twosixth",OBJPROP_WIDTH,2);    
         }//if (ObjectFind(
         else ObjectMove("twosixth",0,TimeCurrent(),BottomGreenLine);

         if (ObjectFind("threesixth") == -1)
         {
            ObjectCreate("threesixth",1,0,TimeCurrent(),MiddleWhiteLine);
            ObjectSet("threesixth",OBJPROP_COLOR,White);
            ObjectSet("threesixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("threesixth",OBJPROP_WIDTH,2);
         }//if (ObjectFind(
         else ObjectMove("threesixth",0,TimeCurrent(),MiddleWhiteLine);
      
         if (ObjectFind("foursixth") == -1)
         {
            ObjectCreate("foursixth",1,0,TimeCurrent(),TopGreenLine);
            ObjectSet("foursixth",OBJPROP_COLOR,Green);
            ObjectSet("foursixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("foursixth",OBJPROP_WIDTH,2);
         }//if (ObjectFind(
         else ObjectMove("foursixth",0,TimeCurrent(),TopGreenLine);
      
         if (ObjectFind("fivesixth") == -1)
         {
            ObjectCreate("fivesixth",1,0,TimeCurrent(),TopGoldLine);
            ObjectSet("fivesixth",OBJPROP_COLOR,Gold);
            ObjectSet("fivesixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("fivesixth",OBJPROP_WIDTH,2);
         }//if (ObjectFind(
         else ObjectMove("fivesixth",0,TimeCurrent(),TopGoldLine);
            
         if (ObjectFind("halftopsixth") == -1)
         {
            ObjectCreate("halftopsixth",1,0,TimeCurrent(),HalfTopLine);
            ObjectSet("halftopsixth",OBJPROP_COLOR,Magenta);
            ObjectSet("halftopsixth",OBJPROP_STYLE,STYLE_DASH);
            ObjectSet("halftopsixth",OBJPROP_WIDTH,1);     
         }//if (ObjectFind("halftopsixth") == -1)
         else ObjectMove("halftopsixth",0,TimeCurrent(),HalfTopLine);
      
         if (ObjectFind("sixsixth") == -1)
         {
            ObjectCreate("sixsixth",1,0,TimeCurrent(),TopLine);
            ObjectSet("sixsixth",OBJPROP_COLOR,Magenta);
            ObjectSet("sixsixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("sixsixth",OBJPROP_WIDTH,2);     
         }//if (ObjectFind("sixsixth") == -1)
         else ObjectMove("sixsixth",0,TimeCurrent(),TopLine);


      }//if(ctgl != TopGoldLine || cbgl != BottomGoldLine) 
      
   //}//if (!IsTesting() && !IsVisualMode() ) 
          
}//void GetSixths()
  
double GetRsi(int tf, int period, int shift)
{
   return(iRSI(NULL, tf, period, PRICE_CLOSE, shift) );
}//End double GetRsi(int tf, int period, int shift)

bool SendSingleTrade(int type, double lotsize, double price)
{  

   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);
   
   while(IsTradeContextBusy()) Sleep(100);
   
   int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, " ", 0, expiry, col);
   
   if (ticket < 0)
   {
      string stype;
      if (type == OP_BUY) stype = "OP_BUY";
      if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
      if (type == OP_SELL) stype = "OP_SELL";
      if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
      int err=GetLastError();
      Alert(Symbol(), " ", stype," TB order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," TB order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   //Got this far, so trade send succeeded
   OpenTrades++;
   if (OpenTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
   while (!OrderSelect(ticket, SELECT_BY_TICKET) ) Sleep(100);
   TN[OpenTrades] = ticket;
   TP[OpenTrades] = OrderOpenPrice();
   
   return(true);
   
}//bool SendSingleTrade(int type, double lotsize, double price)

bool DoesTradeExist(int type, int magic)
{
   if (GlobalVariablesTotal() == 0) return(false);
   
   for (int cc = 0; cc <= GlobalVariablesTotal(); cc++)
   {
      string name = GlobalVariableName(cc);
      int ticket = StrToDouble(name);
      if (OrderSelect(ticket, SELECT_BY_TICKET) && OrderCloseTime() == 0 
      && GlobalVariableGet(name) == magic && OrderType() == type)
      {
         return(true);
      }//if (OrderSelect(ticket, SELECT_BY_TICKET) && OrderCloseTime() == 0) 
   }//for (int cc = 0; cc <= GlobalVariablesTotal(); cc++)
   
   
   return(false);

}//End bool DoesTradeExist(int type, int magic)


///////////////////////////////////////////////////////////////////////////////////////////////////
//TRADING STYLES MODULE
void StartAggressive()
{

   bool result;
   double SendLots = Lot;
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Check for appropriate distance between trades if there is one already open.
   //Function also checks other filters, if any are being used
   bool TradingAllowed = IsTradingAllowed(2);
   if (!TradingAllowed) return;

   

   /////////////////////////////////////////////////////////////////////////////////////////////////////

   ////////////////////////////////////////////////////////////////////////////////////
   //Using Recovery, so adapt lot sizes
   if (RecoveryInProgress)
   {
      if (OpenTrades == Start_Recovery_at_trades) 
      {
         if (Use1.1.2.4Recovery) SendLots = Lot * 2;         
         if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      }//if (OpenTrades == Start_Recovery_at_trades) 
      
      if (OpenTrades == Start_Recovery_at_trades + 1) 
      {
         if (Use1.1.2.4Recovery) SendLots = Lot * 4;
         if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      }//if (OpenTrades == Start_Recovery_at_trades + 1) 
      
      if (OpenTrades == 4) return;//No further trading is possible
      
      //double RecoveryLineVal = ObjectGet(reentrylinename, OBJPROP_PRICE1);
   }//if (RecoveryInProgress)
  ////////////////////////////////////////////////////////////////////////////////////

   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Look for a trading opportunity
   //Long 
   if (Ask <= BottomLine + (AggressivePipsBuffer * Point) )
   {
      while (IsTradeContextBusy()) Sleep(100);
      RefreshRates();
      result = SendSingleTrade(OP_BUY, SendLots, Ask);
      //if (result) AddReEntryLine(NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits) );         
   }//if (Ask <= BottomLine)
   
   //Short 
   if (Bid >= TopLine - (AggressivePipsBuffer * Point) )
   {
      while (IsTradeContextBusy()) Sleep(100);
      RefreshRates();
      result = SendSingleTrade(OP_SELL, SendLots, Bid);
      //if (result) AddReEntryLine(NormalizeDouble(Bid + (ReEntryLinePips * Point), Digits) );         
   }//if (Bid >= TopLine)
   
   //Set up the magic number & use it to name a GV that holds the magic number of the trade
   if (result)
   {
      TM[OpenTrades] = AggressiveMagicNumber;//Magic number
      string t = DoubleToStr(TN[OpenTrades], 0);
      GlobalVariableSet(t, AggressiveMagicNumber);
   }//if (result)
   

   /////////////////////////////////////////////////////////////////////////////////////////////////////



}//End void StartAggressive()

void StartNormal()
{
   //This function sets a virtual pending order at the half top/bottom lines, then
   //send a market trade when the pending is 'filled' by the market reaching the 'pending' price
   
   bool result;
   double SendLots = Lot;
   


   if (GlobalVariableCheck(NormalPendingLongGvName) )
   {
      ////////////////////////////////////////////////////////////////////////////////////
      //Using Recovery, so adapt lot sizes
      if (RecoveryInProgress)
      {
         if (OpenTrades == Start_Recovery_at_trades) 
         {
            if (Use1.1.2.4Recovery) SendLots = Lot * 2;         
            if (Use1.1.3.3Recovery) SendLots = Lot * 3;
         }//if (OpenTrades == Start_Recovery_at_trades) 
      
         if (OpenTrades == Start_Recovery_at_trades + 1) 
         {
            if (Use1.1.2.4Recovery) SendLots = Lot * 4;
            if (Use1.1.3.3Recovery) SendLots = Lot * 3;
         }//if (OpenTrades == Start_Recovery_at_trades + 1) 
      
         if (OpenTrades == 4) return;//No further trading is possible
      
         //double RecoveryLineVal = ObjectGet(reentrylinename, OBJPROP_PRICE1);
      }//if (RecoveryInProgress)
     ////////////////////////////////////////////////////////////////////////////////////
   
      //Can a 'pending' be filled
      //Long
      if (Ask >= NormalPendingTradePrice && NormalPendingTradePrice > 0 && NormalPendingTradeType == OP_BUY && Ask < BottomGoldLine)
      {
         while (IsTradeContextBusy() ) Sleep(100);
         result = SendSingleTrade(OP_BUY, SendLots, Ask);
         if (result)
         {
            NormalPendingTradePrice = 0;
            NormalPendingTradeType = -1;
            GlobalVariableDel(NormalPendingLongGvName);
            string name = DoubleToStr(TN[OpenTrades], 0);//OpenTrades is incremented by SendSingleTrade
            GlobalVariableSet(name, NormalMagicNumber);
            //AddReEntryLine(NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits) );
         }//if (result)
         
      }//if (Ask >= NormalPendingTradePrice && NormalPendingTradeType == OP_BUY)
      
      //Short
      if (Bid <= NormalPendingTradePrice && NormalPendingTradePrice > 0  && NormalPendingTradeType == OP_SELL && Bid > TopGoldLine)
      {
         while (IsTradeContextBusy() ) Sleep(100);
         result = SendSingleTrade(OP_SELL, SendLots, Bid);
         if (result)
         {
            NormalPendingTradePrice = 0;
            NormalPendingTradeType = -1;
            GlobalVariableDel(NormalPendingShortGvName);
            name = DoubleToStr(TN[OpenTrades], 0);//OpenTrades is incremented by SendSingleTrade
            GlobalVariableSet(name, NormalMagicNumber);
            //AddReEntryLine(NormalizeDouble(Bid + (ReEntryLinePips * Point), Digits) );
         }//if (result)
         
      }//if (Bid <= NormalPendingTradePrice && NormalPendingTradeType == OP_SELL)
      
   
   }//if (GlobalVariableCheck(NormalPendingLongGvName) )
   
   

   //Can TB set a pending?
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Check for appropriate distance between trades if there is one already open.
   //Function also checks other filters, if any are being used
   bool TradingAllowed = IsTradingAllowed(1);
   if (!TradingAllowed) return;

   //Buy
   if (Ask < BottomLine + (NormalPipsBuffer * Point) && HalfBottomLine != NormalPendingTradePrice)
   {
      GlobalVariableSet(NormalPendingLongGvName, HalfBottomLine);
      NormalPendingTradeType = OP_BUY;
      NormalPendingTradePrice = HalfBottomLine;
   }//if (Ask < BottomLine + (NormalPipsBuffer * Point) && HalfBottomLine != NormalPendingTradePrice)
   
   //Sell
   if (Bid > TopLine - (NormalPipsBuffer * Point) && HalfTopLine != NormalPendingTradePrice)
   {
      GlobalVariableSet(NormalPendingShortGvName, HalfTopLine);
      NormalPendingTradeType = OP_SELL;
      NormalPendingTradePrice = HalfTopLine;
   }//if (Bid > TopLine - (NormalPipsBuffer * Point) && HalfTopLine != NormalPendingTradePrice)
   

}//End void StartNormal()

void StartGspe()
{
   //This function sets a virtual pending order at the half top/bottom lines, then
   //send a market trade when the pending is 'filled' by the market reaching the 'pending' price
   
   bool result;
   double SendLots = Lot;
   
   
   //Can a 'pending' be filled
   //Long
   if (Ask >= gspePendingTradePrice && gspePendingTradePrice > 0  && gspePendingTradeType == OP_BUY)
   {
      
      while (IsTradeContextBusy() ) Sleep(100);
      result = SendSingleTrade(OP_BUY, Lot, Ask);
      if (result)
      {
         gspePendingTradePrice = 0;
         gspePendingTradeType = -1;
         GlobalVariableDel(gspePendingLongGvName);
         string name = DoubleToStr(TN[OpenTrades], 0);//OpenTrades is incremented by SendSingleTrade
         GlobalVariableSet(name, gspeMagicNumber);
         //AddReEntryLine(NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits) );
      }//if (result)
      
   }//if (Ask >= gspePendingTradePrice && gspePendingTradeType == OP_BUY)
   
   //Short
   if (Bid <= gspePendingTradePrice && gspePendingTradePrice > 0 && gspePendingTradeType == OP_SELL)
   {
      while (IsTradeContextBusy() ) Sleep(100);
      result = SendSingleTrade(OP_SELL, Lot, Bid);
      if (result)
      {
         gspePendingTradePrice = 0;
         gspePendingTradeType = -1;
         GlobalVariableDel(gspePendingShortGvName);
         name = DoubleToStr(TN[OpenTrades], 0);//OpenTrades is incremented by SendSingleTrade
         GlobalVariableSet(name, gspeMagicNumber);
         //AddReEntryLine(NormalizeDouble(Bid + (ReEntryLinePips * Point), Digits) );
      }//if (result)
      
   }//if (Bid <= gspePendingTradePrice && gspePendingTradeType == OP_SELL)
      
   
  

   //Can TB set a pending?
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Buy
   //if (Ask > MiddleWhiteLine && Ask < NormalizeDouble(MiddleWhiteLine + (GspePips * Point), Digits) )
   if (Ask > MiddleWhiteLine && Ask < TopGreenLine)
   {
      //Only allow one trade at a time
      if (DoesTradeExist(OP_BUY, gspeMagicNumber) ) return;
      GlobalVariableSet(gspePendingLongGvName, TopGreenLine);
      gspePendingTradeType = OP_BUY;
      gspePendingTradePrice = TopGreenLine;
   }//if (Ask > MiddleWhiteLine && Ask < MiddleWhiteLine + (GspePips * Point) )
   
   
   //Sell
   //if (Bid < MiddleWhiteLine && Bid > NormalizeDouble(MiddleWhiteLine - (GspePips * Point), Digits) )
   if (Bid < MiddleWhiteLine && Bid > BottomGreenLine )
   {
      //Only allow one trade at a time
      if (DoesTradeExist(OP_SELL, gspeMagicNumber) ) return;
      GlobalVariableSet(gspePendingShortGvName, BottomGreenLine);
      gspePendingTradeType = OP_SELL;
      gspePendingTradePrice = BottomGreenLine;
   }//if (Bid < MiddleWhiteLine && Bid > MiddleWhiteLine - (GspePips * Point) )
   

}//End void StartGspe()



//END OF TRADING STYLES MODULE
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
void AddReEntryLine(double price)
{
      if (ObjectFind(reentrylinename) > -1) ObjectDelete(reentrylinename);   
      
      
      if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
      {
         int err=GetLastError();      
         Alert("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
         Print("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
         return(0);

      }//if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
      
      ObjectSet(reentrylinename,OBJPROP_COLOR,ReEntryLineColour);
      ObjectSet(reentrylinename,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(reentrylinename,OBJPROP_WIDTH,2);     


}//void AddReEntryLine(int type, double price)
*/
bool IsTradingAllowed(int magic)
{
   //Trades count
   if (OpenTrades >= MaxTradesAllowed) return(false);
   
   
   //TB is only allowed to send multiple trades a reasonable distance apart from one another,
   //so check that the distance is acceptable
   //Min distance from most recently filled trade
   double MostRecentTradePrice = 0;
   
   for (int cc = OpenTrades; cc > 0; cc--)
   {
      OrderSelect(TN[cc], SELECT_BY_TICKET);
      if (OrderCloseTime() != 0 && TM[cc] == magic) return(true);
      if (TM[cc] == magic) 
      {
         MostRecentTradePrice = OrderOpenPrice();
         break;
      }//if (TM[cc] == magic) 
      
   }//for (int cc = OpenTrades; cc > 0; cc--)
      
   //Alert(MostRecentTradePrice);
   if (MostRecentTradePrice == 0) return(true);
   
   double MinDistance = MinPipsFromLastEntry * Point;
   
   
   if (OpenTrades > 0)
   {
      //Normal{ magic number = 1
      if (magic == 1)
      {
         //Possible short trade
         if (Bid > HalfTopLine)
         {
            if (HalfTopLine - MostRecentTradePrice < MinDistance) return(false);
         }//if (Bid > HalfTopLine)
   
   
         //Possible long trade
         if (Ask < HalfBottomLine)
         {
            if (MostRecentTradePrice - HalfBottomLine < MinDistance) return(false);
         }//if (Ask < HalfBottomLine)

      }//if (magic == 1)
   

      //Aggressive trades: Magic number = 2
      //Possible short trade
      if (magic == 2)
      {
         
         if (Bid >= TopLine - (AggressivePipsBuffer * Point) )
         {
            if (Bid - MostRecentTradePrice < MinDistance) return(false);
         }//if (Bid >= TopLine - (AggressivePipsBuffer * Point) )
   
   
         //Possible long trade
         if (Ask <= BottomLine + (AggressivePipsBuffer * Point))
         {
            if (MostRecentTradePrice - Ask < MinDistance) return(false);
         }//if (Ask <= BottomLine + (AggressivePipsBuffer * Point))

      }//if (magic == 2)

   }//if (OpenTrades > 0)
   
     
   

   return(true);

   


}//End bool IsTradingAllowed(int magic)

void ReadOpenTradesIntoMemory()
{

   bool DelGV;
   
   for (int cc = 10; cc >= 0; cc--)
   {
      TN[cc] = -1;
      TP[cc] = 0;
      TM[cc] = 0;
   }//for (cc = 10; cc > 0; cc--)
   
   OpenTrades = 0;
            
   for (cc = 0; cc < GlobalVariablesTotal(); cc++)
   {      
      DelGV = false;
      string name = GlobalVariableName(cc);
      int ticket = StrToDouble(name);
      if (ticket > 0)//Might not be a ticket gv
      {
         if (OrderSelect(ticket, SELECT_BY_TICKET) )
         {
            //Place ticket no and magic no into an array if the trade is still open
            if (OrderSymbol() == Symbol() && OrderCloseTime() == 0)
            {
               OpenTrades++;
               TN[OpenTrades] = OrderTicket();
               TP[OpenTrades] = OrderOpenPrice();
               TM[OpenTrades] = GlobalVariableGet(name);               
            }//if (OrderSymbol() == Symbol() && OrderCloseTime() == 0)
            
            if (OrderSymbol() == Symbol() && OrderCloseTime() > 0) DelGV = true;
         }//if (OrderSelect(ticket, SELECT_BY_TICKET) )
         if (!OrderSelect(ticket, SELECT_BY_TICKET) ) DelGV = true;
         if (DelGV)
         {
            GlobalVariableDel(name);
            cc--;
         }//if (DelGV)     
      }//if (ticket > 0)
      
   }//for (cc = 0; cc <= GlobalVariablesTotal; cc++)
            
   
}//End void ReadOpenTradesIntoMemory()

void HaveAnyTradesClosed()
{

   for (int cc = 1; cc <= OpenTrades; cc++)
   {
      if (!OrderSelect(TN[cc], SELECT_BY_TICKET) || OrderCloseTime() > 0)
      {
         ReadOpenTradesIntoMemory();
         return;
      }//if (!OrderSelect(TB[cc], SELECT_BY_TICKET)
      
   }//for (int cc = 1; cc <= OpenTrades; cc++)
   

}//void HaveAnyTradesClosed()


void MonitorOpenTrades()
{   
   
   //Check for trade closure and adjust trades in memory if so
   HaveAnyTradesClosed();
   
   BasketUpl = 0;
   bool BuyOpen, SellOpen;
   
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = 0; cc <= GlobalVariablesTotal() -1; cc++)
   {
      string name = GlobalVariableName(cc);
      int ticket = StrToDouble(name);
      if (ticket == 0) continue;
      if (!OrderSelect(ticket, SELECT_BY_TICKET) ) continue;
      if (OrderSymbol() == Symbol() && OrderCloseTime() == 0)
      {
         if (OrderProfit() > 0 && ObjectFind(breakevenlinename) == -1 && !RecoveryInProgress 
             && !HedgingInProgress) TradeManagementModule(TM[cc]);
         if (OrderType() == OP_BUY) BuyOpen = true;
         if (OrderType() == OP_SELL) SellOpen = true;
         BasketUpl+= (OrderProfit() + OrderSwap() + OrderCommission() );
         
         if (OrderProfit() < 0 && UseHedging) HedgingModule();
         
         //Close a losing trade
         if (OrderProfit() < 0 && CloseLosingTradesAfterHours > 0 && !RecoveryInProgress && !HedgingInProgress)
         {
            if (TimeLocal() - OrderOpenTime() > CloseLosingTradesAfterHours * 60 * 60)
            {
               bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, Blue);
               if (result) {cc--; ReadOpenTradesIntoMemory(); continue;}
            }//if (TimeLocal() - OrderOpenTime() > CloseLosingTradesAfterHours * 60 * 60)
            
         }//if (OrderProfit() < 0 && CloseLosingTradesAfterHours > 0)
         
         if (ObjectFind(breakevenlinename) > -1 && !HedgingInProgress)
         {
            double take = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
            if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
            {
               while(IsTradeContextBusy()) Sleep(100);
               OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
            }//if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
         }//if (ObjectFind(breakevenlinename) > -1)
         
         /*
         if (ObjectFind(takeprofitlinename) > -1 && ObjectGet(takeprofitlinename, OBJPROP_COLOR) == TakeProfitLineColour)
         {
            take = ObjectGet(takeprofitlinename, OBJPROP_PRICE1);
            if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
            {
               while(IsTradeContextBusy()) Sleep(100);
               OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
            }//if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
         }//if (ObjectFind(takeprofitlinename) > -1)
         */
         
      }//if (OrderSymbol() == Symbol() && OrderCloseTime() == 0)
   }//for (int cc = 0; cc <= GlobalVariablesTotal(); cc++)

   if (BuyOpen && SellOpen) HedgingInProgress = true;
   
   
}//End void MonitorOpenTrades()

////////////////////////////////////////////////////////////////////////////////////////////////
//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(), 5000, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
            ReadOpenTradesIntoMemory();
         }//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(), 5000, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
            ReadOpenTradesIntoMemory();
         }//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)
   
   return(result);

}//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 (Ask >= 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 (Ask >= OrderOpenPrice() 
   } //if (OrderType()==OP_BUY)              			         
    
   if (OrderType()==OP_SELL)
   {
     if (Bid <= 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)
      }//if (Bid <= OrderOpenPrice() 
   }//if (OrderType()==OP_SELL)
      

} // 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)
         {
            ReadOpenTradesIntoMemory();
            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)
         {
            ReadOpenTradesIntoMemory();
            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)
         {
            ReadOpenTradesIntoMemory();
            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)
         {
            ReadOpenTradesIntoMemory();
            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 BreakEvenAtGold()
{
   bool result = true;
   
   if (OrderType() == OP_BUY)
   {
      if (Ask >= BottomGoldLine && OrderStopLoss() == 0)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() + (GoldLineBEP * Point), Digits), 
         OrderTakeProfit(), OrderExpiration(), CLR_NONE);
      }//if (Ask >= BottomGoldLine && OrderStopLoss() == 0)      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (Bid <= TopGoldLine && OrderStopLoss() == 0)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() - (GoldLineBEP * Point), Digits), 
         OrderTakeProfit(), OrderExpiration(), CLR_NONE);
      }//if (Bid <= TopGoldLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_SELL)
   
   if (!result)
   {
      int err=GetLastError();
      if (ShowManagementAlerts==true) Alert("AEB setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("AEB setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)      
         
}//void BreakEvenAtGold()

void CloseAtGold()
{
   bool result = true;
   
   if (OrderType() == OP_BUY)
   {
      if (Ask >= BottomGoldLine)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
         if (result) ReadOpenTradesIntoMemory();      
      }//if (Ask >= BottomGoldLine && OrderStopLoss() == 0)      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (Bid <= TopGoldLine)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
         if (result) ReadOpenTradesIntoMemory();
      }//if (Bid <= TopGoldLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_SELL)
   
   if (!result)
   {
      int err=GetLastError();
      if (ShowManagementAlerts==true) Alert("TB closing of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("TB closing of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)      
         
}//void CloseAtGold()


void TradeManagementModule(int magic)
{
   // 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)
   
   
   //Gole line management for Normal and Aggressive trades
   if (BreakEvenAtGold && OrderProfit() > 0 && magic < 3) BreakEvenAtGold();//gspe magic is 3, so this function does not apply
   
   if (CloseTradeAtGold && OrderProfit() > 0 && magic < 3) CloseAtGold();//gspe magic is 3, so this function does not apply


   //Closure for gpse trades
   if (magic == 3)
   {
      int ticket = OrderTicket();
      string name;
      bool result;
      if (OrderType() == OP_BUY)
      {
         if (Ask >= HalfTopLine)
         {
            while (IsTradeContextBusy() ) Sleep(100);
            result = OrderClose(ticket, OrderLots(), OrderClosePrice(), 5000, Blue);
            if (result)
            {
               name = DoubleToStr(ticket, 0);
               GlobalVariableDel(name);
               ReadOpenTradesIntoMemory();
            }//if (result)            
         }//if (Ask >= HalfTopLine)         
      }//if (OrderType() == OP_BUY)
      
      if (OrderType() == OP_SELL)
      {
         if (Bid <= HalfBottomLine)
         {
            while (IsTradeContextBusy() ) Sleep(100);
            result = OrderClose(ticket, OrderLots(), OrderClosePrice(), 5000, Blue);
            if (result)
            {
               name = DoubleToStr(ticket, 0);
               GlobalVariableDel(name);
               ReadOpenTradesIntoMemory();
            }//if (result)            
         }//if (Ask >= HalfBottomLine)         
      }//if (OrderType() == OP_SELL)
      
   }//if (magic == 3)
   

   if (NoOfTicks >= 10)
   {
      NoOfTicks = 0;//Reset the counter
      
      // Hidden stop loss
      if (HideStopLossEnabled) HiddenStopLoss();
   
      // Hidden take profit
      if (HideTakeProfitEnabled) HiddenTakeProfit();
   
      // Breakeven
      if(BreakEven) BreakEvenStopLoss();
   
      // JumpingStop
      if(JumpingStop) JumpingStopLoss();
   
      //TrailingStop
      if(TrailingStop) TrailingStopLoss();

   }//if (NoOfTicks >= 10)
   

}//void TradeManagementModule(int magic)
//END TRADE MANAGEMENT MODULE
////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////
//RECOVERY MODULE
void RecoveryModule()
{
   //Draw a breakeven line if there is not one in place already.
   //The bot will adjust the tp's during the MonitorOpenTrades function.
   
   if (ObjectFind(breakevenlinename) > -1) return;
   
   buy_price = 0;
   sell_price = 0;
   CheckRecoveryTakeProfit();
   double recovery_profit;
   if (buy_price > 0) 
   {
      recovery_profit = buy_price;
      recovery_profit = NormalizeDouble(buy_price + (RecoveryBreakEvenProfitPips * Point), Digits);
   }//if (buy_price > 0) 
   
   if (sell_price > 0) 
   {
      recovery_profit = sell_price;
      recovery_profit = NormalizeDouble(sell_price - (RecoveryBreakEvenProfitPips * Point), Digits);
   }//if (sell_price > 0) 
   
   ObjectCreate(breakevenlinename,OBJ_HLINE,0,TimeCurrent(), recovery_profit );
   ObjectSet(breakevenlinename,OBJPROP_COLOR,BreakEvenLineColour);
   ObjectSet(breakevenlinename,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(breakevenlinename,OBJPROP_WIDTH,2);
   
}//End void RecoveryModule()

void CheckRecoveryTakeProfit()
{
   //This is adapted from the NB iExposure indicator. I do not understand how it works.
   //There will be redundant code, so anybody wishing to clear it up is most welcome to do so.
   
   ExtLines = 0;
   int    i,col,line;

   ArrayInitialize(ExtSymbolsSummaries,0.0);
   int total=Analyze();
   if(total>0)
   {
      line=0;
      for(i=0; i<ExtSymbolsTotal; i++)
      {
         if (ExtSymbols[i] != Symbol() ) continue;
         if(ExtSymbolsSummaries[i][DEALS]<=0) continue;
         line++;
         //---- add line
         if(line>ExtLines)
         {
            int y_dist=ExtVertShift*(line+1)+1;
            /*for(col=0; col<8; col++)
              {
               name="Line_"+line+"_"+col;
               if(ObjectCreate(name,OBJ_LABEL,windex,0,0))
                 {
                  ObjectSet(name,OBJPROP_XDISTANCE,ExtShifts[col]);
                  ObjectSet(name,OBJPROP_YDISTANCE,y_dist);
                 }
              }*/
            ExtLines++;
         }//if(line>ExtLines)
         //---- set line
         //color  price_colour;//Steve mod
         int    digits=MarketInfo(ExtSymbols[i],MODE_DIGITS);
         double buy_lots=ExtSymbolsSummaries[i][BUY_LOTS];
         double sell_lots=ExtSymbolsSummaries[i][SELL_LOTS];
         if(buy_lots!=0)  buy_price=NormalizeDouble(ExtSymbolsSummaries[i][BUY_PRICE]/buy_lots, Digits);
         if(sell_lots!=0) sell_price=NormalizeDouble(ExtSymbolsSummaries[i][SELL_PRICE]/sell_lots, Digits);
         
      }//for(i=0; i<ExtSymbolsTotal; i++)
   }//if(total>0)


}//End void CheckRecoveryTakeProfit()

int Analyze()
{
   double profit;
   int    i,index,type,total=OrdersTotal();
//----
   for(i=0; i<total; i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS)) continue;
      type=OrderType();
      if(type!=OP_BUY && type!=OP_SELL) continue;
      index=SymbolsIndex(OrderSymbol());
      if(index<0 || index>=SYMBOLS_MAX) continue;
      //----
      ExtSymbolsSummaries[index][DEALS]++;
      profit=OrderProfit()+OrderCommission()+OrderSwap();
      ExtSymbolsSummaries[index][PROFIT]+=profit;
      if(type==OP_BUY)
        {
         ExtSymbolsSummaries[index][BUY_LOTS]+=OrderLots();
         ExtSymbolsSummaries[index][BUY_PRICE]+=OrderOpenPrice()*OrderLots();
        }
      else
        {
         ExtSymbolsSummaries[index][SELL_LOTS]+=OrderLots();
         ExtSymbolsSummaries[index][SELL_PRICE]+=OrderOpenPrice()*OrderLots();
        }
     }
//----
   total=0;
   for(i=0; i<ExtSymbolsTotal; i++)
     {
      if(ExtSymbolsSummaries[i][DEALS]>0) total++;
     }
//----
   return(total);
}//int Analyze()

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SymbolsIndex(string SymbolName)
{
   bool found=false;
//----
   for(int i=0; i<ExtSymbolsTotal; i++)
     {
      if(SymbolName==ExtSymbols[i])
        {
         found=true;
         break;
        }
     }
//----
   if(found) return(i);
   if(ExtSymbolsTotal>=SYMBOLS_MAX) return(-1);
//----
   i=ExtSymbolsTotal;
   ExtSymbolsTotal++;
   ExtSymbols[i]=SymbolName;
   ExtSymbolsSummaries[i][DEALS]=0;
   ExtSymbolsSummaries[i][BUY_LOTS]=0;
   ExtSymbolsSummaries[i][BUY_PRICE]=0;
   ExtSymbolsSummaries[i][SELL_LOTS]=0;
   ExtSymbolsSummaries[i][SELL_PRICE]=0;
   ExtSymbolsSummaries[i][NET_LOTS]=0;
   ExtSymbolsSummaries[i][PROFIT]=0;
//----
   return(i);
}//End int SymbolsIndex(string SymbolName)

//END RECOVERY MODULE
////////////////////////////////////////////////////////////////////////////////////////////////

void CloseAllTrades()
{
   ForceAllTradeDeletion = false;
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = GlobalVariablesTotal(); cc >= 0; cc--)
   {
      string name = GlobalVariableName(cc);
      int ticket = StrToDouble(name);
      if (!OrderSelect(ticket, SELECT_BY_TICKET) ) continue;
      if (OrderSymbol() == Symbol() )
      {
         while(IsTradeContextBusy()) Sleep(100);
         if (OrderType() == OP_BUY || OrderType() == OP_SELL) bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 1000, CLR_NONE);
         if (result) cc++; 
         if (!result) ForceAllTradeDeletion = true;
      }//if (OrderSymbol() == Symbol() )
   
   }//for (int cc = GlobalVariablesTotal(); cc >= 0; cc--)
   ReadOpenTradesIntoMemory();

}//End void CloseAllTrades()

bool IsTradeAlreadyHedged(int ticket)
{

   for (int cc = OrdersTotal() - 1; cc >=0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      string tn = DoubleToStr(ticket, 0);
      if (OrderComment() == tn) return(true);
   }//for (int cc = OrdersTotal() - 1; cc >=0; cc--)
   
   
   return(false);
   
}//End bool IsTradeAlreadyHedged(int ticket)



void HedgingModule()
{
   //Called from MonitorOpenTrades if the trade is loosing
   
   double loss, LossTarget;
   int tn = OrderTicket();
   RefreshRates();
   bool result;
   int ticket;
   
   RsiVal = GetRsi(PERIOD_D1, 20, 0);
   if (RsiVal < 55 && RsiVal > 45) return;

   if (UseAtrHedging) double AtrVal = iATR(NULL, HedgeAtrTf, HedgeAtrPeriod, 0);//For Atr hedging

   if (OrderType() == OP_BUY)
   {
      loss = OrderOpenPrice() - Ask;
      LossTarget = HedgeAtLossPips * Point;
      if (UseAtrHedging) LossTarget = AtrVal;
      
      if (loss > LossTarget )
      {
         bool HedgeExists = IsTradeAlreadyHedged(tn);
         OrderSelect(tn, SELECT_BY_TICKET);
         if (HedgeExists) return;
         if (RsiVal > 45) return;
         //I have taken a trade comment out of SendSingleTrade, so a quick fix is needed
         while (IsTradeContextBusy() ) Sleep(100);
         RefreshRates();
         ticket = OrderSend(Symbol(), OP_SELL, OrderLots() * HedgeLotsMiltiplier, Bid, 500, 0, 0, DoubleToStr(tn, 0), 0, 0, 0);
         if (ticket > -1)
         {
            OpenTrades++;
            OrderSelect(ticket, SELECT_BY_TICKET);
            TN[OpenTrades] = ticket;
            TP[OpenTrades] = OrderOpenPrice();   
         }//if (result)
         
      }//if (loss > LossTarget )
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      loss = Bid - OrderOpenPrice();
      LossTarget = HedgeAtLossPips * Point;
      if (UseAtrHedging) LossTarget = AtrVal;
      
      if (loss > LossTarget )
      {
         HedgeExists = IsTradeAlreadyHedged(tn);
         OrderSelect(tn, SELECT_BY_TICKET);
         if (HedgeExists) return;
         if (RsiVal < 55) return;
         //I have taken a trade comment out of SendSingleTrade, so a quick fix is needed
         while (IsTradeContextBusy() ) Sleep(100);
         RefreshRates();
         ticket = OrderSend(Symbol(), OP_BUY, OrderLots() * HedgeLotsMiltiplier, Ask, 500, 0, 0, DoubleToStr(tn, 0), 0, 0, 0);
         if (ticket > -1)
         {
            OpenTrades++;
            OrderSelect(ticket, SELECT_BY_TICKET);
            TN[OpenTrades] = ticket;
            TP[OpenTrades] = OrderOpenPrice();   
         }//if (result)
         
      }//if (loss > LossTarget )
   }//if (OrderType() == OP_SELL)
   
   
   
}//End void HedgingModule()

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()

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{

   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Delete open trades if a previous attempt failed
   if (ForceAllTradeDeletion)
   {
      CloseAllTrades();
      return;
   }//if (ForcePendingTradeDeletion)
   /////////////////////////////////////////////////////////////////////////////////////////////////////

   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Force a re-read of trades if the orders total has changed.
   //ot is declared at in the general declarations section an stands for OrdersTotal()
   if (ot != OrdersTotal() )
   {
      ReadOpenTradesIntoMemory();
      ot = OrdersTotal();
   }//if (ot != OrdersTotal() )
   
      
   /////////////////////////////////////////////////////////////////////////////////////////////////////

   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Re-read Rsi every hour for hedging
   if (OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      OldH1Bars = iBars(NULL, PERIOD_H1);
      if (UseHedging)
      {
         RsiVal = GetRsi(PERIOD_D1, 20, 0);
         trend = ranging;
         if (RsiVal > 55) trend = up;
         if (RsiVal < 45) trend = down;         
      }//if (UseHedging)
   
   }//if (OldH1Bars != iBars(NULL, PERIOD_H1) )
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Check for a necessary repositioning of the Sixths at a new hi-lo
   if (High[0] > TopLine || Low[0] < BottomLine)
   {
      GetSixths();
      GlobalVariableDel(NormalPendingLongGvName);
      GlobalVariableDel(NormalPendingShortGvName);
   }//if (Ask > TopLine || Bid < BottomLine)
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Monitor existing trades.
   //This function will handle calls to management functions and close profitable/Recovery/Hedge trades as appropriate
   if (OpenTrades > 0) MonitorOpenTrades();
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Reset variables when there are no open trades
   if (OpenTrades == 0)
   {
      HedgingInProgress = false;
      RecoveryInProgress = false;
   }//if (OpenTrades == 0)
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Recovery
      //Recovery
   if (UseRecovery && !HedgingInProgress)
   {
      if (OpenTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
      if (RecoveryInProgress)
      {
         //if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);
         RecoveryModule();
      }//if (RecoveryInProgress)

      //Replace accidentally deleted be line
      if (RecoveryInProgress && ObjectFind(breakevenlinename) == -1)
      //if (ObjectFind(breakevenlinename) == -1 && OpenTrades > TradeNumber) //DC
      {
         RecoveryModule();      
      }//if (ObjectFind(breakevenlinename) == -1 && OpenTrades > 2)
   }//if (UseRecovery)

   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Hedging
   if (HedgingInProgress)
   {
      //if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);
      if (BasketUpl >= 0)
      {
         ForceAllTradeDeletion = true;
         CloseAllTrades();
         ReadOpenTradesIntoMemory();
         return;
      }//if (BasketUpl >= 0)
      
   }//if (HedgingInProgress)
   /////////////////////////////////////////////////////////////////////////////////////////////////////

   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trading hours
   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
   //These functions are a kind of start() for each of the trading styles
   if (Aggressive) StartAggressive();
   if (Normal) StartNormal();
   if (Gspe) StartGspe();
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   //On-screen feedback
   DisplayUserFeedback();
   
}//End int start()
//+------------------------------------------------------------------+