//+------------------------------------------------------------------+
//|                                                    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

/*

void DisplayUserFeedback()
void ReadIndicatorValues()
void LookForTradingOpportunities()
bool IsTradingAllowed()
bool DoesTradeExist(double price)
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
void LookForTradeClosure()
void CloseAllTrades()
void CountPendingTrades()
void DrawTakeProfitLine(int type)

----Re-entry line----
void AddReEntryLine(double price)
void CalculateReEntryLinePips()

----Recovery----
void RecoveryModule()
void CountOpenTrades()
void CheckRecoveryTakeProfit()
int Analyze()
int SymbolsIndex(string SymbolName)

----SHI----
void GetSHI(int shift, int tf)
void DrawLtfShi(int tf, string prefix, color col)
void DelObj(string prefix)

----Trade management module----
void TradeManagementModule()
void BreakEvenStopLoss()
bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
void JumpingStopLoss() 
void HiddenTakeProfit()
void HiddenStopLoss()
void TrailingStopLoss()

----Hedging----
void HedgingModule()
bool IsTradeAlreadyHedged(int ticket)
double GetRsi(int tf, int period, int shift)
double GetHedgeLotSize(int type)

*/
extern string  gen="----General inputs----";
extern double  Lot=0.01;
extern int     BarCount=0;
extern bool    StopTrading=false;
extern int     MaxTradesAllowed=5;
extern int     MagicNumber=0;
extern string  TradeComment="";
extern bool    CriminalIsECN=false;
extern int     MinPipsFromLastEntry=50;
extern string  shi="----SHI----";
extern int     AllBars = 240;
extern int     BarsForFract = 0;
extern int     HtfTimeFrame=1440;
extern color   HtfColour=Turquoise;
extern int     LtfTimeFrame=240;
extern color   LtfColour=Green;
extern int     TtfTimeFrame=60;
extern color   TtfColour=Yellow;

//extern int     PipsBufferFromTradeLine=10;
extern string  tps="----Take Profit and Stop Loss----";
extern bool    TakeProfitIsMiddle=true;
extern bool    TakeProfitIsOpposite=false;
extern bool    UseStopLoss=false;
extern bool    StopLossIsMiddle=true;
extern bool    StopLossIsOpposite=false;
extern string  tpi="----Take profit line----";
extern bool    UseTplTp=false;
extern color   TakeProfitLineColour=Blue;
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=Yellow;
extern color   BreakEvenLineColour=Aqua;
extern int     ReEntryLinePips=0;
extern int     RecoveryBreakEvenProfitPips=10;
extern string  tmm="----Trade management module----";
extern bool    DoNotOverload5DigitCriminals=false;
extern string  BE="Break even settings";
extern bool    BreakEven=true;
extern int     BreakEvenPips=40;
extern int     BreakEvenProfit=30;
extern bool    HideBreakEvenStop=false;
extern int     PipsAwayFromVisualBE=5;
extern string  JSL="Jumping stop loss settings";
extern bool    JumpingStop=true;
extern int     JumpingStopPips=30;
extern bool    AddBEP=false;
extern bool    JumpAfterBreakevenOnly=true;
extern bool    HideJumpingStop=false;
extern int     PipsAwayFromVisualJS=10;
extern string  TSL="Trailing stop loss settings";
extern bool    TrailingStop=false;
extern int     TrailingStopPips=50;
extern bool    HideTrailingStop=false;
extern int     PipsAwayFromVisualTS=10;
extern bool    TrailAfterBreakevenOnly=false;
extern bool    StopTrailAtPipsProfit=false;
extern int     StopTrailPips=0;
extern string  hsl1="Hidden stop loss settings";
extern bool    HideStopLossEnabled=false;
extern int     HiddenStopLossPips=20;
extern string  htp="Hidden take profit settings";
extern bool    HideTakeProfitEnabled=false;
extern int     HiddenTakeProfitPips=20;
extern string  hed="----Hedging----";
extern bool    UseHedging=true;
extern int     HedgeAtLossPips=200;
extern double  HedgeLotsMiltiplier=2;
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;


//SHI
double         LtfShiUpper, LtfShiMiddle, LtfShiLower, pLtfShiUpper, pLtfShiMiddle, pLtfShiLower;
double         HtfShiUpper, HtfShiMiddle, HtfShiLower, pHtfShiUpper, pHtfShiMiddle, pHtfShiLower;
double         TtfShiUpper, TtfShiMiddle, TtfShiLower, pTtfShiUpper, pTtfShiMiddle, pTtfShiLower;
int            CurrentBar = 0;
double         Step = 0;
int            B1 = -1, B2 = -1;
int            UpDown = 0;
double         P1 = 0, P2 = 0, PP = 0;
int            i = 0, AB = 300, BFF = 0;
int            ishift = 0;
double         iprice = 0;
datetime       T1, T2;


bool           ForcePendingTradeDeletion, ForceAllTradeDeletion;
int            OpenTrades, PrevOpenTrades, PendingTradesTotal, PrimaryTrades, SecondaryTrades,
               PendingPrimary, PendingSecondary, Old5Bars;
int            OldLtfBars, OldHtfBars, OldTtfBars;
string         GvName, Gap, ScreenMessage;
double         TpLinePrice1;
int            TpLinePipsFromWhite=10;

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         LtfTrend, HtfTrend, TtfTrend;
bool           HedgingInProgress;
bool           TradeLong=true;
bool           TradeShort=true;
int            TicketNo;
double         TotalLotsOpen;

//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    ExtLtfShifts[8]={ 10, 80, 130, 180, 260, 310, 390, 460 };
int    ExtVertLtfShift=14;
double buy_price=0.0;
double sell_price=0.0;

void DisplayUserFeedback()
{
   
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   //Code for time to bar-end display from Candle Time by Nick Bilak
   double i;
   int m,s,k;
   m=Time[0]+Period()*60-CurTime();
   i=m/60.0;
   s=m%60;
   m=(m-m%60)/60;
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, m + " minutes " + s + " seconds left to bar end", NL);

      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);      
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot: ", Lot, NL);
   if (TradeLong == true) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading long ", NL);
   if (TradeShort == true) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading short ", NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
   //if (CriminalIsECN) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = true", NL);
   //else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "CriminalIsECN = false", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL, NL );
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours", NL);
   if (start_hourm == 0 && end_hourm == 12 && start_houre && end_houre == 24) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            24H trading", NL);
   else
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            start_hourm: ", DoubleToStr(start_hourm, 2), 
                      ": end_hourm: ", DoubleToStr(end_hourm, 2), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "            end_houre: ", DoubleToStr(start_hourm, 2), 
                      ": end_houre: ", DoubleToStr(end_hourm, 2), NL);
                      
   }//else
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LtfShi Upper line: ", DoubleToStr(LtfShiUpper, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LtfShi Middle line: ", DoubleToStr(LtfShiMiddle, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LtfShi Lower line: ", DoubleToStr(LtfShiLower, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "LtfTrend: ", LtfTrend, NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "HtfShi Upper line: ", DoubleToStr(HtfShiUpper, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "HtfShi Middle line: ", DoubleToStr(HtfShiMiddle, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "HtfShi Lower line: ", DoubleToStr(HtfShiLower, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "HtfTrend: ", HtfTrend, NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TtfShi Upper line: ", DoubleToStr(TtfShiUpper, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TtfShi Middle line: ", DoubleToStr(TtfShiMiddle, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TtfShi Lower line: ", DoubleToStr(TtfShiLower, Digits), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "TtfTrend: ", TtfTrend, NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   //ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BarCount = ", BarCount, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Recovery starts at ", Start_Recovery_at_trades, " filled Primary trades", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "ReEntryLinePips = ", ReEntryLinePips, NL);
   if (StopTrading) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading suspended", 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 (BreakEven)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trailing stop is set to ", TrailingStopPips, " pips", NL);
   }//if (BreakEven)

   if (UseHedging)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Hedging is enabled ", " with HedgeAtLossPips = ", HedgeAtLossPips, ": HedgeLotsMiltiplier = ", HedgeLotsMiltiplier, NL);      
   }//if (UseHedging)

//extern bool    UseHedging=false;
//extern int     HedgeAtLossPips=500;
//extern double  HedgeLotsMiltiplier=2;

   Comment(ScreenMessage);


}//void DisplayUserFeedback()




//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   OldLtfBars = 0;
   OldHtfBars = 0;
   OldTtfBars = 0;
   
   //ReEntryLinePips is calculated using Atr during ReadIndicatorValues(). 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;   
 
   TpLinePipsFromWhite*= 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;
   
   if (BarCount == 0)
   {
      //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; }
      
      
      //Now accommodate different time frames
      multiplier = 1;
      if (Period() == PERIOD_M1) multiplier = 60;
      if (Period() == PERIOD_M5) multiplier = 12;
      if (Period() == PERIOD_M15) multiplier = 4;
      if (Period() == PERIOD_M30) multiplier = 2;
      if (Period() == PERIOD_H1) multiplier = 1;
      if (Period() == PERIOD_H4) multiplier = 0.25;
      if (Period() == PERIOD_D1) multiplier = 0.25 / 6;
   
      double dBarCount = BarCount;
      //dBarCount*= multiplier;
      //BarCount = dBarCount;   
      
      //Andy's formula
      BarCount = MathRound(dBarCount/Period()*60);
      
    }//if (BarCount == 0)
     

   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   

   
   
   Comment("..................Waiting for the first tick");
   
   //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);
      
   start();
   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
   DelObj("Ltf");
   DelObj("Htf");
   DelObj("Ttf");
   
   
//----
   return(0);
}

void GetSHI(int shift, int tf)
{
   //Reads BB figures into LtfShiUpper, LtfShiMiddle, LtfShiLower
   
   //extern int     AllBars = 240;
   //extern int     BarsForFract = 0;

   double LtfShiUpper_tmp = ObjectGetValueByShift("LtfTL2", 0);
   double LtfShiLower_tmp = ObjectGetValueByShift("LtfTL1", 0);
   LtfShiMiddle = ObjectGetValueByShift("LtfMIDL", 0);
   
   double pLtfShiUpper_tmp = ObjectGetValueByShift("LtfTL2", 1);
   double pLtfShiLower_tmp = ObjectGetValueByShift("LtfTL1", 1);
   pLtfShiMiddle = ObjectGetValueByShift("LtfMIDL", 1);
   
   if (LtfShiUpper_tmp < LtfShiLower_tmp) {
      LtfShiUpper = LtfShiLower_tmp;
      LtfShiLower = LtfShiUpper_tmp;
      pLtfShiUpper = pLtfShiLower_tmp;
      pLtfShiLower = pLtfShiUpper_tmp;
   }
   else {
      LtfShiUpper = LtfShiUpper_tmp;
      LtfShiLower = LtfShiLower_tmp;
      pLtfShiUpper = pLtfShiUpper_tmp;
      pLtfShiLower = pLtfShiLower_tmp;
   }
   
   if (LtfShiUpper == pLtfShiUpper) LtfTrend = ranging;
   if (LtfShiUpper > pLtfShiUpper) LtfTrend = up;
   if (LtfShiUpper < pLtfShiUpper) LtfTrend = down;
   
   double HtfShiUpper_tmp = ObjectGetValueByShift("HtfTL2", 0);
   double HtfShiLower_tmp = ObjectGetValueByShift("HtfTL1", 0);
   HtfShiMiddle = ObjectGetValueByShift("HtfMIDL", 0);
   
   double pHtfShiUpper_tmp = ObjectGetValueByShift("HtfTL2", 1);
   double pHtfShiLower_tmp = ObjectGetValueByShift("HtfTL1", 1);
   pHtfShiMiddle = ObjectGetValueByShift("HtfMIDL", 1);
   
   if (HtfShiUpper_tmp < HtfShiLower_tmp) {
      HtfShiUpper = HtfShiLower_tmp;
      HtfShiLower = HtfShiUpper_tmp;
      pHtfShiUpper = pHtfShiLower_tmp;
      pHtfShiLower = pHtfShiUpper_tmp;
   }
   else {
      HtfShiUpper = HtfShiUpper_tmp;
      HtfShiLower = HtfShiLower_tmp;
      pHtfShiUpper = pHtfShiUpper_tmp;
      pHtfShiLower = pHtfShiLower_tmp;
   }
   
   if (HtfShiUpper == pHtfShiUpper) HtfTrend = ranging;
   if (HtfShiUpper > pHtfShiUpper) HtfTrend = up;
   if (HtfShiUpper < pHtfShiUpper) HtfTrend = down;

   double TtfShiUpper_tmp = ObjectGetValueByShift("TtfTL2", 0);
   double TtfShiLower_tmp = ObjectGetValueByShift("TtfTL1", 0);
   TtfShiMiddle = ObjectGetValueByShift("TtfMIDL", 0);
   
   double pTtfShiUpper_tmp = ObjectGetValueByShift("TtfTL2", 1);
   double pTtfShiLower_tmp = ObjectGetValueByShift("TtfTL1", 1);
   pTtfShiMiddle = ObjectGetValueByShift("TtfMIDL", 1);
   
   if (TtfShiUpper_tmp < TtfShiLower_tmp) {
      TtfShiUpper = TtfShiLower_tmp;
      TtfShiLower = TtfShiUpper_tmp;
      pTtfShiUpper = pTtfShiLower_tmp;
      pTtfShiLower = pTtfShiUpper_tmp;
   }
   else {
      TtfShiUpper = TtfShiUpper_tmp;
      TtfShiLower = TtfShiLower_tmp;
      pTtfShiUpper = pTtfShiUpper_tmp;
      pTtfShiLower = pTtfShiLower_tmp;
   }
   
   if (TtfShiUpper == pTtfShiUpper) TtfTrend = ranging;
   if (TtfShiUpper > pTtfShiUpper) TtfTrend = up;
   if (TtfShiUpper < pTtfShiUpper) TtfTrend = down;

   
}//void GetSHI(int shift, int tf)

void ReadIndicatorValues()
{

   GetSHI(0, 0);
   
}//void ReadIndicatorValues()


////////////////////////////////////////////////////////////////////////////////////////////////
//TRADE MANAGEMENT MODULE


bool CheckForHiddenStopLossHit(int type, int iPipsAboveVisual, double stop )
{
   //Reusable code that can be called by any of the stop loss manipulation routines except HiddenStopLoss().
   //Checks to see if the market has hit the hidden sl and attempts to close the trade if so. 
   //Returns true if trade closure is successful, else returns false
   
   
   //Check buy trade
   if (type == OP_BUY)
   {
      double sl = NormalizeDouble(stop + (iPipsAboveVisual * Point), Digits);
      if (Bid <= sl)
      {
         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)
      {
         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)
   

}//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())
      {
         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)) 
      {
         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
            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);
         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
            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);
         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)
      {
         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)
      {
         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)
      {
         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)
      {
         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;
		          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;
		            result = OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),0,CLR_NONE);
                  if (result)
                  {
                     Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl, ": Bid ", Bid);
                  }//if (result)
                  else
                  {
                     err=GetLastError();
                     Print(OrderSymbol(), " order modify failed with error(",err,"): ",ErrorDescription(err));
                  }//else
    
		       }//if (Ask < sl -  (TrailingStopPips*Point))
		   }//if (Ask <= OrderOpenPrice() - (TrailingStopPips*Point))
      }//if (OrderType()==OP_SELL) 

      
} // End of TrailingStopLoss sub


void TradeManagementModule()
{

   // Call the working subroutines one by one. 

   //Cut down 5 digit order modify calls for 5 digit crims, if required
   static int NoOfTicks = 9;
   int ndigits = MarketInfo(Symbol(), MODE_DIGITS);
   if (DoNotOverload5DigitCriminals && ( ndigits == 3 || ndigits == 5) )
   {
      NoOfTicks++;
   }//if (DoNotOverload5DigitCriminals && ( digits == 3 || digits == 5) )
   
   if (!DoNotOverload5DigitCriminals || ndigits == 2 || ndigits == 4)
   {
      NoOfTicks = 10;
   }//if (!DoNotOverload5DigitCriminals || digits == 2 || digits == 4)
   
   
   // Global variable to pick up on failed part-closes
   //if (GlobalVariablesTotal()>0) GlobalVariablesExist=true;
   //if (GlobalVariablesExist && GlobalVariablesTotal()>0) TryPartCloseAgain();
   //if (GlobalVariablesExist && GlobalVariablesTotal()==0) GlobalVariablesExist=false;
   
   if (NoOfTicks >= 10)
   {
      NoOfTicks = 0;//Reset the counter
      
      // Hidden stop loss
      if (HideStopLossEnabled) HiddenStopLoss();
   
      // Hidden take profit
      if (HideTakeProfitEnabled) HiddenTakeProfit();
   
      // Breakeven
      if(BreakEven) BreakEvenStopLoss();
   
      // JumpingStop
      if(JumpingStop) JumpingStopLoss();
   
      //TrailingStop
      if(TrailingStop) TrailingStopLoss();

   }//if (NoOfTicks >= 10)
   

}//void TradeManagementModule()
//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;

      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
         string sOpen = DoubleToStr(OrderOpenPrice(), Digits);
         if (sPrice == sOpen)
         {
            return(true);
         }//if (OrderOpenPrice() == price && OrderSymbol() == Symbol() )
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
   }//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 slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   
   //extern int     PendingExpiryMinutes=240;
   int expiry = 0;
   //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);

   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, MagicNumber, expiry, col);
   
   
   //Is a 2 stage criminal
   if (CriminalIsECN)
   {
      ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, MagicNumber, expiry, col);
	   if (stop != 0 && take == 0)
	   {
		   if (ticket > 0)
		   bool result = OrderModify(ticket, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
		   if (!result)
		   {
		       int err=GetLastError();
             Print(Symbol(), " ", type," SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
		   }//if (!result)			  
	   }//if (stop != 0 && take == 0)
      
      if (take != 0 && stop == 0)
	   {
		   if (ticket > 0)
		   result = OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
		   if (!result)
		   {
		       err=GetLastError();
             Print(Symbol(), " ", type," SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
		   }//if (!result)			  
	   }//if (take != 0 && stop == 0)
      
      if (take != 0 && stop != 0)
	   {
		   if (ticket > 0)
		   result = OrderModify(ticket, OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE);
		   if (!result)
		   {
		       err=GetLastError();
             Print(Symbol(), " ", type," SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
		   }//if (!result)			  
	   }//if (take != 0 && stop == 0)
      
      
   }//if (CriminalIsECN)
   
   //Error trapping for both
   if (ticket < 0)
   {
      string stype;
      if (type == OP_BUY) stype = "OP_BUY";
      if (type == OP_SELL) stype = "OP_SELL";
      err=GetLastError();
      Alert(Symbol(), " ", stype," Nanningbob order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," Nanningbob order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   //Got this far, so trade send succeeded
   return(true);
   
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)


bool IsTradingAllowed()
{
   
   
   //Trades count
   if (OpenTrades + PendingTradesTotal >= MaxTradesAllowed) return(false);
   
   //This is possibly redundant, gut I include it as a check anyhow
   if (Bid <= LtfShiUpper && Ask >= LtfShiLower) return(false);
   
   
   //Min distance from most recently filled trade
   if (MostRecentTradePrice != 0)
   {
      double MinDistance = MinPipsFromLastEntry * Point;
      
      //Possible short trade
      if (Bid > LtfShiUpper)
      {
         if (LtfShiUpper - MostRecentTradePrice < MinDistance) return(false);
      }//if (Bid > TopGldLine)
      
      
      //Possible long trade
      if (Ask < LtfShiLower)
      {
         if (MostRecentTradePrice - LtfShiLower < MinDistance) return(false);
      }//if (Ask < LtfShiLower)
      
   }//if (MostRecentTradePrice != 0)
   

   return(true);


}//End bool IsTradingAllowed()
/*
void CalculateReEntryLinePips()
{
   //From THV ATR Pips and adapted here
   //double stopLoss = MathCeil(pipMult * multiplier * (iATR(NULL,0,periods,i)));
   ReEntryLinePips = MathCeil(iATR(NULL, 0, BarCount, 0) * 9 * 10000);
   
   //Adapt to x digit crims
   int multiplier;
   if(Digits == 2 || Digits == 4) multiplier = 1;
   if(Digits == 3 || Digits == 5) multiplier = 10;
   if(Digits == 6) multiplier = 100;   
   if(Digits == 7) multiplier = 1000;   
 
   ReEntryLinePips*= multiplier;
   
}//void CalculateReEntryLinePips()
*/

void DrawTakeProfitLine(int type)
{
   double price;
   
   if (type == OP_BUY) price = NormalizeDouble(LtfShiMiddle + (TpLinePipsFromWhite * Point), Digits);
   if (type == OP_SELL) price = NormalizeDouble(LtfShiMiddle - (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)



void LookForTradingOpportunities()
{
   double target;

   bool TradingAllowed = IsTradingAllowed();
   if (!TradingAllowed) return;

//extern bool    Use1.1.3.3Recovery=false;
//extern bool    Use1.1.2.4Recovery=true;

  
   double SendLots = Lot;
   //Using 1.1.2.4 recovery
   if (RecoveryInProgress)
   {
      if (PrimaryTrades == 2) 
      {
         SendLots = Lot * 2;         
         if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      }//if (PrimaryTrades == 2) 
      
      if (PrimaryTrades == 3) 
      {
         SendLots = Lot * 4;
         if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      }//if (PrimaryTrades == 3) 
      
      if (PrimaryTrades == 4) return;//No further trading is possible
      
      double RecoveryLineVal = ObjectGet(reentrylinename, OBJPROP_PRICE1);
   }//if (RecoveryInProgress)
   
   double stop, take;
   bool result;
               
   //Sell
   if (Bid >= TtfShiUpper && TtfTrend == down && HtfTrend == down && LtfTrend == down )
   {
      if (RecoveryInProgress && LtfShiUpper < RecoveryLineVal) return;
      if (!DoesTradeExist(LtfShiUpper) ) 
      {
         if (TakeProfitIsMiddle) take = LtfShiMiddle;
         if (TakeProfitIsOpposite) take = LtfShiLower;      
         if (UseStopLoss) 
         {
            if (StopLossIsMiddle) stop = NormalizeDouble(Bid + (LtfShiUpper - LtfShiMiddle), Digits);
            if (StopLossIsOpposite) stop = NormalizeDouble(Bid + (LtfShiUpper - LtfShiLower), Digits);      
         }//if (UseStopLoss) 
         result = SendSingleTrade(OP_SELL, TradeComment, SendLots, Bid, stop, take);
         if (result && !RecoveryInProgress && UseTplTp) DrawTakeProfitLine(OP_SELL);
      }//if (!DoesTradeExist(LtfShiUpper) ) 
      
      if (result) AddReEntryLine(NormalizeDouble(Bid + (ReEntryLinePips * Point), Digits) );      
      
   }//if (Bid >= LtfShiHigher && TradeShort)
   
   

   //Buy
   if (Ask <= TtfShiLower && TtfTrend == up && LtfTrend == up && HtfTrend == up )
   {
      if (RecoveryInProgress && LtfShiLower > RecoveryLineVal) return;
      if (!DoesTradeExist(LtfShiLower) ) 
      {
         if (TakeProfitIsMiddle) take = LtfShiMiddle;
         if (TakeProfitIsOpposite) take = LtfShiUpper;
         if (UseStopLoss)
         {
            if (StopLossIsMiddle) stop = NormalizeDouble(Ask - (LtfShiMiddle - LtfShiLower), Digits);
            if (StopLossIsOpposite) stop = NormalizeDouble(Ask - (LtfShiUpper - LtfShiLower), Digits);         
         }//if (UseStopLoss)
         result = SendSingleTrade(OP_BUY, TradeComment, SendLots, Ask, stop, take);
         if (result && !RecoveryInProgress && UseTplTp) DrawTakeProfitLine(OP_BUY);
      }//if (!DoesTradeExist(LtfShiLower) ) 
      
      if (result) AddReEntryLine(NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits) );
   }//if (Ask <= LtfShiLower && TradeLong)
   
   

}//End void LookForTradingOpportunities()

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() && (OrderComment() == TradeComment) 
          && (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) )
      {
         bool result = OrderDelete(OrderTicket() );
         if (result) {cc++; ObjectDelete(reentrylinename); }
         if (!result) ForcePendingTradeDeletion = true;
      }//if (OrderSymbol() == Symbol() && (OrderComment() == TradeComment || 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() )
      {
         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 <= LtfShiMiddle)
         {
            CloseAllTrades();
         }//if (OrderType == OP_SELL && Bid < LtfShiMiddle)
         
         if (OrderType() == OP_BUY && Ask >= LtfShiMiddle)
         {
            CloseAllTrades();
         }//if (OrderType == OP_SELL && Bid < LtfShiMiddle)
         
      }//if (OrderSymbol() == Symbol() )     
   
   }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)


}//End void LookForTradeClosure()
   
void CountOpenTrades()
{
   OpenTrades = 0;
   TicketNo = 0;
   BasketUpl = 0;
   PrimaryTrades = 0;
   bool BuyOpen, SellOpen;
   
   if (OrdersTotal() == 0) return;
   
   for (int cc = 0; cc <= OrdersTotal(); cc++)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
         if (OrderProfit() > 0 && ObjectFind(breakevenlinename) == -1 && !RecoveryInProgress && !HedgingInProgress) 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 (OrderLots() == Lot) PrimaryTrades++;
            TicketNo = OrderTicket();
         }//if (OrderType() == OP_BUY || OrderType() == OP_SELL) 
         
         //Does the position need hedging?         
         if (OrderSelect(TicketNo, SELECT_BY_TICKET) && OrderProfit() < 0 && UseHedging) HedgingModule();
         
         
         if (ObjectFind(breakevenlinename) > -1 && !HedgingInProgress)
         {
            double take = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
            if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
            {
               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) )
            {
               OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
            }//if (OrderTakeProfit() != take && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
         }//if (ObjectFind(takeprofitlinename) > -1)
         
         
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
   }//for (int cc = 0; cc <= OrdersTotal(); cc++)

   if (BuyOpen && SellOpen) HedgingInProgress = true;
   
}//End void CountOpenTrades()

void CountPendingTrades()
{
   PendingTradesTotal = 0;
   PendingPrimary = 0;
   PendingSecondary = 0;
   
   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) 
         {
            PendingTradesTotal++;  
            if (OrderLots() == Lot) PendingPrimary++;            
         }//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=ExtVertLtfShift*(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,ExtLtfShifts[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)

double GetHedgeLotSize(int type)
{
   double hl;
   
   for (int cc = OrdersTotal() - 1; cc >=0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type)
      {
         hl+= OrderLots();
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == type)
      
   }//for (int cc = OrdersTotal() - 1; cc >=0; cc--)

   return(hl);
   
}//double GetHedgeLotSize(int type)


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, HedgeLots;
   int tn = OrderTicket();
   
   RefreshRates();
   
   
   if (OrderType() == OP_BUY)
   {
      loss = OrderOpenPrice() - Ask;
      if (loss > (HedgeAtLossPips * Point) && LtfTrend == down)
      {
         bool HedgeExists = IsTradeAlreadyHedged(tn);
         OrderSelect(tn, SELECT_BY_TICKET);
         if (HedgeExists) return;
         HedgeLots = GetHedgeLotSize(OP_BUY);
         bool result = SendSingleTrade(OP_SELL, DoubleToStr(tn, 0), HedgeLots * HedgeLotsMiltiplier, Bid, 0, 0);
      }//if (loss > (HedgeAtLossPips * Point)      
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      loss = Bid - OrderOpenPrice();
      if (loss > (HedgeAtLossPips * Point)  && LtfTrend == up)
      {
         HedgeExists = IsTradeAlreadyHedged(tn);
         OrderSelect(tn, SELECT_BY_TICKET);
         if (HedgeExists) return;
         HedgeLots = GetHedgeLotSize(OP_SELL);
         result = SendSingleTrade(OP_BUY, DoubleToStr(tn, 0), HedgeLots * HedgeLotsMiltiplier, Ask, 0, 0);
      }//if (loss > (HedgeAtLossPips * Point)      
   }//if (OrderType() == OP_SELL)
   
   
   
}//End void HedgingModule()

/*
SAVED BECAUSE I KNOW THIS WORKS
void DelObj()
{
      ObjectDelete("TL1");
      ObjectDelete("TL2");
      ObjectDelete("MIDL");
}//void DelObj()


void DrawLtfShi(int tf, string prefix)
{
   if((AllBars == 0) || (Bars < AllBars)) 
   AB = Bars; 
   else AB = AllBars; 
      CurrentBar = 2; //??????? ? ???????? ????, ????? ??????? "??????????
   if(BarsForFract > 0) 
             BFF = BarsForFract; 
      else
             switch (Period())
               {
                    case     1: BFF = 12; break;
                    case     5: BFF = 48; break;
                    case    15: BFF = 24; break;
                    case    30: BFF = 24; break;
                    case    60: BFF = 12; break;
                    case   240: BFF = 15; break;
                    case  1440: BFF = 10; break;
                    case 10080: BFF = 6;  break;
                    default: DelObj(); return(-1); break;
               }
   B1 = -1; 
   B2 = -1; 
   UpDown = 0;
   while(((B1 == -1) || (B2==-1)) && (CurrentBar<AB))
     {
             //UpDown = 1 ?????? ?????? ??????? ?????? ??????, UpDown = -1 ?????? ?????? ???????
             //?????? ?????, UpDown = 0 ?????? ??????? ??? ?? ??????.
             //?1 ? ?2 - ?????? ????? ? ??????????, ????? ??? ?????? ??????? ?????.
             //?1 ? ?2 - ?????????????? ???? ????? ??????? ????? ????? ?????????
             if((UpDown < 1) && (CurrentBar == Lowest(Symbol(), Period(), MODE_LOW, BFF*2 + 1,
                CurrentBar - BFF))) 
               {
                    if(UpDown == 0) 
                      { 
                        UpDown = -1; 
                        B1 = CurrentBar; 
                        P1 = Low[B1]; 
                      }
                    else 
                      { 
                        B2 = CurrentBar; 
                        P2 = Low[B2];
                      }
               }
             if((UpDown > -1) && (CurrentBar == Highest(Symbol(), Period(), MODE_HIGH, BFF*2 + 1,
                CurrentBar - BFF))) 
               {
                    if(UpDown == 0) 
                      { 
                        UpDown = 1; 
                        B1 = CurrentBar; 
                        P1 = High[B1]; 
                      }
                    else 
                      { 
                        B2 = CurrentBar; 
                        P2 = High[B2]; 
                      }
               }
             CurrentBar++;
        }
      if((B1 == -1) || (B2 == -1)) 
        {
          DelObj(); 
          return(-1);
        } // ?????? ?? ????? ????????? ????? 300 ????? 8-)
      Step = (P2 - P1) / (B2 - B1); //????????? ???, ???? ?? ?????????????, ?? ????? ??????????
      P1 = P1 - B1*Step; 
      B1 = 0; //???????????? ???? ? ?????? ??? ? ????
//? ?????? ??????? ????? ??????????????? ????? ??????.
      ishift = 0; 
      iprice = 0;
      if(UpDown == 1)
        { 
             PP = Low[2] - 2*Step;
             for(i = 3; i <= B2; i++) 
               {
                    if(Low[i] < PP + Step*i) 
                        PP = Low[i] - i*Step; 
               }
             if(Low[0] < PP) 
               {
                 ishift = 0; 
                 iprice = PP;
               }
             if(Low[1] < PP + Step) 
               {
                 ishift = 1; 
                 iprice = PP + Step;
               }
             if(High[0] > P1) 
               {
                 ishift = 0; 
                 iprice = P1;
               }
             if(High[1] > P1 + Step) 
               {
                 ishift = 1; 
                 iprice = P1 + Step;
               }
        } 
      else
        { 
             PP = High[2] - 2*Step;
             for(i = 3; i <= B2; i++) 
               {
                    if(High[i] > PP + Step*i) 
                        PP = High[i] - i*Step;
               }
             if(Low[0] < P1) 
               {
                 ishift = 0; 
                 iprice = P1;
               }
             if(Low[1] < P1 + Step) 
               {
                 ishift = 1; 
                 iprice = P1 + Step;
               }
             if(High[0] > PP) 
               {
                 ishift = 0; 
                 iprice = PP;
               }
             if(High[1] > PP + Step) 
               {
                 ishift = 1; 
                 iprice = PP + Step;
               }
        }
//?????? ?????????? ???????? ???? ? ??? ?? ??, ????? ????? ?????? ?????????? ?????????
      P2 = P1 + AB*Step;
      T1 = Time[B1]; 
      T2 = Time[AB];
//???? ?? ???? ??????????? ??????, ?? 0, ????? ?????? ?????.
      //if(iprice != 0) 
          
      DelObj();
      ObjectCreate("TL1", OBJ_TREND, 0, T2, PP + Step*AB, T1, PP); 
         ObjectSet("TL1", OBJPROP_COLOR, Lime); 
         ObjectSet("TL1", OBJPROP_WIDTH, 2); 
         ObjectSet("TL1", OBJPROP_STYLE, STYLE_SOLID); 
      ObjectCreate("TL2", OBJ_TREND, 0, T2, P2, T1, P1); 
         ObjectSet("TL2", OBJPROP_COLOR, Lime); 
         ObjectSet("TL2", OBJPROP_WIDTH, 2); 
         ObjectSet("TL2", OBJPROP_STYLE, STYLE_SOLID); 
      ObjectCreate("MIDL", OBJ_TREND, 0, T2, (P2 + PP + Step*AB) / 2, T1, (P1 + PP) / 2);
         ObjectSet("MIDL", OBJPROP_COLOR, Lime); 
         ObjectSet("MIDL", OBJPROP_WIDTH, 1); 
         ObjectSet("MIDL", OBJPROP_STYLE, STYLE_DOT);

   

}//void DrawLtfShi(int tf)
*/

/////////////////////////////////////////////////////////////////////////////////////////////////////
//TRYING TO ADAPT TO MTF
/////////////////////////////////////////////////////////////////////////////////////////////////////
void DelObj(string prefix)
{
      ObjectDelete(prefix + "TL1");
      ObjectDelete(prefix + "TL2");
      ObjectDelete(prefix + "MIDL");
}//void DelObj()


void DrawLtfShi(int tf, string prefix, color col)
{
   if((AllBars == 0) || (iBars(NULL, tf) < AllBars)) 
   AB = iBars(NULL, tf); 
   else AB = AllBars; 
      CurrentBar = 2; //??????? ? ???????? ????, ????? ??????? "??????????
   if(BarsForFract > 0) 
             BFF = BarsForFract; 
      else
             switch (Period())
               {
                    case     1: BFF = 12; break;
                    case     5: BFF = 48; break;
                    case    15: BFF = 24; break;
                    case    30: BFF = 24; break;
                    case    60: BFF = 12; break;
                    case   240: BFF = 15; break;
                    case  1440: BFF = 10; break;
                    case 10080: BFF = 6;  break;
                    default: DelObj(prefix); return(-1); break;
               }
   B1 = -1; 
   B2 = -1; 
   UpDown = 0;
   while(((B1 == -1) || (B2==-1)) && (CurrentBar<AB))
     {
             //UpDown = 1 ?????? ?????? ??????? ?????? ??????, UpDown = -1 ?????? ?????? ???????
             //?????? ?????, UpDown = 0 ?????? ??????? ??? ?? ??????.
             //?1 ? ?2 - ?????? ????? ? ??????????, ????? ??? ?????? ??????? ?????.
             //?1 ? ?2 - ?????????????? ???? ????? ??????? ????? ????? ?????????
             if((UpDown < 1) && (CurrentBar == Lowest(Symbol(), Period(), MODE_LOW, BFF*2 + 1,
                CurrentBar - BFF))) 
               {
                    if(UpDown == 0) 
                      { 
                        UpDown = -1; 
                        B1 = CurrentBar; 
                        P1 = iLow(NULL, tf, B1); 
                      }
                    else 
                      { 
                        B2 = CurrentBar; 
                        P2 = iLow(NULL, tf, B2); 
                      }
               }
             if((UpDown > -1) && (CurrentBar == Highest(Symbol(), tf, MODE_HIGH, BFF*2 + 1,
                CurrentBar - BFF))) 
               {
                    if(UpDown == 0) 
                      { 
                        UpDown = 1; 
                        B1 = CurrentBar; 
                        P1 = iHigh(NULL, tf, B1); 
                      }
                    else 
                      { 
                        B2 = CurrentBar; 
                        P2 = iHigh(NULL, tf, B2); 
                      }
               }
             CurrentBar++;
        }
      if((B1 == -1) || (B2 == -1)) 
        {
          DelObj(prefix); 
          return(-1);
        } // ?????? ?? ????? ????????? ????? 300 ????? 8-)
      Step = (P2 - P1) / (B2 - B1); //????????? ???, ???? ?? ?????????????, ?? ????? ??????????
      P1 = P1 - B1*Step; 
      B1 = 0; //???????????? ???? ? ?????? ??? ? ????
//? ?????? ??????? ????? ??????????????? ????? ??????.
      ishift = 0; 
      iprice = 0;
      if(UpDown == 1)
        { 
             PP = iLow(NULL, tf, 2) - 2*Step;
             for(i = 3; i <= B2; i++) 
               {
                    if(iLow(NULL, tf, i) < PP + Step*i) 
                        PP = iLow(NULL, tf, i) - i*Step; 
               }
             if(iLow(NULL, tf, 0) < PP) 
               {
                 ishift = 0; 
                 iprice = PP;
               }
             if(iLow(NULL, tf, 1) < PP + Step) 
               {
                 ishift = 1; 
                 iprice = PP + Step;
               }
             if(iHigh(NULL, tf, 0) > P1) 
               {
                 ishift = 0; 
                 iprice = P1;
               }
             if(iHigh(NULL, tf, 1) > P1 + Step) 
               {
                 ishift = 1; 
                 iprice = P1 + Step;
               }
        } 
      else
        { 
             PP = iHigh(NULL, tf, 2) - 2*Step;
             for(i = 3; i <= B2; i++) 
               {
                    if(iHigh(NULL, tf, i) > PP + Step*i) 
                        PP = iHigh(NULL, tf, i) - i*Step;
               }
             if(iLow(NULL, tf, 0) < P1) 
               {
                 ishift = 0; 
                 iprice = P1;
               }
             if(iLow(NULL, tf, 1) < P1 + Step) 
               {
                 ishift = 1; 
                 iprice = P1 + Step;
               }
             if(iHigh(NULL, tf, 0) > PP) 
               {
                 ishift = 0; 
                 iprice = PP;
               }
             if(iHigh(NULL, tf, 1) > PP + Step) 
               {
                 ishift = 1; 
                 iprice = PP + Step;
               }
        }
//?????? ?????????? ???????? ???? ? ??? ?? ??, ????? ????? ?????? ?????????? ?????????
      P2 = P1 + AB*Step;
      T1 = iTime(NULL, tf, B1);
      T2 = iTime(NULL, tf, AB);
//???? ?? ???? ??????????? ??????, ?? 0, ????? ?????? ?????.
      //if(iprice != 0) 
          
      DelObj(prefix);
      ObjectCreate(prefix + "TL1", OBJ_TREND, 0, T2, PP + Step*AB, T1, PP); 
         ObjectSet(prefix + "TL1", OBJPROP_COLOR, col); 
         ObjectSet(prefix + "TL1", OBJPROP_WIDTH, 2); 
         ObjectSet(prefix + "TL1", OBJPROP_STYLE, STYLE_SOLID); 
      ObjectCreate(prefix + "TL2", OBJ_TREND, 0, T2, P2, T1, P1); 
         ObjectSet(prefix + "TL2", OBJPROP_COLOR, col); 
         ObjectSet(prefix + "TL2", OBJPROP_WIDTH, 2); 
         ObjectSet(prefix + "TL2", OBJPROP_STYLE, STYLE_SOLID); 
      ObjectCreate(prefix + "MIDL", OBJ_TREND, 0, T2, (P2 + PP + Step*AB) / 2, T1, (P1 + PP) / 2);
         ObjectSet(prefix + "MIDL", OBJPROP_COLOR, col); 
         ObjectSet(prefix + "MIDL", OBJPROP_WIDTH, 1); 
         ObjectSet(prefix + "MIDL", OBJPROP_STYLE, STYLE_DOT);

   

}//void DrawLtfShi(int tf)


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{


   static double OldLtfShiLower, OldLtfShiUpper;//Keep track of where the sixths were, in case they have moved
   static int OldH1Bars;
   
   if (OldLtfBars != iBars(NULL, LtfTimeFrame) )
   {
      DrawLtfShi(LtfTimeFrame, "Ltf", LtfColour);
      OldLtfBars = iBars(NULL, LtfTimeFrame);
   }//if (OldLtfBars != iBars(NULL, LtfTimeFrame) )
   
   if (OldHtfBars != iBars(NULL, HtfTimeFrame) )
   {
      DrawLtfShi(HtfTimeFrame, "Htf", HtfColour);
      OldHtfBars = iBars(NULL, HtfTimeFrame);
   }//if (OldLtfBars != iBars(NULL, LtfTimeFrame) )
   
   if (OldTtfBars != iBars(NULL, TtfTimeFrame) )
   {
      DrawLtfShi(TtfTimeFrame, "Ttf", TtfColour);
      OldTtfBars = iBars(NULL, TtfTimeFrame);
   }//if (OldLtfBars != iBars(NULL, LtfTimeFrame) )
   
   
   /*if (UseHedging && OldH1Bars != iBars(NULL, PERIOD_H1) )
   {
      RsiVal = GetRsi(PERIOD_D1, 20, 0);
      LtfTrend = ranging;
      if (RsiVal > 55) LtfTrend = up;
      if (RsiVal < 45) LtfTrend = 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) 
   
   CountOpenTrades();
   CountPendingTrades();
   
   
   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;
      PrimaryTrades = 0;
      RecoveryInProgress = false;
      HedgingInProgress = false;      
   }//if (OpenTrades == 0) 
   
   if (OpenTrades == 0) RecoveryInProgress = false;
   
   //Recovery
   if (UseRecovery && !HedgingInProgress)
   {
      if (PrimaryTrades >= Start_Recovery_at_trades) RecoveryInProgress = true;
      if (RecoveryInProgress)
      {
         if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);
         RecoveryModule();
      }//if (RecoveryInProgress)

      //Replace accidentally deleted be line
      if (RecoveryInProgress && ObjectFind(breakevenlinename) == -1)
      //if (ObjectFind(breakevenlinename) == -1 && OpenTrades > TradeNumber) //DC
      {
         RecoveryModule();      
      }//if (ObjectFind(breakevenlinename) == -1 && OpenTrades > 2)
   }//if (UseRecovery)
   
   if (HedgingInProgress)
   {
      if (ObjectFind(takeprofitlinename) > -1) ObjectDelete(takeprofitlinename);
      if (BasketUpl >= 0)
      {
         ForceAllTradeDeletion = true;
         CloseAllTrades();
         return;
      }//if (BasketUpl >= 0)
      
   }//if (HedgingInProgress)
   
   
   /*
   if (OldLtfBars != Bars5)
   {
      OldLtfBars = Bars;
      ForcePendingTradeDeletion = true;
      DeletePendingTrades();
      if (ForcePendingTradeDeletion) OldLtfBars = 0;
   }//if (OldLtfBars != 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 (PendingTradesTotal > 0)
      {
         ForcePendingTradeDeletion = true;
         DeletePendingTrades();
      }//if (PendingTradesTotal > 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)
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   ReadIndicatorValues();
   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) 
   
   //Delete pending orders if sixths have changed
   if ((OldLtfShiLower != LtfShiLower || OldLtfShiUpper != LtfShiUpper) && (OldLtfShiLower > 0 
   && OldLtfShiUpper > 0) && PendingTradesTotal > 0)
   {
      ForcePendingTradeDeletion = true;
      DeletePendingTrades();
      return;
   }//if ((OldLtfShiLower != LtfShiLower || OldLtfShiUpper != LtfShiUpper) && (OldLtfShiLower > 0 && OldLtfShiUpper > 0) )
   OldLtfShiLower = LtfShiLower;
   OldLtfShiUpper = LtfShiUpper;
   
   //Should open trades be closed?
   if (BasketUpl >= 0) LookForTradeClosure();
   
   //Look for trading opportunities
   if (!StopTrading)
   {
      LookForTradingOpportunities();
   }//if (!StopTrading)
   
   DisplayUserFeedback();
      

}
//+------------------------------------------------------------------+


