//+------------------------------------------------------------------+
//|                                                    The Beast.mq4 |
//|                                 Copyright © 2010, Steve Hopwood. |
//|                              http://www.hopwood3.freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Steve Hopwood."
#property link      "http://www.hopwood3.freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"

//Trading styles
#define  countertrendtrade "Counter Trend"
#define  trendtrade "Trend"
//Trending
#define  up "Market is trending up"
#define  down "Market is trending down"
#define  ranging "Market is ranging"
#define  none "None"
#define  buy "Looking for a Buy trigger"
#define  sell "Looking for a Sell trigger"
#define  notrade "Not looking for a trade trigger"
#define  globalprefix "Beastie trend "
#define  opentrade "There is a trade open"
#define  stoplossline "Stop loss line"
#define  hiddenstoplossline "Hidden stop loss line"
#define  takeprofitline "Take profit line"
#define  hiddentakeprofitline "Hidden take profit line"
//Reentry for Recovery
#define  reentrylinename "Re entry line"
//Breakeven for reentry
#define  breakevenlinename "Break even line"
//Counter trend pending global variable prefixes
#define  CtPendingLong "Beastie CT Pending Long "
#define  CtPendingShort "Beastie CT Pending short "
#define  alertsent "Alert sent" 

//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



/*
FUNCTIONS LIST

int init()
int deinit()
int start()
void DisplayUserFeedback()

bool SendSingleTrade(int type, double lotsize, double price, string comment, int magic, double stop, double take)

----TRADING STYLES MODULE----
void StartCT()
void StartTrendTrading()
----Trend Trading----
void StartTrendTrading()
void LookForTradeSetup()
void LookForTradeTrigger()
void SetHiddenStop(int type, double price, int HiddenPips)
bool DoesTradeExist()
bool CheckTradingStatusStillValid()
void GetConvergence()
void SendTtWithCT(int type)
----Counter Trend Trading----
void StartCT()
void GetSixths()
bool IsTradingAllowed()
void CloseAllTrades()
void CalculateTradeClosureLine()
----Common----
bool SpreadCheck()


----Indicator readings----
void ReadIndicatorValues()
void GetTMA()
double GetMa(int tf, int period, int mashift, int method, int ap, int shift)
double GetLow()
double GetHigh()


----Open CT trades----
void ReadOpenTradesIntoMemory()
void MonitorOpenTrades()
void HaveAnyTradesClosed()

----Re-entry line----
void AddReEntryLine(double price)

----Time stuff----
bool CheckCtTradingTimes()
bool CheckTtTradingTimes()


----Trade management module for trend trades----
void TradeManagementModule(int magic)
void BreakEvenStopLoss()
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void JumpingStopLoss() 
void TrailingStopLoss()
bool LookForTrendTradeClosure()

----Trade management module for CT trades----
void BreakEvenAtGold()
void CloseAtLine()

----Recovery - CT trades only----
void RecoveryModule()
void CheckRecoveryTakeProfit()
int Analyze()
int SymbolsIndex(string SymbolName)

Here is an auto bar count emailed to me by Scoobs. I intend playing with it as some stage.
Coders might care to do so and report results.
//+------------------------------------------------------------------+
//| expert NumOfBars function                            |
//+------------------------------------------------------------------+
int NumOfBars(string symbol)
  {
    int Multiplier = 0;
    int BarCount = 170;
    int pDigits = MarketInfo(symbol,MODE_DIGITS);
    if(pDigits == 2 || pDigits == 4) Multiplier = 1;
    if(pDigits == 3 || pDigits == 5) Multiplier = 10;
    if(iATR(symbol,1440,14,0)/MarketInfo(symbol,MODE_POINT)>(100*Multiplier)) BarCount = 180;
    if(iATR(symbol,1440,14,0)/MarketInfo(symbol,MODE_POINT)>(150*Multiplier)) BarCount = 190;
    if(iATR(symbol,1440,14,0)/MarketInfo(symbol,MODE_POINT)>(200*Multiplier)) BarCount = 200;
    if(iATR(symbol,1440,14,0)/MarketInfo(symbol,MODE_POINT)>(250*Multiplier)) BarCount = 210;
    return(BarCount);
  }


*/

extern string  ct1="=============================================================";
extern string  ct13="----COUNTER TREND INPUTS----";
extern bool    TradeCounterTrend=true;
extern bool    CtAlertNotTrade=false;
extern bool    CtAlertAndTrade=true;
extern int     CtPipsBuffer=10;
extern int     BarCount=0;
extern bool    CtTradeLong=true;
extern bool    CtTradeShort=true;
extern int     MaxTradesAllowed=5;
extern double  CtLot=0.2;
extern int     MinPipsFromLastEntry=50;
extern int     CloseLosingTradesAfterHours=0;
extern bool    TrendTradeWithCT=true;
extern string  gls="----Gold line break even----";
extern bool    BreakEvenAtGold=false;
extern int     GoldLineBEP=2;
extern string  acc="----CT trade closure----";
extern bool    CloseTradeAtGold=false;
extern bool    CloseTradeAtGreen=false;
extern bool    CloseTradeAtMiddleWhiteLine=false;
extern string  acc1="AutoCalc over rides the above";
extern bool    AutoCalcTradeClosureLine=true;
extern string  rec="----Recovery----";
extern bool    UseRecovery=true;
extern int     Start_Recovery_at_trades=2;
extern bool    Use1.1.3.3Recovery=false;
extern bool    Use1.1.2.4Recovery=true;
extern color   ReEntryLineColour=Turquoise;
extern color   BreakEvenLineColour=Aqua;
extern int     ReEntryLinePips=0;
extern int     RecoveryBreakEvenProfitPips=20;
extern string  tt="----Trading hours----";
extern string  Ct_Trade_Hours= "Set Morning & Evening Hours";
extern string  Ct_Trade_Hoursi= "Use 24 hour, local time clock";
extern string  Ct_Trade_Hours_M= "Morning Hours 0-12";
extern  int    Ct_start_hourm = 0;
extern  int    Ct_end_hourm = 12;
extern string  Ct_Trade_Hours_E= "Evening Hours 12-24";
extern  int    Ct_start_houre = 12;
extern  int    Ct_end_houre = 24;

extern string  ct2="=============================================================";
extern string  tt1="----TREND TRADING INPUTS----";
extern bool    TradeTrend=true;
extern bool    TtAlertNotTrade=false;
extern bool    TtAlertAndTrade=true;
extern double  TtLot=0.2;
extern int     VisualStopLoss=600;
extern int     TouchBufferPips=10;
extern string  sls="----Stop loss----";
extern string  ps="Previous swing";
extern bool    UseSwing=true;
extern double  HiddenSwingStopLossMultiplier=3;
extern int     PipsAddToStopLoss=30;
extern int     MinStopLoss=50;
extern string  tma="TMA";
extern bool    UseTma=false;
extern double  HiddenTmaStopLossMultiplier=1;
extern string  tps="----Take Profit stuff----";
extern int     TakeProfit=200;
extern bool    MoveTpLineWithTMA=false;
extern string  tpsll="Take profit and stop loss lines";
extern color   TpLineColour=Green;
extern color   SlLineColour=Red;
extern string  cvf="----Convergence filter----";
extern bool    UseConvergenceFilter=false;
extern int     ConvergenceLookBackBars=5;
extern int     MaxPipsDifferenceAllowed=7;
extern string  ts="----Trading allowed----";
extern bool    TtTradeLong=true;
extern bool    TtTradeShort=true;
extern string  th="----Trading hours----";
extern string  Tt_Trade_Hours= "Set Morning & Evening Hours";
extern string  Tt_Trade_Hoursi= "Use 24 hour, local time clock";
extern string  Tt_Trade_Hours_M= "Morning Hours 0-12";
extern  int    Tt_start_hourm = 0;
extern  int    Tt_end_hourm = 12;
extern string  Tt_Trade_Hours_E= "Evening Hours 12-24";
extern  int    Tt_start_houre = 12;
extern  int    Tt_end_houre = 24;
extern string  mas="----Moving Averages & Fractals----";
extern string  mas1="Leave these alone unless";
extern string  mas2="you know what you are doing.";
extern string  w1ma="W1 moving average";
extern int     W1Tf=0;
extern int     W1Period=240;
extern string  five="5 x 5 moving average";
extern int     MA5x5Tf=0;
extern int     MA5xPeriod=5;
extern int     MA5xShift=5;
extern string  fra="Fractals - measures the swing";
extern int     FractalTF=0;

//string   TC[] = 
/*
extern string  tpi="----Take profit----";
extern bool    UseTplTp=false;
extern color   TakeProfitLineColour=Blue;
*/
extern string  ct3="=============================================================";
extern string  tmm="----Trade management module----";
extern string  BE="Break even settings";
extern bool    BreakEven=true;
extern int     BreakEvenPips=20;
extern int     BreakEvenProfit=10;
extern bool    HideBreakEvenStop=true;
extern int     PipsAwayFromVisualBE=3;
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=true;
extern int     PipsAwayFromVisualJS=10;
extern string  TSL="Trailing stop loss settings";
extern bool    TrailingStop=true;
extern int     TrailingStopPips=30;
extern bool    HideTrailingStop=true;
extern int     PipsAwayFromVisualTS=10;
extern bool    TrailAfterBreakevenOnly=true;
extern bool    StopTrailAtPipsProfit=false;
extern int     StopTrailPips=0;
extern string  hsl1="Hidden stop loss settings";
//bool           HideStopLossEnabled=true;
extern int     HiddenStopLossPips=20;
extern string  htp="Hidden take profit settings";
//bool    HideTakeProfitEnabled=false;
extern int     HiddenTakeProfitPips=20;
/*
extern string  hed="----Hedging----";
extern bool    UseHedging=false;
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  ct4="=============================================================";
extern string  mis="----Odds and ends----";
extern bool    CriminalIsECN=false;
extern int     MaxSpread=10;
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            CtMagicNumber=1;//Magic number for Counter Trend trades
string         CtTradeComment=countertrendtrade;//Trade comment for demo Counter Trend trades
int            TtMagicNumber=2;//Magic number for Trend trades
string         TtTradeComment=trendtrade;//Trade comment for demo Trend trades
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
bool           CtTradeTimeOk, TtTradeTimeOk;

//Trend Trading variables
string         TtGvName;//Stores the name of the global variable that holds the trading status
string         TradingStatus;// 0 = waiting to buy; 1 = waiting to sell; -1 = not looking for a trade
double         HiddenStopLoss, HiddenTakeProfit;
int            TicketNo;
bool           ConvergenceHappening;
double         PrevTmaMiddle;

//Trend
string         trend;

//Moving averages
double         W1MaVal, Ma5Val;
double         TmaUpper, TmaMiddle, TmaLower;

//Auto-calc Counter Trend trade closure. Set up arrays according to NB descriptions
string         VeryVolatile[] = {"GBPNZD", "EURNZD", "GBPAUD", "GBPJPY"};//Targets the middle white line
//Bob describes first line of MediumVolatile array as 'Volatile' and the second as 'Medium volatile, so this array 
//could be further split, so the first groupd could target half-way between Green and Gold. We shall see.
string         MediumVolatile[] = {"GBPCHF", "CADJPY", "EURCAD", "EURAUD", "USDCHF", "GBPUSD", "EURJPY",
                                    "NZDJPY", "AUDCHF", "AUDJPY", "USDJPY", "EURUSD", "NZDCHF", "CADCHF"};//Targets nearest green line
string         LowVolatile[] = {"AUDNZD", "NZDUSD", "CHFJPY", "AUDCAD", "USDCAD", "NZDCAD", "AUDUSD", "EURCHF", "EURGBP"};//Targets nearest Gold line

//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
//Counter Trend' trading
string         CtPendingLongGvName, CtPendingShortGvName;
int            CtPendingTradeType;
double         CtPendingTradePrice;
//'gspe' trading
string         gspePendingLongGvName, gspePendingShortGvName;
int            gspePendingTradeType;
double         gspePendingTradePrice;


//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
string         PipDescription=" pips";

//Hedging      
//double         BasketUpl;//Keeps tally of upl so hedged positions can be closed at breakeven
//bool           HedgingInProgress = false;//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);
      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), NL);
   int spread = MarketInfo(Symbol(), MODE_SPREAD);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MaxSpread = ", MaxSpread, " (Current = ", spread, ")", NL);      
   
   //Trading styles
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   if (TradeCounterTrend && CtTradeTimeOk)
   {  
      
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "COUNTER-TREND TRADING - ");            
      if (!CtAlertNotTrade) ScreenMessage = StringConcatenate(ScreenMessage,"auto-trading", NL);
      if (CtAlertNotTrade) ScreenMessage = StringConcatenate(ScreenMessage, "using Beastie to generate trade alerts, but not to send the trades", NL);
      if (CtAlertAndTrade) ScreenMessage = StringConcatenate(ScreenMessage, "using Beastie to generate both trades and trade alerts", NL);

      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CtPipsBuffer = ", CtPipsBuffer, 
                      ": Magic number = ", CtMagicNumber, ": CtTradeComment = ", CtTradeComment, NL);
      if (CtTradeLong == true) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading long ");
      if (CtTradeShort == true) ScreenMessage = StringConcatenate(ScreenMessage, ": Trading short ", NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CtLot: ", CtLot);      
      ScreenMessage = StringConcatenate(ScreenMessage, ":  Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL);
      if (TrendTradeWithCT) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TrendTradeWithCT is enabled", NL);      
      else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TrendTradeWithCT is disabled", NL);      
      if (CloseTradeAtMiddleWhiteLine) ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CloseTradeAtMiddleWhiteLine = true", NL);
      if (CloseTradeAtGreen) ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CloseTradeAtGreen = true", NL);
      if (CloseTradeAtGold) ScreenMessage = StringConcatenate(ScreenMessage, Gap, "CloseTradeAtGold = true", NL);
      if (!CloseTradeAtMiddleWhiteLine && !CloseTradeAtGreen && !CloseTradeAtGold) ScreenMessage = StringConcatenate(ScreenMessage, Gap, ": No trade closure option selected", NL);
      //ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
      if (BreakEvenAtGold) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            BreakEvenAtGold = true. GoldLineBEP = ", GoldLineBEP, NL);
      else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            BreakEvenAtGold = False", NL);
   
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours", NL);
      if (Ct_start_hourm == 0 && Ct_end_hourm == 12 && Ct_start_houre == 12 && Ct_end_houre == 24) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            24H trading", NL);
      else
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            Ct_start_hourm: ", DoubleToStr(Ct_start_hourm, 2), 
                         ": Ct_end_hourm: ", DoubleToStr(Ct_end_hourm, 2));
         ScreenMessage = StringConcatenate(ScreenMessage, ":   Ct_end_houre: ", DoubleToStr(Ct_start_houre, 2), 
                         ": Ct_end_houre: ", DoubleToStr(Ct_end_houre, 2), NL);
                      
      }//else
      
      //ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BarCount = ", BarCount);
      ScreenMessage = StringConcatenate(ScreenMessage, ":  Recovery starts at ", Start_Recovery_at_trades, " filled trades");
      ScreenMessage = StringConcatenate(ScreenMessage, ":  ReEntryLinePips = ", ReEntryLinePips, NL);

      //Display pending trades
      //ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
      if (GlobalVariableCheck(CtPendingLongGvName) )
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Counter Trend Buy stop ", 
                         DoubleToStr(GlobalVariableGet(CtPendingLongGvName), Digits), 
                         ": Ask = ", DoubleToStr(Ask, Digits), NL);
      }//if (GlobalVariableCheck(CtPendingLongGvName) )
   
      if (GlobalVariableCheck(CtPendingShortGvName) )
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Counter Trend Sell stop ", 
                         DoubleToStr(GlobalVariableGet(CtPendingShortGvName), Digits),
                         ": Bid = ", DoubleToStr(Bid, Digits), NL);
      }//if (GlobalVariableCheck(CtPendingShortGvName) )
   
      
   }//if (TradeCounterTrend && CtTradeTimeOk) 
   
   if (TradeCounterTrend && !CtTradeTimeOk)
   {      
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Outside trading hours: Ct_start_hourm-end_hourm: ", Ct_start_hourm, "-",Ct_end_hourm, 
                     ": Ct-start_houre-end_houre: ", Ct_start_houre, "-",Ct_end_houre);
   }//if (TradeCounterTrend && !CtTradeTimeOk)

   
   
   //Trend trading
   if (TradeTrend)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);   
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TREND TRADING - ");            
      if (!TtAlertNotTrade) ScreenMessage = StringConcatenate(ScreenMessage,"auto-trading", NL);
      if (TtAlertNotTrade) ScreenMessage = StringConcatenate(ScreenMessage, "using Beastie to generate trade alerts, but not to send the trades", NL);
      if (TtAlertAndTrade) ScreenMessage = StringConcatenate(ScreenMessage, "using Beastie to generate both trades and trade alerts", NL);
      ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Lot size: ", TtLot);
      ScreenMessage = StringConcatenate(ScreenMessage, ":  Take profit: ", TakeProfit, PipDescription);
      ScreenMessage = StringConcatenate(ScreenMessage, ":  Visual Stop loss: ", VisualStopLoss, PipDescription,  NL);   
      if (TtTradeLong) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Long trading allowed");
      if (TtTradeShort) ScreenMessage = StringConcatenate(ScreenMessage, ": Short trading allowed", NL);
      if (MoveTpLineWithTMA)  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Moving tp with TMA", NL);
      if (!MoveTpLineWithTMA)  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not moving tp with TMA", NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TouchBufferPips: ", TouchBufferPips, NL);

      //Stop loss
      if (UseSwing)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using the swing to calculate the stop loss. PipsAddToStopLoss: ", PipsAddToStopLoss, NL);
      }//if (UseSwing)
      if (UseTma)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using Tma to calculate the stop loss. HiddenTmaStopLossMultiplier: ", HiddenTmaStopLossMultiplier, NL);
      }//if (UseTma)
   
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MinStopLoss: ", MinStopLoss, NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", TtMagicNumber);
      ScreenMessage = StringConcatenate(ScreenMessage,":   Trade comment: ", TtTradeComment, NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Long trade swap: ", MarketInfo(Symbol(), MODE_SWAPLONG));
      ScreenMessage = StringConcatenate(ScreenMessage, ":   Short trade swap: ", MarketInfo(Symbol(), MODE_SWAPSHORT), NL );
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours", NL);
      
      if (Tt_start_hourm == 0 && Tt_end_hourm == 12 && Tt_start_houre == 12 && Tt_end_houre == 24) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            24H trading", NL);
      else
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            Tt_start_hourm: ", DoubleToStr(Tt_start_hourm, 2), 
                         ": Tt_end_hourm: ", DoubleToStr(Tt_end_hourm, 2));
         ScreenMessage = StringConcatenate(ScreenMessage,":  Tt_start_houre: ", DoubleToStr(Tt_start_houre, 2), 
                         ": end_houre: ", DoubleToStr(Tt_end_houre, 2), NL);
                      
      }//else
      if (TradeTrend && !TtTradeTimeOk)
      {      
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Outside trading hours", NL);
      }//if (TradeTrend && !TtTradeTimeOk)
      else ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);

      if (TtTradeTimeOk)
      {
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "W1 Moving average: ", DoubleToStr(W1MaVal, Digits), NL);
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TMA Upper line: ", DoubleToStr(TmaUpper, Digits));
         ScreenMessage = StringConcatenate(ScreenMessage, ":  Middle line: ", DoubleToStr(TmaMiddle, Digits));
         ScreenMessage = StringConcatenate(ScreenMessage, ":  Lower line: ", DoubleToStr(TmaLower, Digits), NL);
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "5MA: ", DoubleToStr(Ma5Val, Digits), NL);
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trend is: ", trend, NL);
         if (UseConvergenceFilter && ConvergenceHappening) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using convergence filter. TMA and 249MA are converging. (", PrevTmaMiddle, " ", TmaMiddle, ")", NL);
         if (UseConvergenceFilter && !ConvergenceHappening) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using convergence filter. TMA and 249MA are not converging.(", PrevTmaMiddle, " ", TmaMiddle, ")", NL);
         if (TradingStatus != opentrade) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading status is: ", TradingStatus, NL);
         
      }//if (TtTradeTimeOk)
      if (TradingStatus == opentrade) ScreenMessage = StringConcatenate(ScreenMessage,Gap, 
                                         "Trading status is: ", TradingStatus, 
                                         ": Hidden stop loss is ", DoubleToStr(HiddenStopLoss, Digits), 
                                         ": Hidden take profit is ", DoubleToStr(HiddenTakeProfit, Digits), NL);

      ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);

   
   }//if (TradeTrend)
   
   //Open trades
      //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 = "Counter Trend";
         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 (TicketNo > 0) 
      {
         type = "Trend";
         OrderSelect(TicketNo, SELECT_BY_TICKET);
         ScreenMessage = StringConcatenate(ScreenMessage,Gap, OrderTicket(), "  ", DoubleToStr(OrderTakeProfit(), Digits), 
                         ": Magic 2", ": Type ", type, NL);
      }//if (TicketNo > 0) 
      
   }//if (OpenTrades > 0)

   
   //Open trade management
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Open trade management: ", NL);
   if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = true", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = false", 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;   

   if (multiplier > 1) PipDescription = " points"; 
   
   //Trend trading
   TakeProfit*= multiplier;
   VisualStopLoss*= multiplier;
   MinStopLoss*= multiplier;
   PipsAddToStopLoss*= multiplier;
   TouchBufferPips*= multiplier;
   MaxPipsDifferenceAllowed*= multiplier;
   
   //Counter trend trading
   RecoveryBreakEvenProfitPips*= multiplier;
   ReEntryLinePips*= multiplier;
   CtPipsBuffer*= multiplier;
   MinPipsFromLastEntry*= multiplier;
   GoldLineBEP*= multiplier;
   
   //Trade management
   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
   //Counter Trend trading
   CtPendingLongGvName = CtPendingLong + Symbol();
   CtPendingShortGvName = CtPendingShort + Symbol();
   
   //Read 'pending' trades in the event of a restart
   //Long
   CtPendingTradeType=-1;//Initialise the variable
   if (GlobalVariableCheck(CtPendingLongGvName) )
   {
      CtPendingTradePrice = GlobalVariableGet(CtPendingLongGvName);
      CtPendingTradeType = OP_BUY;
   }//if (GlobalVariableCheck(CtPendingLongGvName) )
   
   //Short
   if (GlobalVariableCheck(CtPendingShortGvName) )
   {
      CtPendingTradePrice = GlobalVariableGet(CtPendingShortGvName);
      CtPendingTradeType = OP_SELL;
   }//if (GlobalVariableCheck(CtPendingShortGvName) )

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   
   //Calculate trade closure levels
   if (AutoCalcTradeClosureLine) CalculateTradeClosureLine();
   
   
   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();
   
   
   ////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trend trading
   GvName = globalprefix + Symbol();
   //Pick up after a restart
   TradingStatus = notrade;
   if (GlobalVariableCheck(GvName))
   {
      int type = GlobalVariableGet(GvName);
      if (TtTradeLong) TradingStatus = buy;
      if (type == 1 && TtTradeShort) TradingStatus = sell;      
   }//if (GlobalVariableCheck(GvName) > -1)  

   ReadIndicatorValues();//For initial display in case user has turned of constant re-display
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   
   //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");
   

   Comment("");   
   
//----
   return(0);
}


void CalculateTradeClosureLine()
{
   //Calculates the TradeCounterTrend and Aggressive trade closure lines based on Bob's volatility groupd


   CloseTradeAtGold=true;
   CloseTradeAtGreen=false;
   CloseTradeAtMiddleWhiteLine=false;
   
   int cc;
   
   for (cc = 0; cc <= ArraySize(VeryVolatile);  cc++)
   {
      int index = StringFind(Symbol(), VeryVolatile[cc]);
      if (index > -1)
      {
         CloseTradeAtMiddleWhiteLine = true;
         CloseTradeAtGold=false;
         return;
      }//if (index > -1)
      
   }//for (cc = 0; cc <= ArraySize(VeryVolatile);  cc++)
   

   for (cc = 0; cc <= ArraySize(MediumVolatile);  cc++)
   {
      index = StringFind(Symbol(), MediumVolatile[cc]);
      if (index > -1)
      {
         CloseTradeAtGreen = true;
         CloseTradeAtGold=false;
         return;
      }//if (index > -1)
      
   }//for (cc = 0; cc <= ArraySize(MediumVolatile);  cc++)
   

}//void CalculateTradeClosureLine()


void GetSixths()
{

   TopLine = High[iHighest(NULL,0,MODE_HIGH,BarCount,1)];
   if (High[0] > TopLine) TopLine = NormalizeDouble(High[0], Digits);
   BottomLine = Low[iLowest(NULL,0,MODE_LOW,BarCount,1)];
   if (Low[0] < BottomLine) BottomLine = NormalizeDouble(Low[0], Digits);
   //double value = High[iHighest(NULL,0,MODE_HIGH,BarCount,0)] - Low[iLowest(NULL,0,MODE_LOW,BarCount,0)];      //value top of the chart - value bottom
   double value = TopLine - BottomLine;
   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);
   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("sixsixth", OBJPROP_PRICE1);
      double bl = ObjectGet("zerosixth", OBJPROP_PRICE1);
      
      if(tl != TopLine || bl != BottomLine) 
      {
         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, string comment, int magic, double stop, double take)
{  
         
   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   int expiry = 0;
   //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);
   
   while(IsTradeContextBusy()) Sleep(100);
   //Spread check
   if (!SpreadCheck() ) return(false);
      
   //Send pending trade for counter-trend trades
   if (magic == CtMagicNumber) int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, 0, expiry, col);
   
   //Send market order for trend trades
   if (magic == TtMagicNumber)
   {
         
      if (!CriminalIsECN) ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, 0, expiry, col);
         
      if (CriminalIsECN)
      {
      
         ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, 0, expiry, col);
         int err;
         if (ticket > 0)
         {
	     
	           if (take > 0 && stop > 0)
              {
                 while(IsTradeContextBusy()) Sleep(100);
                 bool result = OrderModify(ticket, OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE);
                 if (!result)
                 {
                     err=GetLastError();
                     Print(Symbol(), " SL/TP  order modify failed with error(",err,"): ",ErrorDescription(err));               
                 }//if (!result)			  
              }//if (take > 0 && stop > 0)
      
	           if (take != 0 && stop == 0)
              {
                 while(IsTradeContextBusy()) Sleep(100);
                 result = OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
                 if (!result)
                 {
                     err=GetLastError();
                     Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
                 }//if (!result)			  
              }//if (take == 0 && stop != 0)

              if (take == 0 && stop != 0)
              {
                 while(IsTradeContextBusy()) Sleep(100);
                 result = OrderModify(ticket, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
                 if (!result)
                 {
                     err=GetLastError();
                     Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
                 }//if (!result)			  
              }//if (take == 0 && stop != 0)

         }//if (ticket > 0)

         
      }//if (CriminalIsEcn)
      
   
   }//if (magic == TtMagicNumber)
   
   
   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";
      err=GetLastError();
      Alert(Symbol(), " ", stype," Beastie order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," Beastie order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   //Got this far, so trade send succeeded
   if (magic == CtMagicNumber)
   {
      OpenTrades++;
      if (OpenTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
      GlobalVariableDel(CtPendingLongGvName);
      GlobalVariableDel(CtPendingShortGvName);
      CtPendingTradePrice = 0;
      CtPendingTradeType = -1;            
   }//if (magic = CtMagicNumber)
   
   Sleep(60000);
   while(!IsConnected() ) Sleep(100);
   while(!IsTradeAllowed() ) Sleep(100);
   while (!OrderSelect(ticket, SELECT_BY_TICKET) ) Sleep(100);
   if (magic == CtMagicNumber)
   {
      TN[OpenTrades] = ticket;
      TP[OpenTrades] = OrderOpenPrice();
   }//if (magic = CtMagicNumber)
   
   if (magic == TtMagicNumber)
   {
      TicketNo = ticket;
   }//if (magic == TtMagicNumber)
   
   return(true);
   
}//bool SendSingleTrade(int type, double lotsize, double price)

bool DoesTradeExist()
{
   TicketNo = 0;
   
   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) == TtMagicNumber && OrderSymbol() == Symbol())
      {
         TicketNo = ticket;
         TradingStatus = opentrade;
         //Check hidden/visual stop loss and tp lines exist
         if (ObjectFind(stoplossline) == -1)
         {
            ObjectCreate(stoplossline,1,0,TimeCurrent(),OrderStopLoss());
            ObjectSet(stoplossline,OBJPROP_COLOR,SlLineColour);
            ObjectSet(stoplossline,OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet(stoplossline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(stoplossline) == -1)
         
         if (ObjectFind(hiddenstoplossline) == -1 && OrderStopLoss() > 0)
         {
            if (OrderType() == OP_BUY) SetHiddenStop(OP_BUY, OrderOpenPrice(), 0 );
            if (OrderType() == OP_SELL) SetHiddenStop(OP_SELL, OrderOpenPrice(), 0 );
            ObjectCreate(hiddenstoplossline,1,0,TimeCurrent(), HiddenStopLoss);
            ObjectSet(hiddenstoplossline,OBJPROP_COLOR,SlLineColour);
            ObjectSet(hiddenstoplossline,OBJPROP_STYLE,STYLE_DASH);
            ObjectSet(hiddenstoplossline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(hiddenstoplossline) == -1)
         
         if (ObjectFind(takeprofitline) == -1 && OrderTakeProfit() > 0)
         {
            ObjectCreate(takeprofitline,1,0,TimeCurrent(),OrderTakeProfit());
            ObjectSet(takeprofitline,OBJPROP_COLOR,TpLineColour);
            ObjectSet(takeprofitline,OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet(takeprofitline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(takeprofitline) == -1)
         
         if (ObjectFind(hiddentakeprofitline) == -1 && OrderTakeProfit() > 0)
         {
            if (OrderType() == OP_BUY) HiddenTakeProfit = NormalizeDouble(OrderTakeProfit() - (HiddenTakeProfitPips * Point), Digits);
            if (OrderType() == OP_SELL) HiddenTakeProfit = NormalizeDouble(OrderTakeProfit() + (HiddenTakeProfitPips * Point), Digits);
            ObjectCreate(hiddentakeprofitline,1,0,TimeCurrent(), HiddenTakeProfit);
            ObjectSet(hiddentakeprofitline,OBJPROP_COLOR,TpLineColour);
            ObjectSet(hiddentakeprofitline,OBJPROP_STYLE,STYLE_DASH);
            ObjectSet(hiddentakeprofitline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(hiddentakeprofitline) == -1)

         //Make the robot adjust the tp/sl if the user has moved the line
         double target = ObjectGet(takeprofitline, OBJPROP_PRICE1);
         if (OrderTakeProfit() != target && target > 0)
         {
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), target, OrderExpiration(), CLR_NONE);
         }//if (OrderTakeProfit() != target)
         
         target = ObjectGet(stoplossline, OBJPROP_PRICE1);
         if (OrderStopLoss() != target && target > 0)
         {
            OrderModify(OrderTicket(), OrderOpenPrice(), target, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
         }//if (OrderTakeProfit() != target)
         
         //Read the hidden stop loss
         HiddenStopLoss = ObjectGet(hiddenstoplossline, OBJPROP_PRICE1);

         //Read the hidden take profit
         HiddenTakeProfit = ObjectGet(hiddentakeprofitline, OBJPROP_PRICE1);

         return(true);
      }//if (OrderSelect(ticket, SELECT_BY_TICKET) && OrderCloseTime() == 0) 
   }//for (int cc = 0; cc <= GlobalVariablesTotal(); cc++)
   
   ObjectDelete(hiddenstoplossline);
   ObjectDelete(stoplossline);
   ObjectDelete(takeprofitline);
   
   
   return(false);

}//End bool DoesTradeExist(int type, int magic, string comment)


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()
{
   //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;
   
      
   double target = ObjectGet(reentrylinename, OBJPROP_PRICE1);
   
   
   if (OpenTrades > 0)
   {
      
         
      //Possible short trade
      if (Bid > HalfTopLine)
      {
         if (Bid < target) return(false);
      }//if (Bid > HalfTopLine)


      //Possible long trade
      if (Ask < HalfBottomLine)
      {
         if (Ask > target) return(false);
      }//if (Ask < HalfBottomLine)

   

      

   }//if (OpenTrades > 0)
   
     
   
   //Got this far, so ok to trade
   return(true);

   


}//End bool IsTradingAllowed()

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)
            {
               //For ct trades
               OpenTrades++;
               TN[OpenTrades] = OrderTicket();
               TP[OpenTrades] = OrderOpenPrice();
               TM[OpenTrades] = GlobalVariableGet(name);
               //Adjust for trend trade
               if (TM[OpenTrades] == 2)
               {
                  TicketNo = OrderTicket();
                  OpenTrades--;
               }//if (TM[OpenTrades] == 2)
               
            }//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;
      int tm = GlobalVariableGet(name);
      if (OrderSymbol() == Symbol() && OrderCloseTime() == 0 && tm == CtMagicNumber)
      {
         int magic = GlobalVariableGet(name);
         //if (OrderProfit() > 0 && ObjectFind(breakevenlinename) == -1 && !RecoveryInProgress 
         //    && !HedgingInProgress) TradeManagementModule(magic);
         if (OrderProfit() > 0 && ObjectFind(breakevenlinename) == -1 && !RecoveryInProgress && magic == 1) TradeManagementModule(magic);
         //if (OrderType() == OP_BUY) BuyOpen = true;
         //if (OrderType() == OP_SELL) SellOpen = true;
         //BasketUpl+= (OrderProfit() + OrderSwap() + OrderCommission() );
         
         //Hedging
         //if (OrderProfit() < 0 && UseHedging) HedgingModule();
         
         
         //Close a losing trade
         if (OrderProfit() < 0 && CloseLosingTradesAfterHours > 0 && !RecoveryInProgress)
         {
            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)
         {
            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 (OrderSymbol() == Symbol() && OrderCloseTime() == 0)
   }//for (int cc = 0; cc <= GlobalVariablesTotal(); cc++)

   
   
}//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)
         {
            if (ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
            //Force a redraw of the stop loss and hidden stop loss lines
            ObjectDelete(stoplossline);
            ObjectDelete(hiddenstoplossline);
            Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
            if (HideBreakEvenStop) SetHiddenStop(OP_BUY, OrderStopLoss(), BreakEvenProfit*Point);
         }//if (result)
         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)
         {
            if (ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
            //Force a redraw of the stop loss and hidden stop loss lines
            ObjectDelete(stoplossline);
            ObjectDelete(hiddenstoplossline);
            Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
            if (HideBreakEvenStop) SetHiddenStop(OP_SELL, OrderStopLoss(), BreakEvenProfit*Point);
         }//if (result)
         if (!result && ShowManagementAlerts)
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//if !result && ShowManagementAlerts)      
        //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
        // {
        //    PartCloseSuccess = PartCloseTradeFunction();
        //    if (!PartCloseSuccess) SetAGlobalTicketVariable();
        // }//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
      }//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)
               //Force a redraw of the stop loss and hidden stop loss lines
               ObjectDelete(stoplossline);
               ObjectDelete(hiddenstoplossline);
               if (HideJumpingStop) SetHiddenStop(OP_BUY, sl, PipsAwayFromVisualJS);
            }//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)
            //Force a redraw of the stop loss and hidden stop loss lines
            ObjectDelete(stoplossline);
            ObjectDelete(hiddenstoplossline);
            if (HideJumpingStop) SetHiddenStop(OP_BUY, sl, PipsAwayFromVisualJS);
         }//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)
               //Force a redraw of the stop loss and hidden stop loss lines
               ObjectDelete(stoplossline);
               ObjectDelete(hiddenstoplossline);
               if (HideJumpingStop) SetHiddenStop(OP_SELL, sl, PipsAwayFromVisualJS);
            }//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())      
      {
         int t = 0;
         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)
            //Force a redraw of the stop loss and hidden stop loss lines
            ObjectDelete(stoplossline);
            ObjectDelete(hiddenstoplossline);
            if (HideJumpingStop) SetHiddenStop(OP_SELL, sl, PipsAwayFromVisualJS);
         }//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 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);
                  //Force a redraw of the stop loss and hidden stop loss lines
                  ObjectDelete(stoplossline);
                  ObjectDelete(hiddenstoplossline);
                  if (HideTrailingStop) SetHiddenStop(OP_BUY, sl, PipsAwayFromVisualTS);
               }//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);
                     //Force a redraw of the stop loss and hidden stop loss lines
                     ObjectDelete(stoplossline);
                     ObjectDelete(hiddenstoplossline);
                     if (HideTrailingStop) SetHiddenStop(OP_BUY, sl, PipsAwayFromVisualTS);
                  }//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;
   double stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
   double NewStop;
   
   
   if (OrderType() == OP_BUY)
   {
      if (Ask >= BottomGoldLine && OrderStopLoss() == 0)
      {
         //Min stop level check
         NewStop = NormalizeDouble(OrderOpenPrice() + (GoldLineBEP * Point), Digits);
         if (Ask - NewStop < stoplevel) return;
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
      }//if (Ask >= BottomGoldLine && OrderStopLoss() == 0)      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (Bid <= TopGoldLine && OrderStopLoss() == 0)
      {
         //Min stop level check
         NewStop = NormalizeDouble(OrderOpenPrice() - (GoldLineBEP * Point), Digits);
         if (NewStop - Bid < stoplevel) return;
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NewStop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
      }//if (Bid <= TopGoldLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_SELL)
   
   if (!result)
   {
      int err=GetLastError();
      if (ShowManagementAlerts==true) Alert("Beastie setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("Beastie setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)      
         
}//void BreakEvenAtGold()

void CloseAtLine()
{
   bool result = true;
   double target;
   string reason;

   if (CloseTradeAtMiddleWhiteLine) {target = MiddleWhiteLine; reason = " middle white line: Ticket no ";}
      
   
   if (OrderType() == OP_BUY)
   {
      if (CloseTradeAtGold) {target = BottomGoldLine; reason = " bottom gold line: Ticket no ";}
      if (CloseTradeAtGreen) {target = BottomGreenLine; reason = " bottom green line: Ticket no ";}
      
      if (Ask >= target && target > 0)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
         if (result) 
         {
            Alert(OrderSymbol(), " CT Buy trade closed at the ", reason, OrderTicket() );
            Print(OrderSymbol(), " CT Buy trade closed at the ", reason, OrderTicket() );
            ReadOpenTradesIntoMemory();
         }//if (result) 
         
      }//if (Ask >= BottomGoldLine && OrderStopLoss() == 0)      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (CloseTradeAtGold) {target = TopGoldLine;  reason = " top gold line: Ticket no ";}
      if (CloseTradeAtGreen) {target = TopGreenLine; reason = " top green line: Ticket no ";}
      
      if (Bid <= target && target > 0)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
         if (result) 
         {
            Alert(OrderSymbol(), " CT Sell trade closed at the ", reason, OrderTicket() );
            Print(OrderSymbol(), " CT Sell trade closed at the ", reason, OrderTicket() );            
            ReadOpenTradesIntoMemory();
         }//if (result) 
         
      }//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 CloseAtLine()


void TradeManagementModule(int magic)
{
   // Call the working subroutines one by one. 

   
   
   //Gole line management for TradeCounterTrend and Aggressive trades
   if (BreakEvenAtGold && OrderProfit() > 0 && magic == 1) BreakEvenAtGold();
   
   if (OrderProfit() > 0 && magic == 1) CloseAtLine();


   //mptm-style management is only appropriate to trend trading
   if (magic == 2)
   {
      
      // Breakeven
      if(BreakEven) BreakEvenStopLoss();

      // JumpingStop
      if(JumpingStop) JumpingStopLoss();

      //TrailingStop
      if(TrailingStop) TrailingStopLoss();
      
      //Hidden stop loss line
      if (ObjectFind(hiddenstoplossline) == -1)
      {
         ObjectCreate(hiddenstoplossline,1,0,TimeCurrent(), HiddenStopLoss);
         ObjectSet(hiddenstoplossline,OBJPROP_COLOR,SlLineColour);
         ObjectSet(hiddenstoplossline,OBJPROP_STYLE,STYLE_DASH);
         ObjectSet(hiddenstoplossline,OBJPROP_WIDTH,1);         
      }//if (ObjectFind(hiddenstoplossline) == -1)
      else
      {
         ObjectMove(hiddenstoplossline, 0, TimeCurrent(), HiddenStopLoss);
      }//else
         
   }//if (magic == 2)
   
   

}//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
////////////////////////////////////////////////////////////////////////////////////////////////

bool LookForTrendTradeClosure()
{
   /*
   Closes a trend trade if it hits:
      - the hidden stop loss
      - a TMA cross of the 240MA in the wrong direction
   
   */
   double StopTarget = ObjectGet(hiddenstoplossline, OBJPROP_PRICE1);
   double TakeTarget = ObjectGet(hiddentakeprofitline, OBJPROP_PRICE1);
   
   bool CloseTrade;
   string reason;
   
   if (OrderType() == OP_BUY) 
   {
      //Hidden stop loss
      if (Ask <= StopTarget && StopTarget > 0) 
      {
         CloseTrade = true;
         reason = " Trend trade has hit its hidden stop loss and closed";
      }//if (Ask <= StopTarget && StopTarget > 0) 
      
      //Hidden take profit
      if (Ask >= TakeTarget && TakeTarget > 0) 
      {
         CloseTrade = true;
         reason = " Trend trade has hit its hidden take profit and closed";
      }//if (Ask >= TakeTarget && TakeTarget > 0) 
      
      //TMA wrong side of 240MA
      if (TmaMiddle < W1MaVal) 
      {
         CloseTrade = true;
         reason = " Trend trade closed because of TMA/240MA re-cross";
      }//if (TmaMiddle < W1MaVal) 
      
   }//if (OrderType() == OP_BUY) 
   
   if (OrderType() == OP_SELL)
   {
      //Hidden stop loss
      if (Bid >= StopTarget && StopTarget > 0) 
      {
         CloseTrade = true;
         reason = " Trend trade has hit its hidden stop loss and closed";
      }//if (Bid >= StopTarget && StopTarget > 0) 
      
      //Hidden take profit
      if (Bid <= TakeTarget && TakeTarget > 0) 
      {
         CloseTrade = true;
         reason = " Trend trade has hit its hidden take profit and closed";
      }//if (Ask >= TakeTarget && TakeTarget > 0) 
      
      //TMA wrong side of 240MA
      if (TmaMiddle > W1MaVal) 
      {
         CloseTrade = true;
         reason = " Trend trade closed because of TMA/240MA re-cross";
      }//if (TmaMiddle > W1MaVal) 
      
      
   }//if (OrderType() == OP_SELL && Bid <= StopTarget)
   
   if (CloseTrade)
   {
      bool result = OrderClose(TicketNo, OrderLots(), OrderClosePrice(), 5000, Blue);
      if (result) 
      {
         ReadOpenTradesIntoMemory();
         ObjectDelete(stoplossline);
         ObjectDelete(hiddenstoplossline);
         ObjectDelete(takeprofitline);
         ObjectDelete(hiddentakeprofitline);
         HiddenStopLoss = 0;
         HiddenTakeProfit = 0;
         Print(Symbol(), reason);
         Alert(Symbol(), reason);
         Comment("                           Sleeping following a trade closure");
         Sleep(60000 * 60);
         return(true);
      }//if (result) 
      
      if (!result)
      {
         int err=GetLastError();
         Print(Symbol(), " Trend trade  order close failed with error(",err,"): ",ErrorDescription(err));               
         Alert(Symbol(), " Trend trade  order close failed with error(",err,"): ",ErrorDescription(err));         
      }//if (!result)
      
      
   }//if (CloseTrade)
   
   
   return(false);

}//bool LookForTrendTradeClosure()


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 CheckCtTradingTimes()
{
   int hour = TimeHour(TimeLocal() );
   
   if (Ct_end_hourm < Ct_start_hourm)
	{
		Ct_end_hourm += 24;
	}
	

	if (Ct_end_houre < Ct_start_houre)
	{
		Ct_end_houre += 24;
	}
	
	bool ok2Trade = true;
	
	ok2Trade = (hour >= Ct_start_hourm && hour <= Ct_end_hourm) || (hour >= Ct_start_houre && hour <= Ct_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 >= Ct_start_hourm && hour <= Ct_end_hourm) || (hour >= Ct_start_houre && hour <= Ct_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(Ct_end_hourm, Ct_end_houre))
   {      
      ok2Trade = false;
   }//if (hour >= MathMax(end_hourm, end_houre))

   return(ok2Trade);

}//bool CheckCtTradingTimes()

bool CheckTtTradingTimes()
{
   int hour = TimeHour(TimeLocal() );
   
   if (Tt_end_hourm < Tt_start_hourm)
	{
		Tt_end_hourm += 24;
	}
	

	if (Tt_end_houre < Tt_start_houre)
	{
		Tt_end_houre += 24;
	}
	
	bool ok2Trade = true;
	
	ok2Trade = (hour >= Tt_start_hourm && hour <= Tt_end_hourm) || (hour >= Tt_start_houre && hour <= Tt_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 >= Tt_start_hourm && hour <= Tt_end_hourm) || (hour >= Tt_start_houre && hour <= Tt_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(Tt_end_hourm, Tt_end_houre))
   {      
      ok2Trade = false;
   }//if (hour >= MathMax(end_hourm, end_houre))

   return(ok2Trade);

}//bool CheckTtTradingTimes()

void ReplaceReEntryLine()
{

   //Find the most recent trade in the sequence and replace the missing re-entry line
   
   for (int cc = OpenTrades; cc >= 0; cc--)
   {      
      int ticket = TN[OpenTrades];
      if (OrderSelect(ticket, SELECT_BY_TICKET) )
      {
         if (OrderSymbol() == Symbol() && OrderCloseTime() == 0 && TM[OpenTrades] < 3)
         {
            if (OrderType() == OP_BUY) AddReEntryLine(NormalizeDouble(OrderOpenPrice() - (ReEntryLinePips * Point), Digits) );
            if (OrderType() == OP_SELL) AddReEntryLine(NormalizeDouble(OrderOpenPrice() + (ReEntryLinePips * Point), Digits) );
            return;
         }//if (OrderSymbol() == Symbol() && OrderCloseTime() == 0)      
         
      }//if (OrderSelect(ticket, SELECT_BY_TICKET) )
      
   }//for (cc = OpenTrades; cc >= 0; cc--)
            


}//void ReplaceReEntryLine()

////////////////////////////////////////////////////////////////////////////////////////////////
//Indicator module


void GetTMA()
{
   TmaMiddle = iMA(NULL, 0, 56, 0, MODE_LWMA, PRICE_CLOSE, 0);
   double range = iATR(NULL,0,100,10)*2.0;
   TmaUpper  = TmaMiddle + range;
   TmaLower  = TmaMiddle - range;

}//End void GetTMA()


double GetMa(int tf, int period, int mashift, int method, int ap, int shift)
{
   return(iMA(NULL, tf, period, mashift, method, ap, shift) );
}//End double GetMa(int tf, int period, int mashift, int method, int ap, int shift)


void GetConvergence()
{
   ConvergenceHappening = false;
   
   double max = MaxPipsDifferenceAllowed * Point;
   
   PrevTmaMiddle = iMA(NULL, 0, 56, 0, MODE_LWMA, PRICE_CLOSE, ConvergenceLookBackBars);
   if (trend == up)
   {
      if (PrevTmaMiddle > TmaMiddle && PrevTmaMiddle - TmaMiddle > max) ConvergenceHappening = true;
   }//if (trend == up)
   
   if (trend == down)
   {
      if (PrevTmaMiddle < TmaMiddle && TmaMiddle - PrevTmaMiddle > max) ConvergenceHappening = true;   
   }//if (trend == down)
   
   
   
   
}//void GetConvergence()

double GetLow()
{

   double v;
   
   for (int cc = 1; cc <= Bars; cc++)
   {
      v = iFractals(NULL, FractalTF, MODE_LOWER, cc);
      if (v != 0) return(v);
   }//for (int cc = 1; cc <= Bars; cc++)
   

}//double GetLow()

double GetHigh()
{

   double v;
   
   for (int cc = 1; cc <= Bars; cc++)
   {
      v = iFractals(NULL, FractalTF, MODE_UPPER, cc);
      if (v != 0) return(v);
   }//for (int cc = 1; cc <= Bars; cc++)
   

}//double GetHigh()


void ReadIndicatorValues()
{

   W1MaVal = GetMa(W1Tf, W1Period, 0, MODE_SMMA, PRICE_MEDIAN, 0);
   Ma5Val = GetMa(MA5x5Tf, MA5xPeriod, MA5xShift, MODE_SMMA, PRICE_MEDIAN, 0);
   GetTMA();
   
   
   //Adjust tp if there is an open trade and the TMA has moved
   static int OldH1Bars;
   if (MoveTpLineWithTMA && OrderSelect(TicketNo, SELECT_BY_TICKET) && OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      double target = ObjectGet(takeprofitline, OBJPROP_PRICE1);
      OldH1Bars = iBars(NULL, PERIOD_H1);
        
      if (OrderCloseTime() == 0)
      {
         if (OrderType() == OP_BUY)
         {
            if (TmaUpper != target)
            {
               ObjectMove(takeprofitline,0,TimeCurrent(),TmaUpper);
            }//if (TmaUpper != target)            
         }//if (OrderType() == OP_BUY)
         
         if (OrderType() == OP_SELL)
         {
            if (TmaLower != target)
            {
               ObjectMove(takeprofitline,0,TimeCurrent(), TmaLower);
            }//if TmaLower != target)            
         }//if (OrderType() == OP_SELL)
         
      }//if (OrderCloseTime == 0)
      
   }//if (MoveTpLineWithTMA && OrderSelect(TicketNo, SELECT_BY_TICKET) )
   
   
   //Determine trend and alter trading status on a change of trend direction
   trend = none;
   if (TmaMiddle > W1MaVal) trend = up;
   if (TmaMiddle < W1MaVal) trend = down;
   
   if (trend == up && TradingStatus == sell)
   {
      TradingStatus = notrade;
      GlobalVariableDel(GvName);
   }//if (trend == up && TradingStatus == sell)
   
   if (trend == down && TradingStatus == buy)
   {
      TradingStatus = notrade;
      GlobalVariableDel(GvName);
   }//if (trend == up && TradingStatus == sell)
   
   
   //Convergence filter
   if (UseConvergenceFilter)
   {
      GetConvergence();      
   }//if (UseConvergenceFilter)
   
   
}//void ReadIndicatorValues()

//End Indicator module
////////////////////////////////////////////////////////////////////////////////////////////////

bool SpreadCheck()
{
   //Returns the spread status as ok or not ok to both trading strategies
   
   if (MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread) return(false);
   
   return(true);


}//bool SpreadCheck()



void SetHiddenStop(int type, double price, int HiddenPips)
{
   //I have coded this so it can be used both to set the initial hidden stop when the trend trade is sent,
   //and the hidden stop for jumping and trailing stop function.
   //Passing 0 as HiddenPips tells the function that it is setting the initial hidden stop for the trade

   double pips;
   
   if (type == OP_BUY)
   {
      //Initial trend trade
      if (HiddenPips == 0)
      {
         if (UseSwing)
         {
            HiddenStopLoss = GetLow();
            pips = price - HiddenStopLoss;
            pips*= HiddenSwingStopLossMultiplier;
            pips+= PipsAddToStopLoss * Point;
            if (pips < MinStopLoss * Point) pips = MinStopLoss * Point;
         }//if (UseSwing)
      
         if (UseTma)
         {
            pips = price - TmaLower;
            pips*= HiddenTmaStopLossMultiplier;         
         }//if (UseTma)
      
         HiddenStopLoss = NormalizeDouble(price - pips, Digits);
      
      }//if (HiddenPips == 0)
      
      //Subsequent jumping/breakeven/trailing stop
      if (HiddenPips > 0)
      {
         HiddenStopLoss = NormalizeDouble(price + (HiddenPips * Point), Digits);
      }//if (HiddenPips > 0)
      
      
      
   }//if (type == OP_BUY)
   
   
   if (type == OP_SELL)
   {

      //Initial trend trade
      if (HiddenPips == 0)
      {
         if (UseSwing)
         {
            HiddenStopLoss = GetHigh();
            pips = HiddenStopLoss - price;
            pips*= HiddenSwingStopLossMultiplier;
            pips+= PipsAddToStopLoss * Point;
            if (pips < MinStopLoss * Point) pips = MinStopLoss * Point;
         }//if (UseSwing)
      
         if (UseTma)
         {
            pips = TmaUpper - price;
            pips*= HiddenTmaStopLossMultiplier;         
         }//if (UseTma)
      
         HiddenStopLoss = NormalizeDouble(price + pips, Digits);         
      }//if (HiddenPips == 0)
      
      //Subsequent jumping/breakeven/trailing stop
      if (HiddenPips > 0)
      {
         //Alert(HiddenStopLoss);
         HiddenStopLoss = NormalizeDouble(price - (HiddenPips * Point), Digits);
         //Alert(HiddenStopLoss);
      }//if (HiddenPips > 0)
      
      
   }//if (type == OP_SELL)
   
   
}//End void SetHiddenStop(int type, double price, int HiddenPips)

void LookForTradeSetup()
{

   //Sets up the appropriate global variable if the market has come within TouchBufferPips of the 
   //TMA upper/lower lines. This allows the robot to carry on where it left off after a restart
   double target;
   TradingStatus = notrade;

   if (trend == up)
   {
      if (UseConvergenceFilter)
      {
         if (ConvergenceHappening) return;
      }//if (UseConvergenceFilter)
         
      if (Low[0] <= TmaLower + (TouchBufferPips * Point) )
      {
         TradingStatus = buy;
         GlobalVariableSet(GvName, 0);
      }//if (Low[0] <= TmaLower + (TouchBufferPips * Point) )
   }//if (trend == up)

   if (trend == down)
   {
      if (UseConvergenceFilter)
      {
         if (ConvergenceHappening) return;
      }//if (UseConvergenceFilter)
      if (High[0] >= TmaUpper - (TouchBufferPips * Point) )
      {
         TradingStatus = sell;
         GlobalVariableSet(GvName, 1);
      }//if (High[0] >= TmaUpper - (TouchBufferPips * Point) )
   }//if (trend == down)

}//void LookForTradeSetup()

bool CheckTradingStatusStillValid()
{

   if (TradingStatus == buy)
   {
      if (Ma5Val > TmaMiddle)
      {
         TradingStatus = notrade;
         GlobalVariableDel(GvName);
         return(false);
      }//if (Ma5Val > TmaMiddle)
      
   }//if (TradingStatus == buy)


   if (TradingStatus == sell)
   {
      if (Ma5Val < TmaMiddle)
      {
         TradingStatus = notrade;
         GlobalVariableDel(GvName);
         return(false);
      }//if (Ma5Val < TmaMiddle)            
   }//if (TradingStatus == sell)

   if (UseConvergenceFilter)
   {
      if (ConvergenceHappening)
      {
         TradingStatus = notrade;
         GlobalVariableDel(GvName);
         return(false);
      }//if (ConvergenceHappening)      
   }//if (UseConvergenceFilter)
      

   //Got this far, so trading status is still valid
   return(true);
   
}//End bool CheckTradingStatusStillValid()

void LookForTradeTrigger()
{
   string comment = " ";
   if (IsDemo() ) comment = TtTradeComment;


   RefreshRates();
   double take, stop, price;
   int type;
   bool SendTrade;
   double MinStopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
   //Spread check
   if (!SpreadCheck() ) return;
      
   //Long 
   if (TradingStatus == buy && TtTradeLong)
   {
      if (Ask > Ma5Val && Ma5Val < TmaMiddle)
      {
         if (IsTradeContextBusy() ) Sleep(100);
         RefreshRates();
         //if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         if (VisualStopLoss > 0) stop = NormalizeDouble(Ask - (VisualStopLoss * Point), Digits);
         SetHiddenStop(OP_BUY, Ask, 0);
         take = TmaUpper;
         
         if (TakeProfit > 0)
         {
            take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         }//if (TakeProfit > 0)
         
         
         type = OP_BUY;
         price = Ask;
         SendTrade = true;
      }//if (Ask > Ma5Val and Ma5Val < TmaMiddle)
      
   }//if (TradingStatus == buy)
   

   //Short
   if (TradingStatus == sell && TtTradeShort)
   {
      if (Bid < Ma5Val && Ma5Val > TmaMiddle)
      {
         if (IsTradeContextBusy() ) Sleep(100);
         RefreshRates();
         //if (TakeProfit > 0) take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
         if (VisualStopLoss > 0) stop = NormalizeDouble(Bid + (VisualStopLoss * Point), Digits);
         SetHiddenStop(OP_SELL, Bid, 0);
         take = TmaLower;
         
         if (TakeProfit > 0)
         {
            take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
         }//if (TakeProfit > 0)
         
         type = OP_SELL;
         price = Bid;
         SendTrade = true;      
      }//if (Ask < 0)
   }//if (TradingStatus == sell)

   if (SendTrade)
   {
      if (!TtAlertNotTrade || TtAlertAndTrade) bool result = SendSingleTrade(type, TtLot, price, comment, TtMagicNumber, stop, take);
      if (TtAlertNotTrade || TtAlertAndTrade)
      {
         result = true;
         string stype = "BUY";
         if (type == OP_SELL) stype = "SELL";
         Alert("Beastie ", Symbol(), stype, " Trend Trade trigger");
         SendMail("Beastie " + Symbol() +  " " + stype  + " Trend Trade trigger", "Beastie " + Symbol() + " " + stype + " Trend Trade trigger");
         GlobalVariableDel(GvName);
         TradingStatus = alertsent;
      }//if (TtAlertNotTrade)
         
   }//if (SendTrade)
   
   //Actions when trade send succeeds
   if (SendTrade && result && !TtAlertNotTrade)
   {
      GlobalVariableDel(GvName);
      TradingStatus = opentrade;
      //Set up a gv with the magic number
      string name = DoubleToStr(TicketNo, 0);//TicketNo is set by SendSingleTrade
      GlobalVariableSet(name, TtMagicNumber);
      ObjectCreate(hiddenstoplossline,1,0,TimeCurrent(), HiddenStopLoss);
      ObjectSet(hiddenstoplossline,OBJPROP_COLOR,SlLineColour);
      ObjectSet(hiddenstoplossline,OBJPROP_STYLE,STYLE_DASH);
      ObjectSet(hiddenstoplossline,OBJPROP_WIDTH,1);
   }//if (result)
   
   //Actions when trade send fails
   if (SendTrade && !result)
   {
   
   }//if (!result)
   
   

}//void LookForTradeTrigger()

void SendTtWithCT(int type)
{

   /*
   This function is called when a CT trade triggers, if TrendTradeWithCT & TradeTrend are enabled, and sends a 
   trade trend with the appropriate virtual magic number and trade comment.
   Trading conditions are:
      - TradeTrend enabled
      - TrendTradeWithCT enabled
      - Convergence is not happening (if this filter is being used)
      - trend is same direction as the CT trade
      - market is < TmaLower for Buy, above TmaUpper for Sell
      - spread is ok
      - there is not already a trend trade open
      
   
   There is not yet a 5MA filter. This is easily added.
   */
      
   double stop, take, price;
   int NoOfTries;
   string comment = " ";

   bool result = false;
   
   //General filters
   if (DoesTradeExist() ) return;
   if (!TradeTrend) return;
   if (!TrendTradeWithCT) return;
   if (UseConvergenceFilter && ConvergenceHappening) return;
   //Spread check
   if (!SpreadCheck() ) return;
         
   
   while (!result)
   {
      if (IsTradeContextBusy() ) Sleep(100);
            
      if (type == OP_BUY)
      {
         //Specific filters
         if (trend != up) return;
         if (Ask > TmaLower) return;
         if (TmaMiddle > W1MaVal) return;
         
         if (IsDemo() ) comment = TtTradeComment;
         if (VisualStopLoss > 0) stop = NormalizeDouble(Ask - (VisualStopLoss * Point), Digits);
         RefreshRates();
         SetHiddenStop(OP_BUY, Ask, 0);
         take = TmaUpper;
   
         if (TakeProfit > 0)
         {
            take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
         }//if (TakeProfit > 0) 
         
         RefreshRates();
         price = Ask;
      }//if (type == OP_BUY)


      if (type == OP_SELL)
      {
         if (trend != down) return;
         if (Bid < TmaUpper) return;
         
         if (IsDemo() ) comment = TtTradeComment;
         if (VisualStopLoss > 0) stop = NormalizeDouble(Bid + (VisualStopLoss * Point), Digits);
         RefreshRates();
         SetHiddenStop(OP_SELL, Bid, 0);
         take = TmaLower;
   
         if (TakeProfit > 0)
         {
            take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
         }//if (TakeProfit > 0)
         RefreshRates();
         price = Bid;

      }//if (type == OP_SELL)

      //Got this far, so send the trade
      result = SendSingleTrade(type, TtLot, price, comment, TtMagicNumber, stop, take);
      
      if (result)
      {
         TradingStatus = opentrade;
         //Set up a gv with the magic number
         string name = DoubleToStr(TicketNo, 0);//TicketNo is set by SendSingleTrade
         GlobalVariableSet(name, TtMagicNumber);
         TicketNo = OrderTicket();
         Sleep(1000);
         ObjectCreate(hiddenstoplossline,1,0,TimeCurrent(), HiddenStopLoss);
         ObjectSet(hiddenstoplossline,OBJPROP_COLOR,SlLineColour);
         ObjectSet(hiddenstoplossline,OBJPROP_STYLE,STYLE_DASH);
         ObjectSet(hiddenstoplossline,OBJPROP_WIDTH,1);
         
         if (ObjectFind(takeprofitline) == -1 && OrderTakeProfit() > 0)
         {
            ObjectCreate(takeprofitline,1,0,TimeCurrent(),OrderTakeProfit());
            ObjectSet(takeprofitline,OBJPROP_COLOR,TpLineColour);
            ObjectSet(takeprofitline,OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet(takeprofitline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(takeprofitline) == -1)
         
         if (ObjectFind(hiddentakeprofitline) == -1 && OrderTakeProfit() > 0)
         {
            if (OrderType() == OP_BUY) HiddenTakeProfit = NormalizeDouble(OrderTakeProfit() - (HiddenTakeProfitPips * Point), Digits);
            if (OrderType() == OP_SELL) HiddenTakeProfit = NormalizeDouble(OrderTakeProfit() + (HiddenTakeProfitPips * Point), Digits);
            ObjectCreate(hiddentakeprofitline,1,0,TimeCurrent(), HiddenTakeProfit);
            ObjectSet(hiddentakeprofitline,OBJPROP_COLOR,TpLineColour);
            ObjectSet(hiddentakeprofitline,OBJPROP_STYLE,STYLE_DASH);
            ObjectSet(hiddentakeprofitline,OBJPROP_WIDTH,1);
         }//if (ObjectFind(hiddentakeprofitline) == -1)
         
         ReadOpenTradesIntoMemory();

      }//iif (result)
      
      //Try a maximum of 50 times
      NoOfTries++;
      if (NoOfTries == 50) return;

   }//while (!result)
   

}//void SendTtWithCT(int type)


/////////////////////////////////////////////////////////////////////////////////////////////////////
//TRADING STYLES MODULE

void StartCT()
{
   //This function acts as start() for counter-trend trading
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Look for closure of an open trade
   if (OpenTrades > 0 && OpenTrades < Start_Recovery_at_trades)
   {
      OrderSelect(TN[OpenTrades], SELECT_BY_TICKET);
      if (OrderCloseTime() == 0) TradeManagementModule(1);   
   }//if (OpenTrades > 0 && OpenTrades < Start_Recovery_at_trades)
   
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Check for a necessary repositioning of the Sixths at a new hi-lo
   if (High[0] > TopLine || Low[0] < BottomLine)
   {
      GetSixths();
      GlobalVariableDel(CtPendingLongGvName);
      GlobalVariableDel(CtPendingShortGvName);
      CtPendingTradePrice = 0;
      CtPendingTradeType = -1;            
   }//if (Ask > TopLine || Bid < BottomLine)
   
   //Check for accidental deletion of the sixths lines - also helps visual backtesting
   if (ObjectFind("halfbottomsixth") == -1) GetSixths();
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Monitor existing trades.
   //This function will handle calls to management functions and close profitable/Recovery trades as appropriate
   if (OpenTrades > 0) MonitorOpenTrades();
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Reset variables when there are no open trades
   if (OpenTrades == 0)
   {
      RecoveryInProgress = false;
      ObjectDelete(reentrylinename);
   }//if (OpenTrades == 0)
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Recovery
   if (UseRecovery)
   {
      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)
      {
         RecoveryModule();      
      }//if (ObjectFind(breakevenlinename) == -1 && OpenTrades > 2)
      
      //Delete orphan breakeven line
      if (!RecoveryInProgress && ObjectFind(breakevenlinename) > -1)
      {
         ObjectDelete(breakevenlinename);
      }//if (!RecoveryInProgress && ObjectFind(breakevenlinename) > -1)
      
      //Replace accidentally deleted/ missing re[entry line
      if (RecoveryInProgress && ObjectFind(reentrylinename) == -1)
      {
         ReplaceReEntryLine();      
      }//if (RecoveryInProgress && ObjectFind(reentrylinename) == -1)
      
      
   }//if (UseRecovery)

   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   //Replace deleted reentry line
   if (ObjectFind(reentrylinename) == -1 && OpenTrades > 0)
   {
      double price;
      if (OrderType() == OP_BUY)
      {
         price = NormalizeDouble(OrderOpenPrice() - (MinPipsFromLastEntry * Point), Digits);
      }//if (OrderType() == OP_BUY)
      
      if (OrderType() == OP_SELL)
      {
         price = NormalizeDouble(OrderOpenPrice() + (MinPipsFromLastEntry * Point), Digits);
      }//if (OrderType() == OP_SELL)
      
      AddReEntryLine(price);
      
   }//if (ObjectFind(reentrylinename) == -1 && OpenTrades > 0)
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////

   //Trading hours
   CtTradeTimeOk = CheckCtTradingTimes();
   if (!CtTradeTimeOk)
   {      
      return;
   }//if (hour < start_hourm)
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   bool result;
   double SendLots = CtLot;
   
   string comment = " ";
   if (IsDemo() ) comment = CtTradeComment;

   
   if (CtPendingTradePrice > 0)
   {
      
      ////////////////////////////////////////////////////////////////////////////////////
      //Using Recovery, so adapt lot sizes
      if (RecoveryInProgress)
      {
         if (OpenTrades == Start_Recovery_at_trades) 
         {
            if (Use1.1.2.4Recovery) SendLots = CtLot * 2;         
            if (Use1.1.3.3Recovery) SendLots = CtLot * 3;
         }//if (OpenTrades == Start_Recovery_at_trades) 
      
         if (OpenTrades == Start_Recovery_at_trades + 1) 
         {
            if (Use1.1.2.4Recovery) SendLots = CtLot * 4;
            if (Use1.1.3.3Recovery) SendLots = CtLot * 3;
         }//if (OpenTrades == Start_Recovery_at_trades + 1) 
      
         if (OpenTrades == 4) return;//No further trading is possible
      
         
      }//if (RecoveryInProgress)
    
      ////////////////////////////////////////////////////////////////////////////////////
      //Can a 'pending' be filled
      //Spread check
      if (!SpreadCheck() ) return;
      
      //Long
      if (Ask >= CtPendingTradePrice && CtPendingTradePrice > 0 && CtPendingTradeType == OP_BUY && Ask < BottomGoldLine)
      {
         while (IsTradeContextBusy() ) Sleep(100);
         //Look for a trend trade opportunity
         if (TradeTrend) SendTtWithCT(OP_BUY);
         
         if (!CtAlertNotTrade || CtAlertAndTrade) result = SendSingleTrade(OP_BUY, SendLots, NormalizeDouble(Ask, Digits), comment, CtMagicNumber, 0, 0);
         if (CtAlertNotTrade || CtAlertAndTrade)
         {
            result = true;
            Alert("Beastie ", Symbol(), " counter-trend Buy trade trigger");
            SendMail("Beastie " + Symbol() + " counter-trend Buy trade", " counter-trend Buy trade trigger");
         }//if (CtAlertNotTrade)
         
         if (result && comment == CtTradeComment)
         {
            CtPendingTradePrice = 0;
            CtPendingTradeType = -1;
            GlobalVariableDel(CtPendingLongGvName);
            string name = DoubleToStr(TN[OpenTrades], 0);//OpenTrades is incremented by SendSingleTrade
            GlobalVariableSet(name, CtMagicNumber);
            //Force a re-calculation of breakeven
            if (RecoveryInProgress)
            {
               ObjectDelete(breakevenlinename);
               RecoveryModule();
               AddReEntryLine(NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits) );
            }//if (RecoveryInProgress)

            ObjectDelete(reentrylinename);
            if (!RecoveryInProgress) AddReEntryLine(NormalizeDouble(Ask - (MinPipsFromLastEntry * Point), Digits) );
         }//if (result && comment == CtTradeComment)
         
         
      }//if (Ask >= CtPendingTradePrice && CtPendingTradeType == OP_BUY)
      
      //Short      
      if (Bid <= CtPendingTradePrice && CtPendingTradePrice > 0  && CtPendingTradeType == OP_SELL && Bid > TopGoldLine)
      {
         while (IsTradeContextBusy() ) Sleep(100);
         //Look for a trend trade opportunity
         if (TradeTrend) SendTtWithCT(OP_SELL);         


         if (!CtAlertNotTrade || CtAlertAndTrade) result = SendSingleTrade(OP_SELL, SendLots, NormalizeDouble(Bid, Digits), comment, CtMagicNumber, 0, 0);
         if (CtAlertNotTrade || CtAlertAndTrade)
         {
            result = true;
            Alert("Beastie ", Symbol(), " counter-trend Sell trade trigger");
            SendMail("Beastie " + Symbol() + " counter-trend Sell trade", " counter-trend Buy trade trigger");
         }//if (CtAlertNotTrade)
         
         if (result && comment == CtTradeComment)
         {
            CtPendingTradePrice = 0;
            CtPendingTradeType = -1;
            GlobalVariableDel(CtPendingShortGvName);
            name = DoubleToStr(TN[OpenTrades], 0);//OpenTrades is incremented by SendSingleTrade
            GlobalVariableSet(name, CtMagicNumber);
            //Force a re-calculation of breakeven
            if (RecoveryInProgress)
            {
               ObjectDelete(breakevenlinename);
               RecoveryModule();
               AddReEntryLine(NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits) );
            }//if (RecoveryInProgress)
            
            ObjectDelete(reentrylinename);
            if (!RecoveryInProgress) AddReEntryLine(NormalizeDouble(Bid + (MinPipsFromLastEntry * Point), Digits) );
         }//if (result && comment == CtTradeComment)
         
         
      }//if (Bid <= CtPendingTradePrice && CtPendingTradeType == OP_SELL)
      
   
   }//if (CtPendingTradePrice > 0)
   
   //Should a pending be deleted?
   if (CtPendingTradePrice > 0 && Bid < TopGoldLine && Ask > BottomGoldLine)
   {
      CtPendingTradePrice = 0;
      CtPendingTradeType = -1;
      GlobalVariableDel(CtPendingShortGvName);
      GlobalVariableDel(CtPendingLongGvName);
            
   }//if (CtPendingTradePrice > 0 && (Bid < TopGoldLine && Ask > BotomGoldLine)
   

   //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();
   if (!TradingAllowed) return;

   double RecoveryLineVal = ObjectGet(reentrylinename, OBJPROP_PRICE1);
   
   //Buy
   if ( (Low[0] <= BottomLine + (CtPipsBuffer * Point) || Low[1] <= TopLine + (CtPipsBuffer * Point) )  && Ask < HalfBottomLine  && HalfBottomLine != CtPendingTradePrice && CtTradeLong)
   {
      if (RecoveryInProgress && Ask > RecoveryLineVal) return;
      GlobalVariableSet(CtPendingLongGvName, HalfBottomLine);
      CtPendingTradeType = OP_BUY;
      CtPendingTradePrice = HalfBottomLine;
   }//if (Ask < BottomLine + (CtPipsBuffer * Point) && HalfBottomLine != CtPendingTradePrice)
   
   //Sell
   if ( (High[0] >= TopLine - (CtPipsBuffer * Point) || High[1] >= TopLine - (CtPipsBuffer * Point) ) && Bid > HalfTopLine && HalfTopLine != CtPendingTradePrice && CtTradeShort)
   {
      if (RecoveryInProgress && Bid < RecoveryLineVal) return;
      GlobalVariableSet(CtPendingShortGvName, HalfTopLine);
      CtPendingTradeType = OP_SELL;
      CtPendingTradePrice = HalfTopLine;
   }//if (Bid > TopLine - (CtPipsBuffer * Point) && HalfTopLine != CtPendingTradePrice)
   

}//End void StartCT()


void StartTrendTrading()
{

   static bool TradeExists;
   
   if (OrdersTotal() == 0)
   {
      TicketNo = 0;
      ObjectDelete(stoplossline);
      ObjectDelete(takeprofitline);
      ObjectDelete(hiddenstoplossline);
      ObjectDelete(hiddentakeprofitline);
         
   }//if (OrdersTotal() == 0)

   ReadIndicatorValues();

   
   //Hourly check that there is still a global in place, to try to ensure that the bot is displaying the correct
   //trading status
   static int OldH1Bars;
   if (OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      OldH1Bars = iBars(NULL, PERIOD_H1);
      if (!GlobalVariableCheck(GvName) ) TradingStatus = notrade;
   }//if (OldH1Bars != iBars(NULL, PERIOD_H1)
   
     
   ///////////////////////////////////////////////////////////////////////////////////////////////
   //Find open trades
   if (OrdersTotal() > 0)
   {
      TradeExists = DoesTradeExist();
      if (TradeExists)
      {
         OrderSelect(TicketNo, SELECT_BY_TICKET);
         TradeManagementModule(TtMagicNumber);
         bool TradeClosed = LookForTrendTradeClosure();
         if (TradeClosed) 
         {
            TradeExists = false;
            return;
         }//if (TradeClosed) 
         
      }//if (TradeExists)
      
      if (!TradeExists)
      {
         ObjectDelete(stoplossline);
         ObjectDelete(hiddenstoplossline);
         ObjectDelete(hiddentakeprofitline);
         ObjectDelete(takeprofitline);
         //TradingStatus = notrade;
      }//if (TradeExists)
   }//if (OrdersTotal() > 0)

 
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trading times
   TtTradeTimeOk = CheckTtTradingTimes();
   if (!TtTradeTimeOk)
   {
      return;
   }//if (!TtTradeTimeOk)
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ///////////////////////////////////////////////////////////////////////////////////////////////         
   //Trading
   if (TicketNo == 0)
   {
      //Look for a trading setup
      if (TradingStatus != buy && TradingStatus != sell) LookForTradeSetup();

      //Trade trigger.
      //First, check that the setup is still valid
      if (TradingStatus == buy || TradingStatus == sell) 
      {
         bool StillValid = CheckTradingStatusStillValid();
         if (!StillValid) return;
         LookForTradeTrigger();
      }//if (TradingStatus == buy || TradingStatus == sell) 
      
      
   }//if (TicketNo == 0)
   ///////////////////////////////////////////////////////////////////////////////////////////////      

}//End void StartTrendTrading()

//END OF TRADING STYLES MODULE
/////////////////////////////////////////////////////////////////////////////////////////////////////


//+------------------------------------------------------------------+
//| 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() )
   
      
   /////////////////////////////////////////////////////////////////////////////////////////////////////

      
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trading
   //These functions are a kind of start() for each of the trading styles
   if (TradeCounterTrend || TicketNo > 0) StartCT();//Conditional has to adapt to trades converted from CT to TT
   if (TradeTrend) StartTrendTrading();
   /////////////////////////////////////////////////////////////////////////////////////////////////////
   
   //On-screen feedback
   DisplayUserFeedback();
   
}//End int start()
//+------------------------------------------------------------------+