//+------------------------------------------------------------------+
//|                                                    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"
#property copyright "Copyright © 2009, Steve Hopwood"
#property link      "http://www.hopwood3.freeserve.co.uk"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"
#define  GvPrefix "macman "
#define  breakevenlinename "Break even line"
#define  reentrylinename "Re entry line"
#define  takeprofitlinename "Take profit line"
#define  up "Market is trending up"
#define  down "Market is trending down"
#define  ranging "Market is ranging"

//From iExposure
#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

/*
ChicagoRob's pairs: eurusd - usdjpy - gbpusd - audusd - eurjpy - usdcad - nzdusd - audjpy

int init()
int deinit()
int start()
void DisplayUserFeedback()

void GetSixths()
int GetBarCount()
void CalculateTrades()
bool IsTradingAllowed()
bool PairsNotAtMaximumCheck()
bool DoesTradeExist(double price)
double CalculateStop(double price, int type)
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
double CalculateStop(double price, int type)
void LookForTradeClosure()
void CloseAllTrades()
void CountPendingTrades()
void DrawTakeProfitLine(int type) not used
Void DoIdiotChecks()
void TradeDirectionBySwap()

----Matt's Order Reliable library code
bool O_R_CheckForHistory(int ticket) Cheers Matt, You are a star.
void O_R_Sleep(double mean_time, double max_time)

----Volatility----
double CalculateVolatility(int period, int LookBack)

----Re-entry line----
void AddReEntryLine(double price)
void CalculateReEntryLinePips()
void ReplaceReEntryLine()

----Recovery----
void RecoveryModule()
void CountOpenTrades()
void CheckRecoveryTakeProfit()
int Analyze()
int SymbolsIndex(string SymbolName)


----Trade management module----
void TradeManagementModule()
void BreakEvenStopLoss()
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void JumpingStopLoss() 
void HiddenTakeProfit()
void HiddenStopLoss()
void TrailingStopLoss()
void CandlestickTrailingStopLoss()
bool CleanUp()
void CloseAtGold()
void CloseAtGreen()
void CloseAtMiddle()


----Hedging----
void HedgingModule()
bool IsTradeAlreadyHedged(int ticket)
double GetRsi(int tf, int period, int shift)

*/
extern string  gen="----General inputs----";
extern double  Lot=0.02;
extern bool    StopTrading=false;
extern bool    TradeLong=true;
extern bool    TradeShort=true;
extern int     MaxTradesAllowedPerPair=5;
extern int     MaxOpenPairsAllowed=5;
extern int     PipsBufferFromTradeLine=5;
extern int     MinPipsFromLastEntry=50;
extern double  MaxSpread=120;
extern int     TouchesRequired=0;
extern string  amc="----Available Margin checks----";
extern string  sco="Scoobs";
extern bool    UseScoobsMarginCheck=false;
extern string  fk="ForexKiwi";
extern bool    UseForexKiwi=true;
extern int     FkMinimumMarginPercent=1100;
extern string  bc="----BarCount----";
extern int     BarCount=0;
extern bool    UseMax=false;
extern bool    UseChaserL=true;
extern string  CCIHelp = "Hourly Period for CCI MA";
extern int     CCIPeriod=120;
extern string  gls="----Gold line stuff----";
extern bool    BreakEvenAtGold=false;
extern int     GoldLineBEP=10;
extern string  acc="----Trade closure----";
extern bool    CloseTradeAtGold=true;
extern bool    CloseTradeAtGreen=false;
extern bool    CloseTradeAtMiddleWhiteLine=false;
extern string  acc1="AutoCalc over rides the above";
extern bool    AutoCalcTradeClosureLine=true;
extern string  vs="----Volatility inputs----";
extern int     LookBackDays=20;
extern int     LowVolatility=100;
extern int     MediumVolatility=150;
extern int     HighVolatility=200;
extern int     PsychoticallyDeranged=250;

/*
extern string  tpi="----Take profit----";
extern bool    UseTplTp=false;
extern color   TakeProfitLineColour=Blue;
*/
extern string  pts="----Swap filter----";
extern bool    CadPairsPositiveOnly=true;
extern bool    AudPairsPositiveOnly=true;
extern bool    NzdPairsPositiveOnly=true;
extern string  rec="----Recovery----";
extern bool    UseRecovery=true;
extern int     Start_Recovery_at_trades=2;  //DC
extern bool    Use1.1.3.3Recovery=false;
extern bool    Use1.1.2.4Recovery=true;
extern color   ReEntryLineColour=Turquoise;
extern color   BreakEvenLineColour=Blue;
extern int     ReEntryLinePips=0;
extern int     RecoveryBreakEvenProfitPips=20;
extern string  sli="----Stop loss----";
extern bool    UseStopLoss=false;
extern int     StopLoss=0;
extern string  tmm="----Trade management module----";
extern string  BE="Break even settings";
extern bool    BreakEven=false;
extern int     BreakEvenPips=40;
extern int     BreakEvenProfit=30;
extern bool    HideBreakEvenStop=false;
extern int     PipsAwayFromVisualBE=5;
extern string  JSL="Jumping stop loss settings";
extern bool    JumpingStop=false;
extern int     JumpingStopPips=30;
extern bool    AddBEP=false;
extern bool    JumpAfterBreakevenOnly=true;
extern bool    HideJumpingStop=false;
extern int     PipsAwayFromVisualJS=10;
extern string  TSL="Trailing stop loss settings";
extern bool    TrailingStop=false;
extern int     TrailingStopPips=50;
extern bool    HideTrailingStop=false;
extern int     PipsAwayFromVisualTS=10;
extern bool    TrailAfterBreakevenOnly=false;
extern bool    StopTrailAtPipsProfit=false;
extern int     StopTrailPips=0;
extern string  tcs="Candle trailing stop settings";
extern bool    UseCandleTS=false;
extern string  hsl1="Hidden stop loss settings";
extern bool    HideStopLossEnabled=false;
extern int     HiddenStopLossPips=20;
extern string  htp="Hidden take profit settings";
extern bool    HideTakeProfitEnabled=false;
extern int     HiddenTakeProfitPips=20;
extern string  hed="----Hedging----";
extern bool    UseHedging=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  tt="----Trading hours----";
extern string  Trade_Hours= "Set Morning & Evening Hours";
extern string  Trade_Hoursi= "Use 24 hour, local time clock";
extern string  Trade_Hours_M= "Morning Hours 0-12";
extern  int    start_hourm = 0;
extern  int    end_hourm = 12;
extern string  Trade_Hours_E= "Evening Hours 12-24";
extern  int    start_houre = 12;
extern  int    end_houre = 24;
extern string  mis="----Odds and ends----";
extern bool    ShowManagementAlerts=true;
extern int     DisplayGapSize=30;

//CCI for dynamic BarCount
int            CurBars;

//6ths variable.
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;
double         HalfTopLine, HalfBottomLine;

bool           ForcePendingTradeDeletion;
bool           ForceAllTradeDeletion;
//int            OldBars, OpenTrades, PrevOpenTrades, PendingTrades, Old5Bars;
int            OldBars, OpenTrades, PendingTrades, Old5Bars;
//string         GvName, Gap, ScreenMessage;
string         Gap, ScreenMessage;
double         TpLinePrice1;
int            TpLinePipsFromWhite=10;
int            TicketNo = -1;//Save the ticket no of a pending trade
bool           BuyOpen, SellOpen;
int            Touches=0;//Count the number of touches of the outer lines to trigger a trade
double         OldBid;
   
double         TradeNumber;  //DC to use with recovery module
double         BasketUpl;//Fopr keeping track of the upl of whether a group of trades should be in Recovery
double         MostRecentTradePrice;//For making sure new trades are sent a min pips distance from an existing open trade
double         RsiVal;
string         trend;
bool           HedgingInProgress;
int            PipsMove=1;//Pips the market must move before a pending is modified
int            OldCountOpenTrades;//From Jose Luis to help with keeping track of Recovery
int            NoOfPairsTrading;//Keeps a tally of the number of pairs with open trades

//Volatility
double         Volatility;
int            D1Bars;

//Matt's O-R stuff
int 	         O_R_Setting_max_retries 	= 10;
double 	      O_R_Setting_sleep_time 		= 4.0; /* seconds */
double 	      O_R_Setting_sleep_max 		= 15.0; /* seconds */


//Recovery
bool           RecoveryInProgress, TpMoved;
string ExtSymbols[SYMBOLS_MAX];
int    ExtSymbolsTotal=0;
double ExtSymbolsSummaries[SYMBOLS_MAX][7];
int    ExtLines=-1;
string ExtCols[8]={"Symbol",
                   "Deals",
                   "Buy lots",
                   "Buy price",
                   "Sell lots",
                   "Sell price",
                   "Net lots",
                   "Profit"};
int    ExtShifts[8]={ 10, 80, 130, 180, 260, 310, 390, 460 };
int    ExtVertShift=14;
double buy_price=0.0;
double sell_price=0.0;

void DisplayUserFeedback()
{
   
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   //Code for time to bar-end display from Candle Time by Nick Bilak
   double i;
   int m,s,k;
   m=Time[0]+Period()*60-CurTime();
   i=m/60.0;
   s=m%60;
   m=(m-m%60)/60;
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, m + " minutes " + s + " seconds left to bar end", NL);

/*
extern bool    Primary_trades=true;
extern int     PipsBufferFromTradeLine=5;
extern bool    Secondary_trades=true;
extern bool    Tertiary_trades=true;
extern double  Lot=0.02;
extern double  Secondary_trade_Lot_size=0.02;
extern double  Tertiary_trade_Lot_size=0.01;
*/
      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot: ", Lot);
   ScreenMessage = StringConcatenate(ScreenMessage, ":  PipsBufferFromTradeLine: ", PipsBufferFromTradeLine, NL);   
   if (TouchesRequired > 1) ScreenMessage = StringConcatenate(ScreenMessage, ":  Touches required to trigger trades: ", TouchesRequired, ": Touches so far ", Touches, NL);
   
   if (TradeLong == true) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading long ", NL);
   if (TradeShort == true) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading short ", NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
   //if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = true", NL);
   //else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = false", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL);
   if (MarketInfo(Symbol(), MODE_SPREAD) <= MaxSpread) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MaxSpread: ", MaxSpread, "  Spread is ", MarketInfo(Symbol(), MODE_SPREAD), NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "MaxSpread: ", MaxSpread, "  &&&&& SPREAD IS ", MarketInfo(Symbol(), MODE_SPREAD), " &&&&&", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Criminal's swap for long trades: ", MarketInfo(Symbol(), MODE_SWAPLONG), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Criminal's swap for short trades: ", MarketInfo(Symbol(), MODE_SWAPSHORT), NL);
   
   static int Old5minbars;
   if (Old5minbars != iBars(Symbol(), PERIOD_M5) )
   {
      PairsNotAtMaximumCheck();
      Old5minbars = iBars(Symbol(), PERIOD_M5);
   }//if (Old5minbars != iBars(Symbol(), PERIOD_M5)
   if (NoOfPairsTrading >= MaxOpenPairsAllowed) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading only allowed for Recovery and Hedging, if enabled. Pairs trading: ", NoOfPairsTrading, NL, NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Pairs trading: ", NoOfPairsTrading, NL, NL);
      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours", NL);
   if (start_hourm == 0 && end_hourm == 12 && start_houre && end_houre == 24) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            24H trading", NL);
   else
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_hourm: ", DoubleToStr(start_hourm, 2), 
                      ": end_hourm: ", DoubleToStr(end_hourm, 2), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            end_houre: ", DoubleToStr(start_hourm, 2), 
                      ": end_houre: ", DoubleToStr(end_hourm, 2), NL);
                      
   }//else

   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BarCount = ", BarCount, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Recovery starts at ", Start_Recovery_at_trades, " filled trades", NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Volatility = ", Volatility, ":  ReEntryLinePips = ", ReEntryLinePips, NL);
   if (StopTrading) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading suspended", NL);


   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade management: ", NL);
   if (BreakEvenAtGold) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            BreakEvenAtGold = true. GoldLineBEP = ", GoldLineBEP, NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BreakEvenAtGold = False", 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 (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 (BreakEven)


   if (UseCandleTS)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using candlestick trailing stop", NL);
   }//if (UseCandleTS)
   
   
   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)

//extern bool    UseHedging=false;
//extern int     HedgeAtLossPips=500;
//extern double  HedgeLotsMiltiplier=2;

   Comment(ScreenMessage);


}//void DisplayUserFeedback()




//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----

   
   /*
   //ReEntryLinePips is calculated using Atr during GetSixths(). I keep this code in case we change our minds
   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;
   */
   
   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(Symbol() == "XAUUSD" || StringSubstr(Symbol(),0,1)=="#") multiplier = 10;//For ChaserL
   
   TpLinePipsFromWhite*= multiplier;
   StopLoss*= multiplier;
   RecoveryBreakEvenProfitPips*= multiplier;
   ReEntryLinePips*= multiplier;
   PipsBufferFromTradeLine*= multiplier;
   MinPipsFromLastEntry*= multiplier;
   BreakEvenPips*= multiplier;
   BreakEvenProfit*= multiplier;
   PipsAwayFromVisualBE*= multiplier;
   JumpingStopPips*= multiplier;
   PipsAwayFromVisualJS*= multiplier;
   TrailingStopPips*= multiplier;
   PipsAwayFromVisualTS*= multiplier;
   StopTrailPips*= multiplier;
   HiddenStopLossPips*= multiplier;
   HiddenTakeProfitPips*= multiplier;
   HedgeAtLossPips*= multiplier;
   PipsMove*= multiplier;
   
   
   //Volatility
   LowVolatility*= multiplier;
   MediumVolatility*= multiplier;
   HighVolatility*= multiplier;
   PsychoticallyDeranged*= multiplier;

   if (BarCount == 0)
   {
      GetBarCount();
   }//if (BarCount == 0)
     

   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   

   
   
   Comment("..................Waiting for the first tick");
   
   OldBars = Bars;
   Old5Bars = iBars(NULL, PERIOD_M5);//For 'mopping up' operations

   //GvName = GvPrefix + Symbol();
   //PrevOpenTrades = GlobalVariableGet(GvName);
   if (ObjectFind(takeprofitlinename) == 0 && ObjectGet(takeprofitlinename, OBJPROP_COLOR) == Gray) TpLinePrice1 = ObjectGet(takeprofitlinename, OBJPROP_PRICE1);
   GetSixths();

   //Calculate trade closure levels
   if (AutoCalcTradeClosureLine) CalculateTradeClosureLine();

   //Idiot checks
   DoIdiotChecks();
   
   //Swap filter
   TradeDirectionBySwap();
   
   OldBid = Bid;
   //start();
   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");

   //Delete the Sixths lines
   ObjectDelete("zerosixth");
   ObjectDelete("onesixth");
   ObjectDelete("twosixth");
   ObjectDelete("threesixth");
   ObjectDelete("foursixth");
   ObjectDelete("fivesixth");
   ObjectDelete("sixsixth");
   ObjectDelete("halfbottomsixth");
   ObjectDelete("halftopsixth");
   
   
//----
   return(0);
}

void DoIdiotChecks()
{
   if (Start_Recovery_at_trades < 2) Start_Recovery_at_trades = 2;
   if (Lot < MarketInfo(Symbol(), MODE_MINLOT)) Lot = MarketInfo(Symbol(), MODE_MINLOT);

}//End Void DoIdiotChecks()


int GetBarCount()
{
   
   double 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;


   //My thanks to Max for this code
   if (UseMax)
   {      
      //Set up the BarCount. H1 TF first. Default barcount set at 170
      //From scoobs
      //BarCount = NormalizeDouble((iATR(NULL,1440 ,200,0)/MarketInfo(Symbol(),MODE_POINT))/10,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; }
   
      double dBarCount = BarCount;
      //dBarCount*= multiplier;
      //BarCount = dBarCount;   
      
      //Andy's formula
      BarCount = MathRound(dBarCount/Period()*60);

   
   }//if (UseMax)
      
   


   //My thanks to ChaserL for providing this code. This uses CCI to calculate a dynamic BarCount
   if (UseChaserL)
   {
      int IndTimeframe=PERIOD_H1;
      int PeriodCount=0;
      int PeriodTotal=0;
      int TempAbovePer=0;
      int TempBelowPer=0;
      int CCIPos=0;
      int TempCCIPos=0;

      CurBars=iBars(NULL,IndTimeframe);
      int IndBars=MathMin(720,CurBars);
      for(int i=1;i<=IndBars;i++)
        {
          TempCCIPos=CCIPos;
         if(iCCI(NULL,IndTimeframe,CCIPeriod,PRICE_WEIGHTED,i)>100 && CCIPos != 1)
           {
            TempAbovePer=i;
            CCIPos=1;
           }
         if(iCCI(NULL,IndTimeframe,CCIPeriod,PRICE_WEIGHTED,i)<-100 && CCIPos != -1)
           {
            TempBelowPer=i;
            CCIPos=-1;
           }
         if(TempAbovePer>0 && TempBelowPer>0 && CCIPos != TempCCIPos && CCIPos!=0)
           {
            PeriodCount++;
            PeriodTotal+=MathAbs(TempAbovePer-TempBelowPer);
           }
        }
   
      if(PeriodCount==0) BarCount=170*multiplier;
      else BarCount=PeriodTotal/PeriodCount*multiplier;
      //Print("Tot Bars: ", PeriodTotal, " / Total Reversals: ", PeriodCount, " * TimeframeMultiplier: ", multiplier, " = ", BarCount);
   }//if (UseChaserL)
   


}//End of int GetBarCount()



void CalculateTradeClosureLine()
{
   //Calculates the CounterTrend trade closure lines based on the pair's calculated volatility 

   CloseTradeAtGold=false;
   CloseTradeAtGreen=false;
   CloseTradeAtMiddleWhiteLine=false;
   
   //Alert(Symbol(), " Vol ", Volatility, " Low vol ", LowVolatility);

   //Low
   if (Volatility < LowVolatility) CloseTradeAtGold = true;
   //Medium/high
   if (Volatility >= LowVolatility && Volatility < PsychoticallyDeranged) CloseTradeAtGreen = true;
   //Deranged
   if (Volatility >= PsychoticallyDeranged) CloseTradeAtMiddleWhiteLine = true;
   



}//void CalculateTradeClosureLine()


void GetSixths()
{

   double ctgl = TopGoldLine;
   double cbgl = BottomGoldLine;
   
   /*
   Old code that read the lines on the screen
   TopGoldLine = NormalizeDouble(ObjectGet("fivesixth", OBJPROP_PRICE1), Digits);
   TopGreenLine = NormalizeDouble(ObjectGet("foursixth", OBJPROP_PRICE1), Digits);
   MiddleWhiteLine = NormalizeDouble(ObjectGet("threesixth", OBJPROP_PRICE1), Digits);
   BottomGreenLine = NormalizeDouble(ObjectGet("twosixth", OBJPROP_PRICE1), Digits);
   BottomGoldLine = NormalizeDouble(ObjectGet("onesixth", OBJPROP_PRICE1), 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 sixth = value/6;
   double valueS = (value*(MathPow(10,Digits)));
   double sixthS = (sixth*(MathPow(10,Digits)));
   
   TopLine = High[iHighest(NULL,0,MODE_HIGH,BarCount,0)];
   HalfTopLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,0)]+sixth+sixth+sixth+sixth+sixth+(sixth / 2), Digits);
   BottomLine = Low[iLowest(NULL,0,MODE_LOW,BarCount,0)];
   HalfBottomLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,0)]+(sixth / 2),Digits);
   BottomGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,0)]+sixth, Digits);
   BottomGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,0)]+sixth+sixth, Digits);
   MiddleWhiteLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,0)]+sixth+sixth+sixth, Digits);
   TopGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,0)]+sixth+sixth+sixth+sixth, Digits);
   TopGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,0)]+sixth+sixth+sixth+sixth+sixth, Digits);
   */
   
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //New code copied from Beastie
   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)));
   
   HalfTopLine = NormalizeDouble(BottomLine+sixth+sixth+sixth+sixth+sixth+(sixth / 2), Digits);
   HalfBottomLine = NormalizeDouble(BottomLine+(sixth / 2),Digits);
   BottomGoldLine = NormalizeDouble(BottomLine+sixth, Digits);
   BottomGreenLine = NormalizeDouble(BottomLine+sixth+sixth, Digits);
   MiddleWhiteLine = NormalizeDouble(BottomLine+sixth+sixth+sixth, Digits);
   TopGreenLine = NormalizeDouble(BottomLine+sixth+sixth+sixth+sixth, Digits);
   TopGoldLine = NormalizeDouble(BottomLine+sixth+sixth+sixth+sixth+sixth, Digits);
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   //if(ctgl != TopGoldLine || cbgl != BottomGoldLine) ForcePendingTradeDeletion = true;
   //Modify the open price of an existing pending
   if((ctgl != TopGoldLine || cbgl != BottomGoldLine) && TicketNo > -1)
   {
      if (OrderSelect(TicketNo, SELECT_BY_TICKET) )
      {
         bool result = true;
         if (OrderType() == OP_BUYSTOP)
         {
            if (OrderOpenPrice() - HalfBottomLine >= PipsMove * Point) result = OrderModify(OrderTicket(), HalfBottomLine, OrderStopLoss(), OrderTakeProfit(), 0, Green);         
            if (result) AddReEntryLine(NormalizeDouble(HalfBottomLine - (ReEntryLinePips * Point), Digits) );
         }//if (OrderType() == OP_BUYSTOP)
         
         if (OrderType() == OP_SELLSTOP)
         {
            if (HalfTopLine - OrderOpenPrice() >= PipsMove * Point) result = OrderModify(OrderTicket(), HalfTopLine, OrderStopLoss(), OrderTakeProfit(), 0, Red);         
            if (result) AddReEntryLine(NormalizeDouble(HalfTopLine + (ReEntryLinePips * Point), Digits) ); 
         }//if (OrderType() == OP_SELLSTOP
         
         
         if (!result)
         {
            int err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Order open price mod ", 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 (OrderSelect(TicketNo, SELECT_BY_TICKET) )
      
   }//if((ctgl != TopGoldLine || cbgl != BottomGoldLine) && TicketNo > -1)
   


   //Calculate ReEntryLinePips
   //if (ReEntryLinePips == 0) CalculateReEntryLinePips();

   
   if (!IsTesting() && !IsVisualMode() ) 
   {
      //Draw the lines
      double tl = ObjectGet("fivesixth", OBJPROP_PRICE1);
      double bl = ObjectGet("onesixth", OBJPROP_PRICE1);
      
      if(tl != TopGoldLine || bl != BottomGoldLine) 
      {
         if (ObjectFind("zerosixth") == -1)
         {
            ObjectCreate("zerosixth",1,0,TimeCurrent(),BottomLine);
            ObjectSet("zerosixth",OBJPROP_COLOR,Magenta);
            ObjectSet("zerosixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("zerosixth",OBJPROP_WIDTH,2);     
         }//if (ObjectFind("zerosixth") == -1)
         else ObjectMove("zerosixth",0,TimeCurrent(),BottomLine);
      
         if (ObjectFind("halfbottomsixth") == -1)
         {
            ObjectCreate("halfbottomsixth",1,0,TimeCurrent(),HalfBottomLine);
            ObjectSet("halfbottomsixth",OBJPROP_COLOR,Magenta);
            ObjectSet("halfbottomsixth",OBJPROP_STYLE,STYLE_DASH);
            ObjectSet("halfbottomsixth",OBJPROP_WIDTH,1);     
         }//if (ObjectFind("halfbottomsixth") == -1)
         else ObjectMove("halfbottomsixth",0,TimeCurrent(),HalfBottomLine);
      
         if (ObjectFind("onesixth") == -1)
         {
            ObjectCreate("onesixth",1,0,TimeCurrent(),BottomGoldLine);
            ObjectSet("onesixth",OBJPROP_COLOR,Gold);
            ObjectSet("onesixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("onesixth",OBJPROP_WIDTH,2);     
         }//if (ObjectFind("onesixth") == -1)
         else ObjectMove("onesixth",0,TimeCurrent(),BottomGoldLine);
      
         if (ObjectFind("twosixth") == -1)
         {
            ObjectCreate("twosixth",1,0,TimeCurrent(),BottomGreenLine);
            ObjectSet("twosixth",OBJPROP_COLOR,Green);
            ObjectSet("twosixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("twosixth",OBJPROP_WIDTH,2);    
         }//if (ObjectFind(
         else ObjectMove("twosixth",0,TimeCurrent(),BottomGreenLine);

         if (ObjectFind("threesixth") == -1)
         {
            ObjectCreate("threesixth",1,0,TimeCurrent(),MiddleWhiteLine);
            ObjectSet("threesixth",OBJPROP_COLOR,White);
            ObjectSet("threesixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("threesixth",OBJPROP_WIDTH,2);
         }//if (ObjectFind(
         else ObjectMove("threesixth",0,TimeCurrent(),MiddleWhiteLine);
      
         if (ObjectFind("foursixth") == -1)
         {
            ObjectCreate("foursixth",1,0,TimeCurrent(),TopGreenLine);
            ObjectSet("foursixth",OBJPROP_COLOR,Green);
            ObjectSet("foursixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("foursixth",OBJPROP_WIDTH,2);
         }//if (ObjectFind(
         else ObjectMove("foursixth",0,TimeCurrent(),TopGreenLine);
      
         if (ObjectFind("fivesixth") == -1)
         {
            ObjectCreate("fivesixth",1,0,TimeCurrent(),TopGoldLine);
            ObjectSet("fivesixth",OBJPROP_COLOR,Gold);
            ObjectSet("fivesixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("fivesixth",OBJPROP_WIDTH,2);
         }//if (ObjectFind(
         else ObjectMove("fivesixth",0,TimeCurrent(),TopGoldLine);
            
         if (ObjectFind("halftopsixth") == -1)
         {
            ObjectCreate("halftopsixth",1,0,TimeCurrent(),HalfTopLine);
            ObjectSet("halftopsixth",OBJPROP_COLOR,Magenta);
            ObjectSet("halftopsixth",OBJPROP_STYLE,STYLE_DASH);
            ObjectSet("halftopsixth",OBJPROP_WIDTH,1);     
         }//if (ObjectFind("halftopsixth") == -1)
         else ObjectMove("halftopsixth",0,TimeCurrent(),HalfTopLine);
      
         if (ObjectFind("sixsixth") == -1)
         {
            ObjectCreate("sixsixth",1,0,TimeCurrent(),TopLine);
            ObjectSet("sixsixth",OBJPROP_COLOR,Magenta);
            ObjectSet("sixsixth",OBJPROP_STYLE,STYLE_SOLID);
            ObjectSet("sixsixth",OBJPROP_WIDTH,2);     
         }//if (ObjectFind("sixsixth") == -1)
         else ObjectMove("sixsixth",0,TimeCurrent(),TopLine);


      }//if(ctgl != TopGoldLine || cbgl != BottomGoldLine) 
      
   }//if (!IsTesting() && !IsVisualMode() ) 
          
}//void GetSixths()

////////////////////////////////////////////////////////////////////////////////////////////////
//TRADE MANAGEMENT MODULE
bool CleanUp()
{

   bool success = true, result = true;
   int cc;

   
   //Delete duplicate pending trades
   if (PendingTrades > 1)
   {
      bool PrimaryFound=false;
      for (cc = OrdersTotal() - 1; cc >= 0; cc--)
      {
         if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
         if (OrderSymbol() == Symbol()  && (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP))
         {
            if (!PrimaryFound)
            {
               PrimaryFound = true;
            }
            else 
            {
               if (PrimaryFound) 
               {
                  result = OrderDelete(OrderTicket());
                  Sleep(1000);
                  if (result) 
                  {
                     PendingTrades--;
                     if (PendingTrades == 1) return(success);
                  }//if (result)
                  else return(false);
               }//if (PrimaryFound) 
            }//else 
         }//if (OrderSymbol() == Symbol()  && (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP))
      }//for (cc = OrdersTotal() - 1; cc >= 0; cc--)
   }//if (PendingTrades > 1)
   else return(success);

}//End bool CleanUp()


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());      
         }//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());      
         }//if (result)
         else
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Ask >= sl)  
   }//if (type = OP_SELL)
   
   return(result);

}//End bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )


void BreakEvenStopLoss() // Move stop loss to breakeven
{

   //Check hidden BE for trade closure
   if (HideBreakEvenStop)
   {
      bool TradeClosed = CheckForHiddenStopLossHit(OrderType(), PipsAwayFromVisualBE, OrderStopLoss() );
      if (TradeClosed) return;//Trade has closed, so nothing else to do
   }//if (HideBreakEvenStop)


   bool result;

   if (OrderType()==OP_BUY)
   {
      if (Ask >= OrderOpenPrice() + (Point*BreakEvenPips) && 
          OrderStopLoss()<OrderOpenPrice())
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
         if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
         Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
         if (!result)
         {
            int err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//if !result && ShowManagementAlerts)      
         //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
         //{
         //   bool PartCloseSuccess = PartCloseTradeFunction();
         //   if (!PartCloseSuccess) SetAGlobalTicketVariable();
         //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
      }//if (Ask >= OrderOpenPrice() 
   } //if (OrderType()==OP_BUY)              			         
    
   if (OrderType()==OP_SELL)
   {
     if (Bid <= OrderOpenPrice() - (Point*BreakEvenPips) &&
        (OrderStopLoss()>OrderOpenPrice() || OrderStopLoss()==0)) 
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-(BreakEvenProfit*Point), Digits),OrderTakeProfit(),0,CLR_NONE);
         if (result && ShowManagementAlerts==true) Alert("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
         Print("Breakeven set on ", OrderSymbol(), " ticket no ", OrderTicket());
         if (!result && ShowManagementAlerts)
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//if !result && ShowManagementAlerts)      
        //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
        // {
        //    PartCloseSuccess = PartCloseTradeFunction();
        //    if (!PartCloseSuccess) SetAGlobalTicketVariable();
        // }//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
      }//if (Bid <= OrderOpenPrice() 
   }//if (OrderType()==OP_SELL)
      

} // End BreakevenStopLoss sub

void JumpingStopLoss() 
{
   // Jump sl by pips and at intervals chosen by user .
   // Also carry out partial closure if the user requires this

   // Abort the routine if JumpAfterBreakevenOnly is set to true and be sl is not yet set
   if (JumpAfterBreakevenOnly && OrderType()==OP_BUY)
   {
      if(OrderStopLoss()<OrderOpenPrice()) return(0);
   }
  
   if (JumpAfterBreakevenOnly && OrderType()==OP_SELL)
   {
      if(OrderStopLoss()>OrderOpenPrice() || OrderStopLoss() == 0) return(0);
   }
  
   double sl=OrderStopLoss(); //Stop loss

   if (OrderType()==OP_BUY)
   {
      //Check hidden js for trade closure
      if (HideJumpingStop)
      {
         bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualJS, OrderStopLoss() );
         if (TradeClosed) return;//Trade has closed, so nothing else to do
      }//if (HideJumpingStop)
      
      // First check if sl needs setting to breakeven
      if (sl==0 || sl<OrderOpenPrice())
      {
         if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
         {
            sl=OrderOpenPrice();
            if (AddBEP==true) sl=sl+(BreakEvenProfit*Point); // If user wants to add a profit to the break even
            while(IsTradeContextBusy()) Sleep(100);
            bool result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
            if (result)
            {
               if (ShowManagementAlerts==true) Alert("Jumping stop set at breakeven ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
               Print("Jumping stop set at breakeven: ", OrderSymbol(), ": SL ", sl, ": Ask ", Bid);
               //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
               //{
                  //bool PartCloseSuccess = PartCloseTradeFunction();
                  //if (!PartCloseSuccess) SetAGlobalTicketVariable();
               //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
            }//if (result)
            if (!result)
            {
               int err=GetLastError();
               if (ShowManagementAlerts) Alert(OrderSymbol(), "Ticket ", OrderTicket(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
               Print(OrderSymbol(), " buy trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
            }//if (!result)
             
            return(0);
         }//if (Ask >= OrderOpenPrice() + (JumpingStopPips*Point))
      } //close if (sl==0 || sl<OrderOpenPrice()

  
      // Increment sl by sl + JumpingStopPips.
      // This will happen when market price >= (sl + JumpingStopPips)
      if (Bid>= sl + ((JumpingStopPips*2)*Point) && sl>= OrderOpenPrice())      
      {
         sl=sl+(JumpingStopPips*Point);
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
            Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
            //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
            //{
               //PartCloseSuccess = PartCloseTradeFunction();
               //if (!PartCloseSuccess) SetAGlobalTicketVariable();
            //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
         }//if (result)
         if (!result)
         {
            err=GetLastError();
            if (ShowManagementAlerts) Alert(OrderSymbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
            Print(OrderSymbol(), " buy trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
         }//if (!result)
             
      }// if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())      
   }//if (OrderType()==OP_BUY)
   
   if (OrderType()==OP_SELL)
   {
      //Check hidden js for trade closure
      if (HideJumpingStop)
      {
         TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualJS, OrderStopLoss() );
         if (TradeClosed) return;//Trade has closed, so nothing else to do
      }//if (HideJumpingStop)
            
      // First check if sl needs setting to breakeven
      if (sl==0 || sl>OrderOpenPrice())
      {
         if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
         {
            sl = OrderOpenPrice();
            if (AddBEP==true) sl=sl-(BreakEvenProfit*Point); // If user wants to add a profit to the break even
            while(IsTradeContextBusy()) Sleep(100);
            result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
            if (result)
            {
               //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
               //{
                 // PartCloseSuccess = PartCloseTradeFunction();
                  //if (!PartCloseSuccess) SetAGlobalTicketVariable();
               //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
            }//if (result)
            if (!result)
            {
               err=GetLastError();
               if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
               Print(OrderSymbol(), " sell trade. Jumping stop function failed to set SL at breakeven, with error(",err,"): ",ErrorDescription(err));
            }//if (!result)
             
            return(0);
         }//if (Ask <= OrderOpenPrice() - (JumpingStopPips*Point))
      } // if (sl==0 || sl>OrderOpenPrice()
   
      // Decrement sl by sl - JumpingStopPips.
      // This will happen when market price <= (sl - JumpingStopPips)
      if (Bid<= sl - ((JumpingStopPips*2)*Point) && sl<= OrderOpenPrice())      
      {
         sl=sl-(JumpingStopPips*Point);
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Jumping stop set at ",sl, " ", OrderSymbol(), " ticket no ", OrderTicket());
            Print("Jumping stop set: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
            //if (PartCloseEnabled && OrderLots() > Preserve_Lots)// Only try to do this if the jump stop worked
            //{
              // PartCloseSuccess = PartCloseTradeFunction();
               //if (!PartCloseSuccess) SetAGlobalTicketVariable();
            //}//if (PartCloseEnabled && OrderLots() > Preserve_Lots)
         }//if (result)          
         if (!result)
         {
            err=GetLastError();
            if (ShowManagementAlerts) Alert(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
            Print(OrderSymbol(), " sell trade. Jumping stop function failed with error(",err,"): ",ErrorDescription(err));
         }//if (!result)

      }// close if (Bid>= sl + (JumpingStopPips*Point) && sl>= OrderOpenPrice())         
   }//if (OrderType()==OP_SELL)

} //End of JumpingStopLoss sub

void HiddenStopLoss()
{
   //Called from ManageTrade if HideStopLossEnabled = true


   //Should the order close because the stop has been passed?
   //Buy trade
   if (OrderType() == OP_BUY)
   {
      double sl = NormalizeDouble(OrderOpenPrice() - (HiddenStopLossPips * Point), Digits);
      if (Bid <= sl)
      {
         while(IsTradeContextBusy()) Sleep(100);
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Bid <= sl)      
   }//if (OrderType() == OP_BUY)
   
   //Sell trade
   if (OrderType() == OP_SELL)
   {
      sl = NormalizeDouble(OrderOpenPrice() + (HiddenStopLossPips * Point), Digits);
      if (Ask >= sl)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Stop loss hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Ask >= sl)   
   }//if (OrderType() == OP_SELL)
   

}//End void HiddenStopLoss()

void HiddenTakeProfit()
{
   //Called from ManageTrade if HideStopLossEnabled = true


   //Should the order close because the stop has been passed?
   //Buy trade
   if (OrderType() == OP_BUY)
   {
      double tp = NormalizeDouble(OrderOpenPrice() + (HiddenTakeProfitPips * Point), Digits);
      if (Bid >= tp)
      {
         while(IsTradeContextBusy()) Sleep(100);
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            int err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Ask >= tp)      
   }//if (OrderType() == OP_BUY)
   
   //Sell trade
   if (OrderType() == OP_SELL)
   {
      tp = NormalizeDouble(OrderOpenPrice() - (HiddenTakeProfitPips * Point), Digits);
      if (Ask <= tp)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, CLR_NONE);
         if (result)
         {
            if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket());      
         }//if (result)
         else
         {
            err=GetLastError();
            if (ShowManagementAlerts==true) Alert("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
            Print("Take profit hit. Close of ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
         }//else
      }//if (Bid <= tp)   
   }//if (OrderType() == OP_SELL)
   

}//End void HiddenTakeProfit()

void TrailingStopLoss()
{
      if (TrailAfterBreakevenOnly && OrderType()==OP_BUY)
      {
         if(OrderStopLoss()<OrderOpenPrice()) return(0);
      }
     
      if (TrailAfterBreakevenOnly && OrderType()==OP_SELL)
      {
         if(OrderStopLoss()>OrderOpenPrice()) return(0);
      }
     
   
   
   bool result;
   double sl=OrderStopLoss(); //Stop loss
   double BuyStop=0, SellStop=0;
   
   if (OrderType()==OP_BUY) 
      {
         if (HideTrailingStop)
         {
            bool TradeClosed = CheckForHiddenStopLossHit(OP_BUY, PipsAwayFromVisualTS, OrderStopLoss() );
            if (TradeClosed) return;//Trade has closed, so nothing else to do
         }//if (HideJumpingStop)
		   
		   if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
		   {
		       if (OrderStopLoss() == 0) sl = OrderOpenPrice();
		       if (Bid > sl +  (TrailingStopPips*Point))
		       {
		          sl= Bid - (TrailingStopPips*Point);
		          // Exit routine if user has chosen StopTrailAtPipsProfit and
		          // sl is past the profit Point already
		          if (StopTrailAtPipsProfit && sl>= OrderOpenPrice() + (StopTrailPips*Point)) return;
		          while(IsTradeContextBusy()) Sleep(100);
		          result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
               if (result)
               {
                  Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Ask ", Ask);
               }//if (result) 
               else
               {
                  int err=GetLastError();
                  Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
               }//else
   
		       }//if (Bid > sl +  (TrailingStopPips*Point))
		   }//if (Bid >= OrderOpenPrice() + (TrailingStopPips*Point))
      }//if (OrderType()==OP_BUY) 

      if (OrderType()==OP_SELL) 
      {
		   if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
		   {
             if (HideTrailingStop)
             {
                TradeClosed = CheckForHiddenStopLossHit(OP_SELL, PipsAwayFromVisualTS, OrderStopLoss() );
                if (TradeClosed) return;//Trade has closed, so nothing else to do
             }//if (HideJumpingStop)
		   
		       if (OrderStopLoss() == 0) sl = OrderOpenPrice();
		       if (Ask < sl -  (TrailingStopPips*Point))
		       {
	               sl= Ask + (TrailingStopPips*Point);
  	               // Exit routine if user has chosen StopTrailAtPipsProfit and
		            // sl is past the profit Point already
		            if (StopTrailAtPipsProfit && sl<= OrderOpenPrice() - (StopTrailPips*Point)) return;
		            while(IsTradeContextBusy()) Sleep(100);
		            result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
                  if (result)
                  {
                     Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Bid ", Bid);
                  }//if (result)
                  else
                  {
                     err=GetLastError();
                     Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
                  }//else
    
		       }//if (Ask < sl -  (TrailingStopPips*Point))
		   }//if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
      }//if (OrderType()==OP_SELL) 

      
} // End of TrailingStopLoss sub


void BreakEvenAtGold()
{
   bool result = true;
   
   double stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
   while(IsTradeContextBusy()) Sleep(100);
         
   RefreshRates();
   
   if (OrderType() == OP_BUY)
   {
      if (Ask >= BottomGoldLine && OrderStopLoss() == 0 && Ask - (OrderOpenPrice() + (GoldLineBEP * Point)) >= stoplevel)
      {
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() + (GoldLineBEP * Point), Digits), 
         OrderTakeProfit(), OrderExpiration(), CLR_NONE);
      }//if (Ask >= BottomGoldLine && OrderStopLoss() == 0)      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (Bid <= TopGoldLine && OrderStopLoss() == 0 && OrderOpenPrice() - (GoldLineBEP * Point) - Bid >= stoplevel)
      {
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() - (GoldLineBEP * Point), Digits), 
         OrderTakeProfit(), OrderExpiration(), CLR_NONE);
      }//if (Bid <= TopGoldLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_SELL)
   
   if (!result)
   {
      int err=GetLastError();
      if (ShowManagementAlerts==true) Alert("TOB setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("AEB setting of breakeven SL ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)      
         
}//void BreakEvenAtGold()

void CloseAtGold()
{
   bool result = true;
   
   if (OrderType() == OP_BUY)
   {
      if (Ask >= BottomGoldLine && OrderStopLoss() == 0)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);         
      }//if (Ask >= BottomGoldLine && OrderStopLoss() == 0)      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (Bid <= TopGoldLine && OrderStopLoss() == 0)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);         
      }//if (Bid <= TopGoldLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_SELL)
   
   if (!result)
   {
      int err=GetLastError();
      Alert("TOB order close at Gold ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("TOB order close at Gold ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)      
         
}//void CloseAtGold()


void CloseAtGreen()
{
   bool result = true;

   if (OrderType() == OP_BUY)
   {
      if (Ask >= BottomGreenLine )
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
      }//if (Ask >= BottomGreenLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_BUY)

   if (OrderType() == OP_SELL)
   {
      if (Bid <= TopGreenLine)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
      }//if (Bid <= TopGreenLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_SELL)

   if (!result)
   {
      int err=GetLastError();
      Alert("TOB order close at Green ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("TOB order close at Green ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)

}//void CloseAtGreen()

void CloseAtMiddle()
{
   bool result = true;

   if (OrderType() == OP_BUY)
   {
      if (Ask >= MiddleWhiteLine)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
      }//if (Ask >= MiddleWhiteLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_BUY)

   if (OrderType() == OP_SELL)
   {
      if (Bid <= MiddleWhiteLine)
      {
         while(IsTradeContextBusy()) Sleep(100);
         result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 10000, CLR_NONE);
      }//if (Bid <= MiddleWhiteLine && OrderStopLoss() == 0)
   }//if (OrderType() == OP_SELL)

   if (!result)
   {
      int err=GetLastError();
      Alert("TOB order close at Middle White ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("TOB order close at Middle White ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)

}//void CloseAtMiddle()

void CandlestickTrailingStopLoss()
{
   //Uses the hi/lo of the previous candle to set a trailing stop for profitable trades
   
   double stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
   bool result = true;
   while (IsTradeContextBusy() ) Sleep(100);
   RefreshRates();
   
   if (OrderType() == OP_BUY)
   {
      double low = Low[1];
      if (OrderStopLoss() < low && Ask - low >= stoplevel && low >= OrderOpenPrice())
      {
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(low, Digits), OrderTakeProfit(), OrderExpiration(), CLR_NONE);         
      }//if (OrderStopLoss() < low && Ask - low >= stoplevel)
      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      double high = High[1];
      if ((OrderStopLoss() > high || OrderStopLoss() == 0) && high - Bid >= stoplevel && high <= OrderOpenPrice())
      {
         result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(high, Digits), OrderTakeProfit(), OrderExpiration(), CLR_NONE);         
      }//if (OrderStopLoss() > high && high - Bid >= stoplevel)
      
   }//if (OrderType() == OP_SELL)
   
   //Error trapping
   if (!result)
   {
      int err=GetLastError();
      if (ShowManagementAlerts==true) Alert("Order Candlestick stop loss mod ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
      Print("Order Candlestick stop loss mod ", OrderSymbol(), " ticket no ", OrderTicket()," failed with error (",err,"): ",ErrorDescription(err));
   }//if !result && ShowManagementAlerts)  
   

}//void CandlestickTrailingStopLoss()


void TradeManagementModule()
{

   // Call the working subroutines one by one. 

   double profit = OrderProfit() + OrderSwap() + OrderCommission();
   
   if (CloseTradeAtGold && profit > 0) CloseAtGold();
   if (OrderCloseTime() > 0) return;
   
   if (BreakEvenAtGold && profit > 0) BreakEvenAtGold();
   
   if (CloseTradeAtGreen && profit > 0) CloseAtGreen();

   if (CloseTradeAtMiddleWhiteLine && profit > 0) CloseAtMiddle();

   // Hidden stop loss
   if (HideStopLossEnabled) HiddenStopLoss();

   // Hidden take profit
   if (HideTakeProfitEnabled) HiddenTakeProfit();

   // Breakeven
   if(BreakEven) BreakEvenStopLoss();

   // JumpingStop
   if(JumpingStop) JumpingStopLoss();

   //TrailingStop
   if(TrailingStop) TrailingStopLoss();

   //Candle hi/lo trailing stop
   if (UseCandleTS && OrderProfit() > 0) CandlestickTrailingStopLoss();
   
}//void TradeManagementModule()
//END TRADE MANAGEMENT MODULE
////////////////////////////////////////////////////////////////////////////////////////////////



bool DoesTradeExist(double price)
{

   if (OrdersTotal() == 0) return(false);
   string sPrice = DoubleToStr(price, Digits);
         
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;

      string sOpen = DoubleToStr(OrderOpenPrice(), Digits);

      if (sPrice == sOpen)
      {
         return(true);
      }//if (OrderOpenPrice() == price && OrderSymbol() == Symbol() )
   
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)

   return(false);

}//End bool DoesTradeExist(double price)

bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take, int magic)
{  

   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   int expiry = 0;
   //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);
   
   while(IsTradeContextBusy()) Sleep(100);
   
   int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, magic, expiry, col);
   
   if (ticket < 0)
   {
      string stype;
      if (type == OP_BUY) stype = "OP_BUY";
      if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
      if (type == OP_SELL) stype = "OP_SELL";
      if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
      int err=GetLastError();
      //Alert(Symbol(), " ", stype,"  order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype,"  order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   //Got this far, so trade send succeeded
   //Make sure the trade has appeared in the platform's history to avoid duplicate trades
   O_R_CheckForHistory(ticket); 
   
   PendingTrades++;
      
   return(true);
   
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)

bool IsTradingAllowed()
{
   
   
   //Trades count
   if (OpenTrades + PendingTrades >= MaxTradesAllowedPerPair) return(false);
   
   //This is possibly redundant, but I include it as a check anyhow
   if (Bid <= TopGoldLine && Ask >= BottomGoldLine) 
   {
      Touches = 0;
      return(false);
   }//if (Bid <= TopGoldLine && Ask >= BottomGoldLine) 
   
   //Maximum spread
   if (MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread) return(false);
 
   //Maximum open pairs check
   if (!PairsNotAtMaximumCheck() ) return(false);
 
   //Swap filter
   TradeDirectionBySwap();

   
   /*
   This section commented out. The trade now depends on being the correct side of the re-entry line.
   //Min distance from most recently filled trade
   if (MostRecentTradePrice != 0)
   {
      double MinDistance = MinPipsFromLastEntry * Point;
      
      //Possible short trade
      if (Bid > TopGoldLine)
      {
         if (TopGoldLine - MostRecentTradePrice < MinDistance) return(false);
      }//if (Bid > TopGldLine)
      
      
      //Possible long trade
      if (Ask < BottomGoldLine)
      {
         if (MostRecentTradePrice - BottomGoldLine < MinDistance) return(false);
      }//if (Ask < BottomGoldLine)
      
   }//if (MostRecentTradePrice != 0)
   */

   return(true);


}//End bool IsTradingAllowed()

bool PairsNotAtMaximumCheck()
{
   //Returns true if the no of pairs being trades is <= MaxOpenPairsAllowed, else false
   
   NoOfPairsTrading = 0;
   
   //if (OrdersTotal() < MaxOpenPairsAllowed) return(true);
   if (OrdersTotal() == 0) return(true);
   
   NoOfPairsTrading = 1;
   
   //Put the pair symbols into an array
   string OpenPairs[];
   ArrayResize(OpenPairs, OrdersTotal() );
   OrderSelect(0, SELECT_BY_POS);
   OpenPairs[0] = OrderSymbol();
   
   for (int cc = 1; cc < OrdersTotal(); cc++)
   {
      OrderSelect(cc, SELECT_BY_POS);
      OpenPairs[cc] = OrderSymbol();
      NoOfPairsTrading++;
      //Loop back to see if this is a fresh pair
      for (int d = cc - 1; d >= 0; d--)
      {
         if (OpenPairs[cc] == OpenPairs[d] )
         {
            NoOfPairsTrading--;
            break;
         }//if (OpenPairs[cc] == OpenPairs[d] )
         
      }//for (int d = cc - 1; d >= 0; d--)      
   }//for (int cc = 0; cc < OrdersTotal(); cc++)
   
   if (NoOfPairsTrading < MaxOpenPairsAllowed) return(true);
   
   //MaxOpenPairsAllowed is reached, so see if there is already a trade open for this pair. If so, allow the
   //trade send as it might be required for recovery/hedging
   for (cc = 0; cc < OrdersTotal(); cc++)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() ) return(true);   
   }//for (cc = 0; cc < OrdersTotal(); cc++)
   
   //Got this far, so MaxOpenPairsAllowed is reached and the trade is not required for hedging or recover, 
   //and so should be cancelled
   return(false);

}//End bool PairsNotAtMaximumCheck()


/*
void DrawTakeProfitLine(int type)
{
   double price;
   
   if (type == OP_BUY) price = NormalizeDouble(MiddleWhiteLine + (TpLinePipsFromWhite * Point), Digits);
   if (type == OP_SELL) price = NormalizeDouble(MiddleWhiteLine - (TpLinePipsFromWhite * Point), Digits);
   
   ObjectCreate(takeprofitlinename,OBJ_HLINE,0,TimeCurrent(), price );
   ObjectSet(takeprofitlinename,OBJPROP_COLOR,Gray);
   ObjectSet(takeprofitlinename,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(takeprofitlinename,OBJPROP_WIDTH,2);
   
   TpLinePrice1 = price;

}//End void DrawTakeProfitLine(int type)
*/

double CalculateStop(double price, int type)
{

   double sl;
   double AtrVal = iATR(NULL, 0, 20, 0) * 3;
   
   if (type == OP_BUY)
   {
      if (StopLoss > 0) sl = NormalizeDouble(price - (StopLoss * Point), Digits);
      if (StopLoss == 0) sl = NormalizeDouble(price - AtrVal, Digits);
   }//if (type == OP_BUY)
   

   if (type == OP_SELL)
   {
      if (StopLoss > 0) sl = NormalizeDouble(price + (StopLoss * Point), Digits);
      if (StopLoss == 0) sl = NormalizeDouble(price + AtrVal, Digits);
   }//if (type == OP_SELL)
   
   return(sl);
   
}//End double CalculateStop(double price, int type)

void CalculateTrades()
{
   double target;

   bool TradingAllowed = IsTradingAllowed();
   if (!TradingAllowed) return;


  
   double SendLots = Lot;
   //Using Recovery
   if (RecoveryInProgress)
   {
      if (OpenTrades == 2) 
      {
         SendLots = Lot * 2;         
         if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      }//if (OpenTrades == 2) 
      
      if (OpenTrades == 3) 
      {
         SendLots = Lot * 4;
         if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      }//if (OpenTrades == 3) 
      
      if (OpenTrades == 4) return;//No further trading is possible
      
      
   }//if (RecoveryInProgress)
   
   double ReEntryLineVal = ObjectGet(reentrylinename, OBJPROP_PRICE1);
   
   double stop;

   //Sell
   target = NormalizeDouble(TopLine - (PipsBufferFromTradeLine * Point), Digits);
   if ((Bid >= target || Bid > HalfTopLine && High[1] >= TopLine) && TradeShort)
   {
      if (!UseHedging && BuyOpen == True) return;
      
      
      if (ReEntryLineVal > 0)
      {
         if (Bid < ReEntryLineVal) return;
         if (HalfTopLine < ReEntryLineVal) return;
      }//if (ReEntryLineVal > 0)
      
      //Market must have moved into the target area from below
      if (OldBid < target) Touches++;
      OldBid = Bid;
      if (Touches < TouchesRequired) return;
      
      
      if (!DoesTradeExist(HalfTopLine) ) 
      {
         if (UseStopLoss) stop = CalculateStop(HalfTopLine, OP_SELL);
         while(IsTradeContextBusy()) Sleep(100);
         bool result = SendSingleTrade(OP_SELLSTOP, " ", SendLots, HalfTopLine, stop, 0, 0);
         //if (result && !RecoveryInProgress && UseTplTp) DrawTakeProfitLine(OP_SELL);
      }//if (!DoesTradeExist(TopGoldLine) ) 
      
      if (result) 
      {
         Volatility = CalculateVolatility(PERIOD_D1, LookBackDays);
         CalculateReEntryLinePips();
         AddReEntryLine(NormalizeDouble(HalfTopLine + (ReEntryLinePips * Point), Digits) ); 
         Touches = 0;
      }//if (result) 
      
      //if (!result) return;     
      
   }//if (Bid >= target && Primary_trades && TradeShort)
   
   
   //Buy
   stop = 0;
   target = NormalizeDouble(BottomLine + (PipsBufferFromTradeLine * Point), Digits);
   if ((Ask <= target || Ask < HalfBottomLine && Low[1] <= BottomLine) && TradeLong && Touches >= TouchesRequired)
   {
      
      if (!UseHedging && SellOpen == True) return;
      if (ReEntryLineVal > 0)
      {
         if (Ask > ReEntryLineVal) return;
         if (HalfBottomLine > ReEntryLineVal) return;
      }//if (ReEntryLineVal > 0)
      
      //Market must have moved into the target area from above
      if (OldBid > target) Touches++;
      OldBid = Bid;
      if (Touches < TouchesRequired) return;
      
      
      if (!DoesTradeExist(HalfBottomLine) ) 
      {
         if (UseStopLoss) stop = CalculateStop(HalfBottomLine, OP_BUY);         
         while(IsTradeContextBusy()) Sleep(100);
         result = SendSingleTrade(OP_BUYSTOP, " ", SendLots, HalfBottomLine, stop, 0, 0);
         //if (result && !RecoveryInProgress && UseTplTp) DrawTakeProfitLine(OP_BUY);
      }//if (!DoesTradeExist(HalfBottomLine) ) 
      
      if (result) 
      {
         Volatility = CalculateVolatility(PERIOD_D1, LookBackDays);
         CalculateReEntryLinePips();
         AddReEntryLine(NormalizeDouble(HalfBottomLine - (ReEntryLinePips * Point), Digits) );
         Touches = 0;
      }//if (result) 
      
      //if (!result) return;     
      
   }//if (Ask <= target && Primary_trades && TradeLong)
   

}//End void CalculateTrades()

void DeletePendingTrades()
{
   ForcePendingTradeDeletion = false;
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() && (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) )
      {
         bool result = OrderDelete(OrderTicket() );
         if (result) {cc++; ObjectDelete(reentrylinename); }
         if (!result) ForcePendingTradeDeletion = true;
      }//if (OrderSymbol() == Symbol() && (OrderComment() == Primary_trade_comment || OrderComment() == Secondary_trade_comment) 
   
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)


}//void DeletePendingTrades()

void CloseAllTrades()
{
   ForceAllTradeDeletion = false;
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) 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 (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) result = OrderDelete(OrderTicket() );
         if (result) cc++;
         if (!result) ForceAllTradeDeletion = true;
      }//if (OrderSymbol() == Symbol() )
   
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)


}//End void CloseAllTrades()


void LookForTradeClosure()
{
   ForceAllTradeDeletion = false;
   //if (UseTplTp) return;//Take profit line
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() )
      {
         if (OrderType() == OP_SELL && Bid <= MiddleWhiteLine)
         {
            CloseAllTrades();
         }//if (OrderType == OP_SELL && Bid < MiddleWhiteLine)
         
         if (OrderType() == OP_BUY && Ask >= MiddleWhiteLine)
         {
            CloseAllTrades();
         }//if (OrderType == OP_SELL && Bid < MiddleWhiteLine)
         
      }//if (OrderSymbol() == Symbol() )     
   
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)


}//End void LookForTradeClosure()
   
void CountOpenTrades()
{
   OpenTrades = 0;
   BasketUpl = 0;
   MostRecentTradePrice = 0;
   
   BuyOpen = False;
   SellOpen = False;
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = 0; cc <= OrdersTotal(); cc++)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == 0)
      {
         if (OrderProfit() > 0 && ObjectFind(breakevenlinename) == -1 && !RecoveryInProgress && !HedgingInProgress && OrderTakeProfit() == 0) TradeManagementModule();
         if (OrderType() == OP_BUY || OrderType() == OP_SELL) 
         {
            if (OrderType() == OP_BUY) BuyOpen = true;
            if (OrderType() == OP_SELL) SellOpen = true;
            OpenTrades++;
            BasketUpl+= (OrderProfit() + OrderSwap() + OrderCommission() );
            MostRecentTradePrice = OrderOpenPrice();
            if (OrderProfit() < 0 && UseHedging) HedgingModule();
         }//if (OrderType() == OP_BUY || OrderType() == OP_SELL) 
         
         if (ObjectFind(breakevenlinename) > -1 && !HedgingInProgress)
         {
            double take = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
            if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
            {
               while(IsTradeContextBusy()) Sleep(100);
               OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
            }//if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
         }//if (ObjectFind(breakevenlinename) > -1)
         
         /*
         if (ObjectFind(takeprofitlinename) > -1 && ObjectGet(takeprofitlinename, OBJPROP_COLOR) == TakeProfitLineColour)
         {
            take = ObjectGet(takeprofitlinename, OBJPROP_PRICE1);
            if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
            {
               while(IsTradeContextBusy()) Sleep(100);
               OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
            }//if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
         }//if (ObjectFind(takeprofitlinename) > -1)
         */
         
      }//if (OrderSymbol() == Symbol() )
   }//for (int cc = 0; cc <= OrdersTotal(); cc++)

   if (BuyOpen && SellOpen && UseHedging) HedgingInProgress = true;

   //This bit of code courtesy of José Luis. Many thanks.
   //Check if new trade takes us into Recovery
   if (OpenTrades == 0) OldCountOpenTrades = 0;
   if (OldCountOpenTrades < OpenTrades)
   {
      if (OpenTrades >= Start_Recovery_at_trades)
      {
         RecoveryInProgress = true;
         if (ObjectFind(breakevenlinename) > -1) ObjectDelete(breakevenlinename);
         RecoveryModule();
      }//if (OpenTrades >= Start_Recovery_at_trades)
      OldCountOpenTrades = OpenTrades;
   }//if (OldCountOpenTrades < OpenTrades)

   
}//End void CountOpenTrades()


void CountPendingTrades()
{
   PendingTrades = 0;
   TicketNo = -1;
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = 0; cc <= OrdersTotal(); cc++)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() )
      {
         if (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) 
         {              
            PendingTrades++;
            TicketNo = OrderTicket();
         }//if (OrderType() == OP_BUY || OrderType() == OP_SELL) 
      }//if (OrderSymbol() == Symbol() )
   }//for (int cc = 0; cc <= OrdersTotal(); cc++)

}//End void CountPendingTrades()

void RecoveryModule()
{
   
   //Draw a breakeven line if there is not one in place already.
   //The bot will adjust the tp's during the CountOpenTrades 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)

bool CheckTradingTimes()
{
   int hour = TimeHour(TimeLocal() );
   
   if (end_hourm < start_hourm)
	{
		end_hourm += 24;
	}
	

	if (end_houre < start_houre)
	{
		end_houre += 24;
	}
	
	bool ok2Trade = true;
	
	ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);

	// adjust for past-end-of-day cases
	// eg in AUS, USDJPY trades 09-17 and 22-06
	// so, the above check failed, check if it is because of this condition
	if (!ok2Trade && hour < 12)
	{
 		hour += 24;
		ok2Trade = (hour >= start_hourm && hour <= end_hourm) || (hour >= start_houre && hour <= end_houre);		
		// so, if the trading hours are 11pm - 6am and the time is between  midnight to 11am, (say, 5am)
		// the above code will result in comparing 5+24 to see if it is between 23 (11pm) and 30(6+24), which it is...
	}


   // check for end of day by looking at *both* end-hours

   if (hour >= MathMax(end_hourm, end_houre))
   {      
      ok2Trade = false;
   }//if (hour >= MathMax(end_hourm, end_houre))

   return(ok2Trade);

}//bool CheckTradingTimes()

void 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 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 CountOpenTrades if the trade is loosing
   
   double loss, LossTarget;
   int tn = OrderTicket();
   RefreshRates();
   
   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;
         bool result = SendSingleTrade(OP_SELL, DoubleToStr(tn, 0), OrderLots() * HedgeLotsMiltiplier, Bid, 0, 0, 0);
      }//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;
         result = SendSingleTrade(OP_BUY, DoubleToStr(tn, 0), OrderLots() * HedgeLotsMiltiplier, Ask, 0, 0, 0);
      }//if (loss > LossTarget )
   }//if (OrderType() == OP_SELL)
   
   
   
}//End void HedgingModule()

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)

double CalculateVolatility(int period, int LookBack)
{
   //Calculates the volatility of a pair based on an average of their movement over LookBack periods
   
   double pips;
   for (int cc = 1; cc < LookBack; cc++)
   {
      pips+= iHigh(NULL, period, cc) - iLow(NULL, period, cc);      
   }//for (int cc = 1; cc < LookBack; cc++)
   
   pips/= LookBack;//Average pips movement per day
   //Alert(pips);

   //Convert to pips
   int multiplier;
   if (Digits == 2) multiplier = 10;
   if (Digits == 3) multiplier = 100;
   if (Digits == 4) multiplier = 1000;
   if (Digits == 5) multiplier = 10000;
   
   pips*= multiplier;
   int rpips = pips;//Convert to a simple integer - all we need
   
   return(rpips);
   
}//End double CalculateVolatility(int period, int LookBack)

void CalculateReEntryLinePips()
{

/*
extern int     ReEntryLinePips=0;
extern int     LookBackDays=20;
extern int     LowVolatility=100;
extern int     MediumVolatility=150;
extern int     HighVolatility=200;
extern int     PsychoticallyDeranged=250;

*/
   
   
   //Set up volatility level
   ReEntryLinePips = 250;
   
   //Adapt 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;   
   
   Volatility*= multiplier;

   if (Volatility < LowVolatility) ReEntryLinePips = 150;
   if (Volatility >= LowVolatility && Volatility < MediumVolatility) ReEntryLinePips = 175;
   if (Volatility >= MediumVolatility && Volatility < HighVolatility) ReEntryLinePips = 200;
   if (Volatility >= HighVolatility && Volatility < PsychoticallyDeranged) ReEntryLinePips = 225;
   

   
   ReEntryLinePips*= multiplier;

   //Calculate non-recovery re-entry pips for the re-entry line
   if (OpenTrades + PendingTrades < Start_Recovery_at_trades && MinPipsFromLastEntry > 0) ReEntryLinePips = MinPipsFromLastEntry;
   
   
}//End void CalculateReEntryLinePips()

void ReplaceReEntryLine()
{

   //Find the most recent trade in the sequence and replace the missing re-entry line
   
   for (int cc = OrdersTotal() - 1; cc >= 0; cc--)
   {      
      if (OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) )
      {
         if (OrderSymbol() == Symbol())
         {            
            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(cc, SELECT_BY_POS) )
      
   }//for (cc = OpenTrades; cc >= 0; cc--)
            


}//void ReplaceReEntryLine()

//=============================================================================
//                           O_R_CheckForHistory()
//
//  This function is to work around a very annoying and dangerous bug in MT4:
//      immediately after you send a trade, the trade may NOT show up in the
//      order history, even though it exists according to ticket number.
//      As a result, EA's which count history to check for trade entries
//      may give many multiple entries, possibly blowing your account!
//
//  This function will take a ticket number and loop until
//  it is seen in the history.
//
//  RETURN VALUE:
//     TRUE if successful, FALSE otherwise
//
//
//  FEATURES:
//     * Re-trying under some error conditions, sleeping a random
//       time defined by an exponential probability distribution.
//
//     * Displays various error messages on the log for debugging.
//
//  ORIGINAL AUTHOR AND DATE:
//     Matt Kennel, 2010
//
//=============================================================================
bool O_R_CheckForHistory(int ticket)
{
   //My thanks to Matt for this code. He also has the undying gratitude of all users of my trading robots
   
   int lastTicket = OrderTicket();

   int cnt = 0;
   int err = GetLastError(); // so we clear the global variable.
   err = 0;
   bool exit_loop = false;
   bool success=false;

   while (!exit_loop) {
      /* loop through open trades */
      int total=OrdersTotal();
      for(int c = 0; c < total; c++) {
         if(OrderSelect(c,SELECT_BY_POS,MODE_TRADES) == true) {
            if (OrderTicket() == ticket) {
               success = true;
               exit_loop = true;
            }
         }
      }
      if (cnt > 3) {
         /* look through history too, as order may have opened and closed immediately */
         total=OrdersHistoryTotal();
         for(c = 0; c < total; c++) {
            if(OrderSelect(c,SELECT_BY_POS,MODE_HISTORY) == true) {
               if (OrderTicket() == ticket) {
                  success = true;
                  exit_loop = true;
               }
            }
         }
      }

      cnt = cnt+1;
      if (cnt > O_R_Setting_max_retries) {
         //exit_loop = true;
         Alert(Symbol(), " TOB might need restarting. It thinks there should be a trade in the playform's history that is not showing up.");
         cnt = 0;
      }
      if (!(success || exit_loop)) {
         Print("Did not find #"+ticket+" in history, sleeping, then doing retry #"+cnt);
         O_R_Sleep(O_R_Setting_sleep_time, O_R_Setting_sleep_max);
      }
   }
   // Select back the prior ticket num in case caller was using it.
   if (lastTicket >= 0) {
      OrderSelect(lastTicket, SELECT_BY_TICKET, MODE_TRADES);
   }
   if (!success) {
      Print("Never found #"+ticket+" in history! crap!");
   }
   return(success);
}//End bool O_R_CheckForHistory(int ticket)

//=============================================================================
//                              O_R_Sleep()
//
//  This sleeps a random amount of time defined by an exponential
//  probability distribution. The mean time, in Seconds is given
//  in 'mean_time'.
//  This returns immediately if we are backtesting
//  and does not sleep.
//
//=============================================================================
void O_R_Sleep(double mean_time, double max_time)
{
   if (IsTesting()) {
      return;   // return immediately if backtesting.
   }

   double p = (MathRand()+1) / 32768.0;
   double t = -MathLog(p)*mean_time;
   t = MathMin(t,max_time);
   int ms = t*1000;
   if (ms < 10) {
      ms=10;
   }
   Sleep(ms);
}//End void O_R_Sleep(double mean_time, double max_time)

void TradeDirectionBySwap()
{

   //Sets TradeLong & TradeShort according to the positive/negative swap it attracts

   double LongSwap = MarketInfo(Symbol(), MODE_SWAPLONG);
   double ShortSwap = MarketInfo(Symbol(), MODE_SWAPSHORT);
   

   if (CadPairsPositiveOnly)
   {
      if (StringSubstr(Symbol(), 0, 3) == "CAD" || StringSubstr(Symbol(), 0, 3) == "cad" || StringSubstr(Symbol(), 3, 3) == "CAD" || StringSubstr(Symbol(), 3, 3) == "cad" )      
      {
         if (LongSwap > 0) TradeLong = true;
         else TradeLong = false;
         if (ShortSwap > 0) TradeShort = true;
         else TradeShort = false;         
      }//if (StringSubstr(Symbol(), 0, 3) == "CAD" || StringSubstr(Symbol(), 0, 3) == "cad" )      
   }//if (CadPairsPositiveOnly)
   
   if (AudPairsPositiveOnly)
   {
      if (StringSubstr(Symbol(), 0, 3) == "AUD" || StringSubstr(Symbol(), 0, 3) == "aud" || StringSubstr(Symbol(), 3, 3) == "AUD" || StringSubstr(Symbol(), 3, 3) == "aud" )      
      {
         if (LongSwap > 0) TradeLong = true;
         else TradeLong = false;
         if (ShortSwap > 0) TradeShort = true;
         else TradeShort = false;         
      }//if (StringSubstr(Symbol(), 0, 3) == "AUD" || StringSubstr(Symbol(), 0, 3) == "aud" || StringSubstr(Symbol(), 3, 3) == "AUD" || StringSubstr(Symbol(), 3, 3) == "aud" )      
   }//if (AudPairsPositiveOnly)
   
   
   if (NzdPairsPositiveOnly)
   {
      if (StringSubstr(Symbol(), 0, 3) == "NZD" || StringSubstr(Symbol(), 0, 3) == "nzd" || StringSubstr(Symbol(), 3, 3) == "NZD" || StringSubstr(Symbol(), 3, 3) == "nzd" )      
      {
         if (LongSwap > 0) TradeLong = true;
         else TradeLong = false;
         if (ShortSwap > 0) TradeShort = true;
         else TradeShort = false;         
      }//if (StringSubstr(Symbol(), 0, 3) == "AUD" || StringSubstr(Symbol(), 0, 3) == "aud" || StringSubstr(Symbol(), 3, 3) == "AUD" || StringSubstr(Symbol(), 3, 3) == "aud" )      
   }//if (AudPairsPositiveOnly)
   
   

}//void TradeDirectionBySwap()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{

   CountOpenTrades();
   CountPendingTrades();
   //Mop up unwanted duplicate trades and orphaned secondaries 
   if (PendingTrades > 1) 
   {
      bool result = CleanUp();
      Sleep(10000);
      if (!result)
      {
         return;
      }//if (!result)      
   }//if (PendingTrades > 1)

   /////////////////////////////////////////////////////////////////////////////////////////////////////
   //Calculate volatility for re-entry line etc at the start of each D1 candle
   if (D1Bars != iBars(NULL, PERIOD_D1) )
   {
      D1Bars = iBars(NULL, PERIOD_D1);
      //Get average price movement over LookBackPeriods
      Volatility = CalculateVolatility(PERIOD_D1, LookBackDays);

      CalculateReEntryLinePips();
      if (AutoCalcTradeClosureLine) CalculateTradeClosureLine();
   }//if (D1Bars != iBars(NULL, PERIOD_D1) )
   
   /////////////////////////////////////////////////////////////////////////////////////////////////////


   //static double OldBottomLine, OldTopLine;//Keep track of where the sixths were, in case they have moved
   static int OldH1Bars;
   
   if (UseHedging && OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      GetSixths();
      RsiVal = GetRsi(PERIOD_D1, 20, 0);
      trend = ranging;
      if (RsiVal > 55) trend = up;
      if (RsiVal < 45) trend = down;
      OldH1Bars = iBars(NULL, PERIOD_H1);
   }//if (UseHedging)
   
   
   
   /*
   if (ObjectFind(takeprofitlinename) == 0 && ObjectGet(takeprofitlinename, OBJPROP_PRICE1) != TpLinePrice1) 
   {
      ObjectSet(takeprofitlinename,OBJPROP_COLOR,TakeProfitLineColour);
   }//if (ObjectFind(takeprofitlinename) > -1 && OBJPROP_PRICE1 != TpLinePrice1) 
   */
   
   
   //Replace deleted reentry line
   if (ObjectFind(reentrylinename) == -1 && OpenTrades > 0)
   {
      ReplaceReEntryLine();
   }//if (ObjectFind(reentrylinename) == -1 && OpenTrades > 0)
   
   /*
   //Mop up unwanted duplicate trades and orphaned secondaries 
   if (Old5Bars != iBars(NULL, PERIOD_M5) )
   {
      Old5Bars = iBars(NULL, PERIOD_M5);
      if (OpenTrades > 0 || PendingTrades > 0) 
      {
         bool result = CleanUp();
         Sleep(10000);
         if (!result)
         {
            Old5Bars = 0;
         }//if (!result)
         return;   
      }//if (OpenTrades > 0 && Old5Bars != iBars(NULL, PERIOD_M5) )
   }//if (Old5Bars != iBars(NULL, PERIOD_M5) )
   */

   if (OpenTrades == 0) 
   {
      ForcePendingTradeDeletion = false;
      ForceAllTradeDeletion = false;
      //PrevOpenTrades = 0;
      //GlobalVariableSet(GvName, 0);
      if (ObjectFind(breakevenlinename) > -1) ObjectDelete(breakevenlinename);
      if (ObjectFind(reentrylinename) > -1) ObjectDelete(reentrylinename);
      //if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);      
      MostRecentTradePrice=0;
      OpenTrades = 0;
      RecoveryInProgress = false;
      HedgingInProgress = false;      
   }//if (OpenTrades == 0) 
   
   if (OpenTrades == 0) RecoveryInProgress = false;
   
   //Recovery
   if (UseRecovery && !HedgingInProgress)
   {
      if (OpenTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
      
      /*
      I have moved this to SendSingleTrade.
      if (RecoveryInProgress)
      {
         if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);
         RecoveryModule();
      }//if (RecoveryInProgress)
      */
      
      //Replace accidentally deleted be line
      if (RecoveryInProgress && ObjectFind(breakevenlinename) == -1)
      //if (ObjectFind(breakevenlinename) == -1 && OpenTrades > TradeNumber) //DC
      {
         RecoveryModule();      
      }//if (ObjectFind(breakevenlinename) == -1 && OpenTrades > 2)
   }//if (UseRecovery)
   
   if (HedgingInProgress)
   {
      if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);
      if (BasketUpl >= 0)
      {
         ForceAllTradeDeletion = true;
         CloseAllTrades();
         return;
      }//if (BasketUpl >= 0)
      
   }//if (HedgingInProgress)
   
   
   /*
   if (OldBars != Bars5)
   {
      OldBars = Bars;
      ForcePendingTradeDeletion = true;
      DeletePendingTrades();
      if (ForcePendingTradeDeletion) OldBars = 0;
   }//if (OldBars != Bars)
   */
   
   //Delete pending orders if a previous attempt failed
   
   if (ForcePendingTradeDeletion)
   {
      DeletePendingTrades();
      return;
   }//if (ForcePendingTradeDeletion)
   
   
   //Delete open trades if a previous attempt failed
   if (ForceAllTradeDeletion)
   {
      CloseAllTrades();
      return;
   }//if (ForcePendingTradeDeletion)
   
       /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trading times
   bool TradeTimeOk = CheckTradingTimes();
   if (!TradeTimeOk)
   {
      if (PendingTrades > 0)
      {
         ForcePendingTradeDeletion = true;
         DeletePendingTrades();
      }//if (PendingTrades > 0)
      
      Comment("Outside trading hours\nstart_hourm-end_hourm: ", start_hourm, "-",end_hourm, "\nstart_houre-end_houre: ", start_houre, "-",end_houre);
      return;
   }//if (hour < start_hourm)
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   GetSixths();
   
   
   /*
   if (ObjectFind(takeprofitlinename) == -1 && OpenTrades > 0 && UseTplTp) 
   {
      if (OrderType() == OP_SELL) DrawTakeProfitLine(OP_SELL);
      if (OrderType() == OP_BUY) DrawTakeProfitLine(OP_BUY);
   }//if (ObjectFind(takeprofitlinename) == -1 && OpenTrades > 0) 
   */
   
   /*
   Replaced this with an OrderModify in GetSixths()
   //Delete pending orders if sixths have changed
   if ((OldBottomLine != BottomLine || OldTopLine != TopLine) && (OldBottomLine > 0 
   && OldTopLine > 0) && PendingTrades > 0)
   {
      //ForcePendingTradeDeletion = true;
      //DeletePendingTrades();
      //if (ForcePendingTradeDeletion) return;
   }//if ((OldBottomLine != BottomLine || OldTopLine != TopLine) && (OldBottomLine > 0 && OldTopLine > 0) )
   OldBottomLine = BottomLine;
   OldTopLine = TopLine;
   */
   
   //Should open trades be closed?
   if (BasketUpl >= 0  && HedgingInProgress) LookForTradeClosure();
   
   //Available margin filters
   if (UseScoobsMarginCheck && OpenTrades == 0)
   {
      if(AccountMargin() > (AccountFreeMargin()/100)) 
      {
         Comment(Gap + "There is insufficient margin to allow trading. You might want to turn off the UseScoobsMarginCheck input.");
         return;
      }//if(AccountMargin() > (AccountFreeMargin()/100)) 
      
   }//if (UseScoobsMarginCheck)


   if (UseForexKiwi && AccountMargin() > 0)
   {
      
      double ml = NormalizeDouble(AccountEquity() / AccountMargin() * 100, 2);
      if (ml < FkMinimumMarginPercent)
      {
         Comment(Gap + "There is insufficient margin percent to allow trading. " + DoubleToStr(ml, 2) + "%");
         return;
      }//if (ml < FkMinimumMarginPercent)
      
   }//if (UseForexKiwi && AccountMargin() > 0)
   
   
   //Look for trading opportunities
   if (!StopTrading)
   {
      CalculateTrades();
   }//if (!StopTrading)
   
   DisplayUserFeedback();
      

}
//+------------------------------------------------------------------+
/*
//+------------------------------------------------------------------+
//| expert PivotL function |
//+------------------------------------------------------------------+
double PivotL(string symbol)
{
return(iLow(symbol,60,iLowest(symbo l,60,MODE_LOW,168,1)));
}

//+------------------------------------------------------------------+
//| expert PivotH function |
//+------------------------------------------------------------------+
double PivotH(string symbol)
{
return(iHigh(symbol,60,iHighest(sym bol,60,MODE_HIGH,168,1)));
}

E2u
I think you are right and maybe this is something to check for each pairs also.

When it moves 0-9 pips from the days opening the probability of it reversing the trend is 75%.

When it moves 10-19 pips from the days opening the probability of it reversing the trend is 55%.

When it moves 20-29 pips from the days opening the probability of it reversing the trend is 40 %.

When it moves 30-39 pips from the days opening the probability of it reversing the trend is 25%.

When it moves 40-49 pips from the days opening the probability of it reversing the trend is 13%.

When it moves 50-59 pips from the days opening the probability of it reversing the trend is 8%.

When it moves 60-69 pips from the days opening the probability of it reversing the trend is 4%.

When it moves 70 pips from the days opening the probability of it reversing the trend is less then 1%.
*/