//+------------------------------------------------------------------+
//|     Steve Hopwood's Fib Target-level retracement auto-trader.mq4 |
//|                                  Copyright © 2009, Steve Hopwood |
//|                              http://www.hopwood3.freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Steve Hopwood"
#property link      "http://www.hopwood3.freeserve.co.uk"
#property show_inputs
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"
#define  up "Up"
#define  down "Down"
#define  none "None"
#define  reentrylinename "Re entry line"
#define  breakevenlinename "Break even line"

//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


/*



start()
void DisplayUserFeedback()
void CalculateTradeLevels()


----Fib----
void GetSwing()
void DrawFib()

----Trading----
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
bool TradingTimesCheck()
void LookForMultipleTradeOpps()
void LookForSingleTradeOpportunities()
bool CloseAllTrades()
bool CheckTradingRange()

----Trade direction module----
void ReadIndicatorValues()
void GetBB()
void GetSixths()
void GetStoch()
double GetStochMACD(int fast_ema_period, int slow_ema_period, int signal_period, int StochasticPeriod, int shift)
void GetTradeDirection()

----Rsi----
void ReadRsi()


----Trade management----
bool DoesTradeExist()
bool DeletePendingTrades()
bool DeleteLowerLevelPendingTrades()

----1.1.3.3 recovery module----
void RecoveryModule()
void CountOpenTrades()
void CheckRecoveryTakeProfit()
int Analyze()
int SymbolsIndex(string SymbolName)
void ModifyTakeProfit(double NewTake)
void AddReEntryLine(double price)



*/
extern string  gi="____General inputs----";
extern double  Lot=0.2;
extern int     DireEmergencyStopLossPips=0;
extern int     MagicNumber=0;
extern string  TradeComment="FTLR";
extern int     PendingPipsDistance=17;
extern color   FiboColour=Yellow;
extern bool    CriminalHasSundayCandle=true;
extern int     PipsAllowedBeyondT4=50;
extern bool    UseScoobsMarginCheck=false;
extern string  nbi="----Nanningbob Recovery----";
extern int     RecoveryCandleTF=15;
extern bool    Use1.1.3.3Recovery=false;
extern bool    Use2.4.2Recovery=false;
extern bool    Use1.2.4Recovery=true;
extern int     ReEntryLinePips=150;
extern color   ReEntryLineColour=Turquoise;
extern color   BreakEvenLineColour=Blue;
extern string  st="----Trigger level----";
extern bool    TradeLevelIsT1=true;
extern bool    TradeLevelIsT2=false;
extern bool    TradeLevelIsT3=false;
extern bool    TradeLevelIsT4=false;
extern string  tdf="----Trade direction finding----";
extern string  rsi="----Rsi----";
extern bool    UseRsi=false;
extern string  nb="----Sq_Steve direction finding module----";
extern bool    UseSqSteve=false;
extern string  six="Sixths inputs";
extern int     BarCount=120;
extern bool    TradeZoneA=true;
extern bool    TradeZoneB=true;
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 bool    SundayTradingAllowed=true;
extern string  mis="----Odds and ends----";
extern int     DisplayGapSize=30;
extern bool    ShowUserFeedback=true;
   

//Fib variables
double 			LongFibLevels[] = { 138.2, 161.8, 238.2, 261.8 };
double 			ShortFibLevels[] = { 38.2, 61.8, 138.2, 161.8 };
double         SwingHigh, SwingLow;
double         LongTargetLevel[4], ShortTargetLevel[4];

//6ths variables
double         BottomGoldLine;//Bottom, gold line
double         BottomGreenLine;//Bottom, green line
double         MiddleWhiteLine;//Middle, white line
double         TopGreenLine;//Top, green line
double         TopGoldLine;//Top, gold line

//Stoch variables
double         StochWhite;
double         StochBlue;

//Macd
double         MacdVal;

//BB variables
double         BbUpper, BbLower;

//Sq's stochmacd
int            FastEMA   =12;
int            SlowEMA   =26;
int            SignalSMA =9;
int            StochasticPeriod =120; //4 weeks of H4 bars = 4*5*24/4 = 120


//Trade direction
string         TradeDirection=none;

//1.1.3.3 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;

//Misc
int            OldBars, OpenTrades, OldRecoveryTfBars; 
int            TicketNo;//Holds the ticket number of the most recent open trade eg the last in a sequence of 3
int            NoOfTrades;
bool           RobotDisabled, ForceLowerDelete, ForceAllDelete, StopTrading;
string         Gap, DisabledMessage, ScreenMessage, GvHighName, GvLowName;
double         RsiVal, SendLots;
int            ChartShift = 1;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   
   //Reset ReEntryLinePips according to pair volatility. My thanks to Max for thisn
   if (ReEntryLinePips == 0)
   {
      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)
      
   
   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;   
   DireEmergencyStopLossPips*= multiplier;
   PendingPipsDistance*= multiplier;
   PipsAllowedBeyondT4*= multiplier;
   ReEntryLinePips*= multiplier;
   
   
//----
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   
   TpMoved = true;
    OldBars = 0;
    
    
    //start();

   
   return(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, "Lot size: ", SendLots, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "PendingPipsDistance: ", PendingPipsDistance, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "DireEmergencyStopLossPips: ", DireEmergencyStopLossPips, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Magic number: ", MagicNumber, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade comment: ", TradeComment, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade trigger is ");
   if (TradeLevelIsT1) ScreenMessage = StringConcatenate(ScreenMessage, "T1", NL);
   if (TradeLevelIsT2) ScreenMessage = StringConcatenate(ScreenMessage, "T2", NL);
   if (TradeLevelIsT3) ScreenMessage = StringConcatenate(ScreenMessage, "T3", NL);
   if (TradeLevelIsT4) ScreenMessage = StringConcatenate(ScreenMessage, "T4", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "PipsAllowedBeyondT4: ", PipsAllowedBeyondT4, NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading hours: ", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Start_hourm:  ", DoubleToStr(start_hourm, 2), NL );
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "End_hourm:  ", DoubleToStr(end_hourm, 2), NL );
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Start_houre:  ", DoubleToStr(start_houre, 2), NL );
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "End_houre:   ", DoubleToStr(end_houre, 2), NL, NL );
   if (SundayTradingAllowed) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Sunday trading is allowed", NL);
   else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Sunday trading is not allowed", NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trade direction: ", TradeDirection, NL);
   if (TimeDayOfWeek(TimeLocal()) == 0 && !SundayTradingAllowed) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not trading - Sunday", NL);
   
   /*ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Swing high: ", DoubleToStr(SwingHigh,Digits),NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Targets:", NL);
   for (int cc = ArraySize(LongFibLevels) - 1; cc >= 0; cc--)
   {
      ScreenMessage = StringConcatenate(ScreenMessage, Gap, "      T", cc + 1, ": ", DoubleToStr(LongTargetLevel[cc], Digits), NL);
   }//for (int cc = 0; cc < ArraySize(LongFibLevels); cc++)
   ScreenMessage = StringConcatenate(ScreenMessage,NL);
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Swing low: ", DoubleToStr(SwingLow,Digits),NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Targets:", NL);
   for (cc = 0; cc < ArraySize(ShortFibLevels); cc++)
   {
      ScreenMessage = StringConcatenate(ScreenMessage, Gap, "      T", cc + 1, ": ", DoubleToStr(ShortTargetLevel[cc], Digits), NL);
   }//for (cc = 0; cc < ArraySize(LongFibLevels); cc++)*/
   ScreenMessage = StringConcatenate(ScreenMessage,NL);

   ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Trade direction modules:", NL);
   if (UseRsi)
   {
      ReadRsi();
      ScreenMessage = StringConcatenate(ScreenMessage, Gap, "Using Rsi. Only use this on sub-W1 timeframes. Rsi = ", RsiVal, NL);
   }//if (UseRsi)
   
   if (UseSqSteve)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Using Sq_Steve trade direction finding module", NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "BB Upper line: ", DoubleToStr(BbUpper, Digits) );
      ScreenMessage = StringConcatenate(ScreenMessage, "  BB Lower line: ", DoubleToStr(BbLower, Digits), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Sixths: ", NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Top, gold line: ", DoubleToStr(TopGoldLine, Digits), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Top, green line: ", DoubleToStr(TopGreenLine, Digits), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Middle, white line: ", DoubleToStr(MiddleWhiteLine, Digits), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Bottom, gold line: ", DoubleToStr(BottomGoldLine, Digits), NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Bottom, green line: ", DoubleToStr(BottomGreenLine, Digits), NL);
      if (TradeZoneA) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading zone A (above top gold line and below bottom gold line)", NL);
      if (TradeZoneB) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Trading zone B (above top green line and below bottom green line)", NL);
   
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stochastic white line: ", StochWhite, NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stochastic blue line: ", StochBlue, NL);
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Macd red line: ", DoubleToStr(MacdVal, 4), NL);
  }//if (UseSqSteve) 
      
      
      Comment(ScreenMessage);

}//void DisplayUserFeedback()



//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
   
//----
   return(0);
}

void DrawFib()
{

      if (IsTesting() && !IsVisualMode()) return;

      double HighPrice, LowPrice;
      datetime OpenTime, CloseTime;
      string tf;
      
      HighPrice = iHigh(NULL, 0, ChartShift);
      OpenTime = iTime(NULL, 0, ChartShift);
      LowPrice = iLow(NULL, 0, ChartShift);
      CloseTime = iTime(NULL, 0, ChartShift);
         
      
            
      
            
      ObjectCreate("Fibo",OBJ_FIBO,0,OpenTime,HighPrice,CloseTime,LowPrice);
      ObjectSet("Fibo", OBJPROP_STYLE, STYLE_DASH);
      ObjectSet("Fibo", OBJPROP_COLOR, FiboColour);
      ObjectSet("Fibo", OBJPROP_LEVELCOLOR, FiboColour);
      ObjectSet("Fibo", OBJPROP_WIDTH, 1);
      ObjectSet("Fibo", OBJPROP_FIBOLEVELS, 17);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+0, 0);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+1, 100);
      
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+0, -0.618);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+1, -0.382);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+2, 0);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+3, 0.191);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+4, 0.382);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+5, 0.50);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+6, 0.618);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+7, 0.809);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+8, 1);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+9, 1.382);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+10, 1.618);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+11, 2.382);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+12, 2.618);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+13, -1.382);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+14, -1.618);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+15, 2);
      ObjectSet("Fibo", OBJPROP_FIRSTLEVEL+16, -1);
      
      ObjectSetFiboDescription("Fibo", 0, "Fibo" + " T2 (-61)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 1, "Fibo" + " T1 (-38)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 2, "Fibo" + " Low (0)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 3, "Fibo" + " S1 (19.1)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 4, "Fibo" + " Sell (38.2)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 5, "Fibo" + " Pivot (50)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 6, "Fibo" + " Buy (61.8)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 7, "Fibo" + " R1 (80.9)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 8, "Fibo" + " High (100)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 9, "Fibo" + " T1 (138)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 10, "Fibo" + " T2 (161)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 11, "Fibo" + " T3 (238)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 12, "Fibo" + " T4 (261)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 13, "Fibo" + " T3 (-138)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 14, "Fibo" + " T4 (-161)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 15, "Fibo" + "  (200)"+ "  %$");
      ObjectSetFiboDescription("Fibo", 16, "Fibo" + "  (-100)"+ "  %$");
      

}//End void DrawFib()


bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
{
   
   
   if (!IsTradeAllowed() ) return(false);
   
   
   color col = Red;
   if (type == OP_BUYSTOP) col = Green;
   
   int ticket = OrderSend(Symbol(),type, lotsize, price, 0, stop, take, comment, MagicNumber, 0, col);   
   if (ticket < 0)
   {
      string stype;
      if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
      if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
      if (type == OP_BUY) stype = "OP_BUY";
      if (type == OP_SELL) stype = "OP_SELL";
      int err=GetLastError();
      //Alert(Symbol(), " ", stype," Simone fib order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," Fib level rejection order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   
   //Trade send has succeeded, so draw re-entry line
   double ReEntryPrice;
   if (type == OP_BUYSTOP) 
   {      
      if (TradeLevelIsT1 || TradeLevelIsT2) ReEntryPrice = ShortTargetLevel[3];
      if (TradeLevelIsT3 || TradeLevelIsT4) ReEntryPrice = NormalizeDouble(price - (ReEntryLinePips * Point) , Digits);
      if (Ask < ReEntryPrice) ReEntryPrice = NormalizeDouble(Ask - (ReEntryLinePips * Point), Digits);
   }//if (type == OP_BUYSTOP) 
   
   if (type == OP_SELLSTOP) 
   {
      if (TradeLevelIsT1 || TradeLevelIsT2) ReEntryPrice = LongTargetLevel[3];
      if (TradeLevelIsT3 || TradeLevelIsT4) ReEntryPrice = NormalizeDouble(price + (ReEntryLinePips * Point) , Digits);
      if (Bid > ReEntryPrice) ReEntryPrice = NormalizeDouble(Bid + (ReEntryLinePips * Point), Digits);
   }//if (type == OP_SELLSTOP)    
   AddReEntryLine(ReEntryPrice);
   
   OpenTrades++;
   Sleep(60000);

   return(true);
   
}//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)

bool DoesTradeExist()
{
   TicketNo = 0;
   if (OrdersTotal() == 0) return(false);
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
         TicketNo = OrderTicket();//Tells the robot which is the most recent trade in a sequence
         return (true);
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() == 0)      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   return(false);
   
}//bool DoesTradeExist()

void GetSwing()
{

   //Calculate the shift on the D1 if today is Monday, to leave out the Sunday candle
   if (Period() == PERIOD_D1 && DayOfWeek() == 1 && CriminalHasSundayCandle)
   {
      ChartShift = 2;
   }//if (Period() == PERIOD_D1)
   else ChartShift = 1;
   
   SwingHigh = High[ChartShift];
   SwingLow = Low[ChartShift];
   

    
   CalculateTradeLevels();
   
   
   
}//void GetSwing()


void CalculateTradeLevels()
{
   
   double extent = SwingHigh - SwingLow;
   
   
   for (int cc = 0; cc < ArraySize(LongFibLevels); cc++)
   {
      LongTargetLevel[cc] = NormalizeDouble(SwingLow + (extent * LongFibLevels[cc] / 100), Digits);            
   }//for (int cc = 0; cc < ArraySize(LongFibLevels); cc++)
            
   for (cc = 0; cc < ArraySize(ShortFibLevels); cc++)
   {
      ShortTargetLevel[cc] = NormalizeDouble(SwingLow - (extent * ShortFibLevels[cc] / 100), Digits);            
   }//for (cc = 0; cc <= ArraySize(ShortFibLevels); cc++)
   
}//End void CalculateTradeLevels()

bool TradingTimesCheck()
{

      //Trading times
   int hour = TimeHour(TimeLocal() );
   
   if (end_hourm < start_hourm)
	{
		end_hourm += 24;
	}
	

	if (end_houre < start_houre)
	{
		end_houre += 24;
	}
	
	bool 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))
   {      
      return(false);
   }//if (hour >= MathMax(end_hourm, end_houre))

   return(true);

}//End bool TradingTimesCheck()

void ReadRsi()
{

   RsiVal = iRSI(NULL, PERIOD_D1, 14, PRICE_CLOSE, 0);

}//End void ReadRsi()

/*
void LookForMultipleTradeOpps()
{

   bool OutOfRange = CheckTradingRange();
   if (OutOfRange) return;
   
   if (UseSqSteve)
   {
      GetTradeDirection();
      if (TradeDirection == none) return;
   }//UseSqSteve
   
   bool SendTrade = true;
   bool TradeExists = false;
   double stop, LotSize;

   //Short
   if (Ask < LongTargetLevel[0] && Ask > ShortTargetLevel[0]) SendTrade = false;//Not in the trading zone
   
   if (Ask > LongTargetLevel[0])
   {
      if (UseSqSteve  && TradeDirection != down) return;
      
      TradeExists = DoesTradeExist();
            
      for (int cc = 0; cc < ArraySize(LongFibLevels); cc++)
      {
         double target = LongTargetLevel[cc];
         if (Ask > target && Open[0] < target)
         {
            //Does trade exist selects an open current trade selected.
            //If the trade lot size = Lot * cc + t, then the trade has already been sent
            if (TradeExists)
            {
               if (OrderLots() >= Lot * (cc + 1) )
               {
                  SendTrade = false;
               }//if (OrderLots() == Lot * cc)            
            }//if (TradeExists)
         
            //Rsi check
            if (UseRsi)
            {
               ReadRsi();
               if (RsiVal > 55) SendTrade = false;
            }//if (UseRsi)
         
            //If trade needs sending, then delete the existing trade
            if (SendTrade)
            {            
               stop = NormalizeDouble(LongTargetLevel[3] + (DireEmergencyStopLossPips * Point), Digits);
               if (DireEmergencyStopLossPips == 0) stop = 0;
               LotSize = Lot;
               if (AllowLotIncrements) LotSize = Lot * (cc + 1);
               SendSingleTrade(OP_SELLSTOP, TradeComment, LotSize, NormalizeDouble(Bid - (PendingPipsDistance * Point), Digits), 0, SwingHigh);
            }//if (SendTrade)
         
         
         }//if (Ask > target && Open(0) < target)
      
      }//for (int cc = 0; cc < ArraySize(LongFibLevels); cc++)
   }//if (Ask > LongTargetLevel[0])            
   SendTrade = true;
   TradeExists = false;

   //Long
   if (Bid < LongTargetLevel[0] && Bid > ShortTargetLevel[0]) SendTrade = false;//Not in the trading zone
   
   if (Bid < ShortTargetLevel[0])
   {
      if (UseSqSteve  && TradeDirection != up) return;
      
      TradeExists = DoesTradeExist();   
   
      for (cc = 0; cc < ArraySize(ShortFibLevels); cc++)
      {
         target = ShortTargetLevel[cc];
         if (Bid < target && Open[0] > target)
         {
            //Does trade exist selects an open current trade
            //If the trade lot size = Lot * cc + t, then the trade has already been sent
            if (TradeExists)
            {
               if (OrderLots() >= Lot * (cc + 1) )
               {
                  SendTrade = false;
               }//if (OrderLots() == Lot * cc)            
            }//if (TradeExists)
         
            //Rsi check
            if (UseRsi)
            {
               ReadRsi();
               if (RsiVal < 45) SendTrade = false;
            }//if (UseRsi)

            if (SendTrade)
            {
               stop = NormalizeDouble(ShortTargetLevel[3] - (DireEmergencyStopLossPips * Point), Digits);
               if (DireEmergencyStopLossPips == 0) stop = 0;
               LotSize = Lot;
               if (AllowLotIncrements) LotSize = Lot * (cc + 1);
               SendSingleTrade(OP_BUYSTOP, TradeComment, LotSize, NormalizeDouble(Ask + (PendingPipsDistance * Point), Digits), 0, SwingLow);
            }//if (SendTrade)
         
         
         }//if (Bid < target && Open[0] > target)
      
      }//for (int cc = 0; cc < ArraySize(LongFibLevels); cc++)
   }//if (Bid < ShortTargetLevel[0])      


}//End void LookForMultipleTradeOpps()
*/
void LookForSingleTradeOpportunities()
{

   if (DoesTradeExist() ) return;
   
   bool OutOfRange = CheckTradingRange();
   if (OutOfRange) return;

   if (UseSqSteve)
   {
      GetTradeDirection();
      if (TradeDirection == none) return;
   }//UseSqSteve

   bool SendTrade = true;
   double stop;
   int ap;//Array pointer
   
   if (TradeLevelIsT1) ap = 0;
   if (TradeLevelIsT2) ap = 1;
   if (TradeLevelIsT3) ap = 2;
   if (TradeLevelIsT4) ap = 3;
   
   //Short
   if (Ask < LongTargetLevel[ap] && Ask > ShortTargetLevel[ap]) return;//Not in the trading zone
   
   if (Ask > LongTargetLevel[ap])
   {
      if (UseSqSteve  && TradeDirection != down) return;
      
   
      double target = LongTargetLevel[ap];
      if (Ask > target && Open[0] < target)
      {
      
         //Rsi check
         if (UseRsi)
         {
            ReadRsi();
            if (RsiVal > 55) return;
         }//if (UseRsi)
      
         //If trade needs sending, then delete the existing trade
         if (SendTrade)
         {            
            stop = NormalizeDouble(LongTargetLevel[3] + (DireEmergencyStopLossPips * Point), Digits);
            if (DireEmergencyStopLossPips == 0) stop = 0;
            SendSingleTrade(OP_SELLSTOP, TradeComment, SendLots, NormalizeDouble(Bid - (PendingPipsDistance * Point), Digits), 0, SwingHigh);
         }//if (SendTrade)    
      
      }//if (Ask > target && Open(0) < target)
   }//if (Ask > LongTargetLevel[0])      
      
            
   SendTrade = true;
   
   //Long
   if (Bid < LongTargetLevel[ap] && Bid > ShortTargetLevel[ap]) return;//Not in the trading zone
   
   if (Bid < ShortTargetLevel[ap])
   {
      if (UseSqSteve  && TradeDirection != up) return;
      
   
      target = ShortTargetLevel[ap];
      if (Bid < target && Open[0] > target)
      {
      
         //Rsi check
         if (UseRsi)
         {
            ReadRsi();
            if (RsiVal < 45) return;
         }//if (UseRsi)

         if (SendTrade)
         {
            stop = NormalizeDouble(ShortTargetLevel[3] - (DireEmergencyStopLossPips * Point), Digits);
            if (DireEmergencyStopLossPips == 0) stop = 0;
            SendSingleTrade(OP_BUYSTOP, TradeComment, SendLots, NormalizeDouble(Ask + (PendingPipsDistance * Point), Digits), 0, SwingLow);
         }//if (SendTrade)
           
      }//if (Bid < target && Open[0] > target)
   }//if (Bid < ShortTargetLevel[0])      
      


}//End void LookForSingleTradeOpportunities()


bool CloseAllTrades()
{
   //Closes all open trades at the start of a new candle
   bool DeleteSuccess = true;
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
         bool result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 1000, CLR_NONE);
         if (result) cc++;
         if (!result) DeleteSuccess = false;
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() == 0)      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   return(DeleteSuccess);


}//End bool CloseAllTrades()

bool DeletePendingTrades()
{
   if (OrdersTotal() == 0) return(false);
   bool failed = false;
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) )
      {
         int t = OrderTicket();
         bool result = OrderDelete(t);
         if (result) cc++;
         if (!result) failed = true;
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() == 0)      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   return(failed);
   
}//End bool DeletePendingTrades()

bool DeleteLowerLevelPendingTrades()
{
   if (OrdersTotal() == 0) return(false);
   bool failed = false;
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && (OrderType() == OP_BUYSTOP || OrderType() == OP_SELLSTOP) )
      {
         int t = OrderTicket();
         if (t != TicketNo)
         {
            bool result = OrderDelete(t);
            if (result) cc++;
            if (!result) failed = true;
         }//if (t != TicketNo)
            
      }//if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderCloseTime() == 0)      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   return(failed);
   
}//bool DeleteLowerLevelPendingTrades()

bool CheckTradingRange()
{
   //Returns true if the market is out of range, and false if market is within the tradable range
   
   double RangeHigh = NormalizeDouble(LongTargetLevel[3] + (PipsAllowedBeyondT4 * Point), Digits);
   double RangeLow = NormalizeDouble(ShortTargetLevel[3] - (PipsAllowedBeyondT4 * Point), Digits);
   
   if (Ask > RangeHigh || Bid < RangeLow) 
   {
      ForceAllDelete = DeletePendingTrades();
      return(true);
   }//if (Ask > RangeHigh || Bid < RangeLow) 
   
   return(false);
   
}//End bool CheckTradingRange()

void GetSixths()
{
   /*
   These are declared in the general section and count the lines from the bottom upwards
   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 value = WindowPriceMax(0)-WindowPriceMin(0);      //value top of the chart - value buttem
   double value = High[iHighest(NULL,0,MODE_HIGH,BarCount,1)] - Low[iLowest(NULL,0,MODE_LOW,BarCount,1)];      //value top of the chart - value bottom
   double sixth = value/6;
   double valueS = (value*(MathPow(10,Digits)));
   double sixthS = (sixth*(MathPow(10,Digits)));
   
   BottomGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth, Digits);
   BottomGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth, Digits);
   MiddleWhiteLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth, Digits);
   TopGreenLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth, Digits);
   TopGoldLine = NormalizeDouble(Low[iLowest(NULL,0,MODE_LOW,BarCount,1)]+sixth+sixth+sixth+sixth+sixth, Digits);



}//End void GetSixths()


void GetStoch()
{

   StochWhite = iStochastic(NULL, 0, 7, 3, 3, MODE_LWMA, 1, MODE_MAIN, 0);
   StochBlue = iStochastic(NULL, 0, 14, 3, 5, MODE_LWMA, 1, MODE_MAIN, 0);
   

}//void GetStoch();

double GetStochMACD(int fast_ema_period, int slow_ema_period, int signal_period, int StochasticPeriod, int shift)
{
  // get macd signal line
  double macdSignal;
  int j;
  // get highest/lowest of macdSignal over StochasticPeriod
  double ll = 100000, hh = -100000, dif;
  for(j=shift; j<shift+StochasticPeriod; j++)
  {
    macdSignal = iMACD(NULL,0,fast_ema_period, slow_ema_period, signal_period, PRICE_CLOSE,MODE_SIGNAL,j);
    hh = MathMax(hh,macdSignal);
    ll = MathMin(ll,macdSignal);
  }

  // normalize to 0..100

  dif = hh-ll;
  if (dif==0) return (0);
  else return (100 * (iMACD(NULL,0,fast_ema_period, slow_ema_period, signal_period, PRICE_CLOSE,MODE_SIGNAL,shift)-ll)/dif); 
}//End double GetStochMACD(int fast_ema_period, int slow_ema_period, int signal_period, int StochasticPeriod, int shift)

void GetBB()
{
   //Reads BB figures into BbUpper, BbLower
   
   
   BbUpper = iBands(NULL, 0, 25, 2, 0, PRICE_CLOSE, MODE_UPPER, 0);
   BbLower = iBands(NULL, 0, 25, 2, 0, PRICE_CLOSE, MODE_LOWER, 0);
   
}//void GetBb()


void ReadIndicatorValues()
{

   GetBB();
   GetSixths();
   GetStoch();
   MacdVal = GetStochMACD(FastEMA, SlowEMA, SignalSMA, StochasticPeriod , 0);

}//End void ReadIndicatorValues()


void GetTradeDirection()
{
   
   //Is market in the killing zone
   if (Ask <= TopGreenLine && Ask >= BottomGreenLine && Bid <= TopGreenLine && Bid >= BottomGreenLine)
   {
      TradeDirection = none;
      return;
   }//if (Ask <= TopGreenLine && Ask >= BottomGreenLine Bid <= TopGreenLine && Bid >= BottomGreenLine)
   
   ReadIndicatorValues();
   
   if (TradeZoneA) double target = TopGoldLine;
   if (TradeZoneB) target = TopGreenLine;
   
   
   //Check for short direction trade setup
   if (Ask > target)
   {
      TradeDirection = down;
      if (StochBlue < 85) TradeDirection = none;
      //if (StochWhite > StochBlue) TradeDirection = none;
      if (MacdVal < 85) TradeDirection = none;
      if (BbUpper < TopGreenLine) TradeDirection = none;  
   }//if (Ask > TopGoldLine)

   if (TradeZoneA) target = BottomGoldLine;
   if (TradeZoneB) target = BottomGreenLine;

   //Check for short direction trade setup
   if (Bid < target)
   {
      TradeDirection = up;
      if (StochBlue > 15 ) TradeDirection = none;
      //if (StochWhite < StochBlue) TradeDirection = none;
      if (MacdVal > 15 ) TradeDirection = none;
      if (BbLower > BottomGreenLine) TradeDirection = none;
   }//if (Ask > TopGoldLine)



}//End void GetTradeDirection()

////////////////////////////////////////////////////////////////////////////////////////////////
//1.1.3.3 RECOVERY MODULE updated from the 1.1.3.3 mode
void RecoveryModule()
{
   if (OldRecoveryTfBars == iBars(Symbol(), RecoveryCandleTF) ) return;
   
   //My thanks to sundog for coding the change to 1.1.3.3
    //Check that recovery is necessary
   double TargetPrice = ObjectGet(reentrylinename, OBJPROP_PRICE1); 
   
   if (OrderType() == OP_BUY)
   {
      if (Ask > TargetPrice) return;
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELL)
   {
      if (Bid < TargetPrice) return;
   }//if (OrderType() == OP_SELL)
   
   
   /*
   Users can choose which of the recovery strategies to use.
   extern bool    Use1.1.3.3Recovery=true;
   extern bool    Use2.4.2Recovery=false;
   extern bool    Use1.2.4Recovery=false;
   */

   //If 1 trade open, then recovery is at the 1 stage
   if (OpenTrades == 1)
   {
      //SendMagicNumber = MagicNumber + 30;
      SendLots = Lot * 1;
      if (Use2.4.2Recovery) SendLots = Lot * 2;
      string comment = "L2";
   }//if (OpenTrades == 1)
   
   
   //If 2 trades open, then recovery is at the 3 stage
   if (OpenTrades == 2)
   {
      //SendMagicNumber = MagicNumber + 60;
      if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      if (Use2.4.2Recovery) SendLots = Lot * 4;
      if (Use1.2.4Recovery) SendLots = Lot * 2;
      comment = "L3";
   }//if (OpenTrades == 2)
   
   //If 3 trades open, then recovery is at the sedond 3  stage
   if (OpenTrades == 3)
   {
      //SendMagicNumber = MagicNumber + 90;
      if (Use1.1.3.3Recovery) SendLots = Lot * 3;
      if (Use2.4.2Recovery) SendLots = Lot * 2;
      if (Use1.2.4Recovery) SendLots = Lot * 4;
      comment = "L4";
   }//if (OpenTrades == 3)
   
   //Stop trading if the full 4-trade position is open
   if (OpenTrades == 4)
   {
      StopTrading = true;
   }//if (OpenTrades == 4)

   RecoveryInProgress = true;
   
   if (OpenTrades < 4)
   {
      int PrevOpenTrades = OpenTrades;
      double ReEntryLinePrice;
      double price;
      
      RefreshRates();
      //Buy
      if (OrderType() == OP_BUY && Low[0] <= TargetPrice && Ask > Open[0])
      {
         price = Ask;
         bool result = SendSingleTrade(OP_BUY, comment, SendLots, price, 0, 0);
         if (result) ReEntryLinePrice = NormalizeDouble(price - (ReEntryLinePips * Point), Digits);
      }//if (OrderType() == OP_BUY && Low[0] <= TargetPrice && Ask > Open[0])
   
      //Sell
      if (OrderType() == OP_SELL && High[0] >= TargetPrice && Bid < Open[0])
      {
         price = Bid;
         result = SendSingleTrade(OP_SELL, comment, SendLots, price, 0, 0);
         if (result) ReEntryLinePrice = NormalizeDouble(price + (ReEntryLinePips * Point), Digits);
      }//if (OrderType() == OP_SELL && High[0] >= TargetPrice && Bid < Open[0])
      if (result) OldRecoveryTfBars = iBars(Symbol(), RecoveryCandleTF);
   }//if (OpenTrades < 4)
   
   if (OpenTrades > PrevOpenTrades)
   {
      ObjectDelete(reentrylinename);
      AddReEntryLine(ReEntryLinePrice);
      TpMoved = false;
   }//if (OpenTrades > PrevOpenTrades)
   

}//End void RecoveryModule()

void CountOpenTrades()
{
   OpenTrades = 0;
   TicketNo = 0;

   if (OrdersTotal() == 0) return;
   
   double BreakevenPrice;
   
   for (int cc = 0; cc <= OrdersTotal(); cc++)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;
      //if (OrderSymbol() == Symbol() && (OrderType() == OP_BUY || OrderType() == OP_SELL) )
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
      {
         OpenTrades++;
         TicketNo = OrderTicket();
                  //Check for a break even line move
         if (RecoveryInProgress)
         {
            if (ObjectFind(breakevenlinename) > -1)
            {
               double take = ObjectGet(breakevenlinename, OBJPROP_PRICE1);
               if (OrderTakeProfit() != take)
               {
                  OrderModify(TicketNo, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
               }//if (OrderTakeProfit() != ObjectGet(breakevenlinename, OBJPROP_PRICE1) )
            }//if (ObjectFind(breakevenlinename) > -1)
            if (ObjectFind(breakevenlinename) == -1)
            {
               ObjectCreate(breakevenlinename,OBJ_HLINE,0,TimeCurrent(),OrderTakeProfit());
               ObjectSet(breakevenlinename,OBJPROP_COLOR,BreakEvenLineColour);
               ObjectSet(breakevenlinename,OBJPROP_STYLE,STYLE_SOLID);
               ObjectSet(breakevenlinename,OBJPROP_WIDTH,2);     
            }//if (ObjectFind(breakevenlinename) == -1)
   
            //Create reentry line if one does not exist already - perhaps because of accidental deletion
            if (ObjectFind(reentrylinename) == -1)
            {
               if (OrderType() == OP_BUY) AddReEntryLine(NormalizeDouble(OrderOpenPrice() - (ReEntryLinePips * Point), Digits) );
               if (OrderType() == OP_SELL) AddReEntryLine(NormalizeDouble(OrderOpenPrice() + (ReEntryLinePips * Point), Digits) );
            }//if (ObjectFind(reentrylinename) == -1)
            
         }//if (RecoveryInProgress)
   

      }//if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
   }//for (int cc = 0; cc < OrdersTotal() - 1; cc++)
   
   
}//End void CountOpenTrades();

void ModifyTakeProfit(double NewTake)
{
   if (NewTake == 0) return;
   TpMoved = true;
   
   for (int cc = OrdersTotal() -1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS) ) continue;      
      if (OrderSymbol() == Symbol() && OrderTakeProfit() != NewTake)
      {
         bool result = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), NewTake, OrderExpiration(), CLR_NONE);
         if (!result) TpMoved = false;
      }//if (OrderTakeProfit() != NewTake) 
   
   }//for (int cc = OrdersTotal() -1; cc >= 0; cc--)
   
   ObjectDelete(breakevenlinename);
   ObjectCreate(breakevenlinename,OBJ_HLINE,0,TimeCurrent(), NewTake);
   ObjectSet(breakevenlinename,OBJPROP_COLOR,BreakEvenLineColour);
   ObjectSet(breakevenlinename,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(breakevenlinename,OBJPROP_WIDTH,2);     


}//End void ModifyTakeProfit(double NewTake);

void CheckRecoveryTakeProfit()
{
   //This is adapted from the NB iExposure indicator. I do not understand how it works.
   //There will be redundant code, so anybody wishing to clear it up is most welcome to do so.
   
   ExtLines = 0;
   int    i,col,line;

   ArrayInitialize(ExtSymbolsSummaries,0.0);
   int total=Analyze();
   if(total>0)
   {
      line=0;
      for(i=0; i<ExtSymbolsTotal; i++)
      {
         if (ExtSymbols[i] != Symbol() ) continue;
         if(ExtSymbolsSummaries[i][DEALS]<=0) continue;
         line++;
         //---- add line
         if(line>ExtLines)
         {
            int y_dist=ExtVertShift*(line+1)+1;
            /*for(col=0; col<8; col++)
              {
               name="Line_"+line+"_"+col;
               if(ObjectCreate(name,OBJ_LABEL,windex,0,0))
                 {
                  ObjectSet(name,OBJPROP_XDISTANCE,ExtShifts[col]);
                  ObjectSet(name,OBJPROP_YDISTANCE,y_dist);
                 }
              }*/
            ExtLines++;
         }//if(line>ExtLines)
         //---- set line
         //color  price_colour;//Steve mod
         int    digits=MarketInfo(ExtSymbols[i],MODE_DIGITS);
         double buy_lots=ExtSymbolsSummaries[i][BUY_LOTS];
         double sell_lots=ExtSymbolsSummaries[i][SELL_LOTS];
         if(buy_lots!=0)  buy_price=NormalizeDouble(ExtSymbolsSummaries[i][BUY_PRICE]/buy_lots, Digits);
         if(sell_lots!=0) sell_price=NormalizeDouble(ExtSymbolsSummaries[i][SELL_PRICE]/sell_lots, Digits);
         
      }//for(i=0; i<ExtSymbolsTotal; i++)
   }//if(total>0)


}//End void CheckRecoveryTakeProfit()

int Analyze()
{
   double profit;
   int    i,index,type,total=OrdersTotal();
//----
   for(i=0; i<total; i++)
     {
      if(!OrderSelect(i,SELECT_BY_POS)) continue;
      type=OrderType();
      if(type!=OP_BUY && type!=OP_SELL) continue;
      index=SymbolsIndex(OrderSymbol());
      if(index<0 || index>=SYMBOLS_MAX) continue;
      //----
      ExtSymbolsSummaries[index][DEALS]++;
      profit=OrderProfit()+OrderCommission()+OrderSwap();
      ExtSymbolsSummaries[index][PROFIT]+=profit;
      if(type==OP_BUY)
        {
         ExtSymbolsSummaries[index][BUY_LOTS]+=OrderLots();
         ExtSymbolsSummaries[index][BUY_PRICE]+=OrderOpenPrice()*OrderLots();
        }
      else
        {
         ExtSymbolsSummaries[index][SELL_LOTS]+=OrderLots();
         ExtSymbolsSummaries[index][SELL_PRICE]+=OrderOpenPrice()*OrderLots();
        }
     }
//----
   total=0;
   for(i=0; i<ExtSymbolsTotal; i++)
     {
      if(ExtSymbolsSummaries[i][DEALS]>0) total++;
     }
//----
   return(total);
}//int Analyze()

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int SymbolsIndex(string SymbolName)
{
   bool found=false;
//----
   for(int i=0; i<ExtSymbolsTotal; i++)
     {
      if(SymbolName==ExtSymbols[i])
        {
         found=true;
         break;
        }
     }
//----
   if(found) return(i);
   if(ExtSymbolsTotal>=SYMBOLS_MAX) return(-1);
//----
   i=ExtSymbolsTotal;
   ExtSymbolsTotal++;
   ExtSymbols[i]=SymbolName;
   ExtSymbolsSummaries[i][DEALS]=0;
   ExtSymbolsSummaries[i][BUY_LOTS]=0;
   ExtSymbolsSummaries[i][BUY_PRICE]=0;
   ExtSymbolsSummaries[i][SELL_LOTS]=0;
   ExtSymbolsSummaries[i][SELL_PRICE]=0;
   ExtSymbolsSummaries[i][NET_LOTS]=0;
   ExtSymbolsSummaries[i][PROFIT]=0;
//----
   return(i);
}//End int SymbolsIndex(string SymbolName)


//END 1.1.3.3 RECOVERY MODULE
////////////////////////////////////////////////////////////////////////////////////////////////

void AddReEntryLine(double price)
{
      if (ObjectFind(reentrylinename) > -1) ObjectDelete(reentrylinename);   
      
      
      if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
      {
         int err=GetLastError();      
         Alert("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
         Print("Re-entry line draw failed with error(",err,"): ",ErrorDescription(err));
         return(0);

      }//if (!ObjectCreate(reentrylinename,OBJ_HLINE,0,TimeCurrent(),price) )
      
      ObjectSet(reentrylinename,OBJPROP_COLOR,ReEntryLineColour);
      ObjectSet(reentrylinename,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(reentrylinename,OBJPROP_WIDTH,2);     

      



}//void AddReEntryLine(int type, double price)

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----


   if(OldBars != Bars) 
   {
      ObjectDelete("Fibo");
      GetSwing();
      DrawFib();
      OldBars = Bars;
      if (OrdersTotal() > 0 && Period() > PERIOD_D1)
      {
         bool CloseAll = CloseAllTrades();
         if (!CloseAll) OldBars = 0;
      }//if (OrdersTotal() > 0)
      ForceAllDelete = DeletePendingTrades();
         
   }//if(OldBars != Bars && NoOfTrades == 0) 

   
   if (RobotDisabled )
   {
      Comment("The robot has been suspended. Reason: ", DisabledMessage);
      return;
   }//if (RobotDisabled )
 
   //In case of deletion failure of lower level pendings
   if (ForceLowerDelete) ForceLowerDelete = DeleteLowerLevelPendingTrades();
   
   //In case of deletion failure of all pendings
   if (ForceAllDelete) ForceAllDelete = DeletePendingTrades();
   
      //1.1.3.3 recovery   
   CountOpenTrades();      
   if (TicketNo > 0) OrderSelect(TicketNo, SELECT_BY_TICKET);
   if (OpenTrades > 1) RecoveryInProgress = true;
   if (OpenTrades == 0) 
   {
      TicketNo = 0;
      RecoveryInProgress = false;
      TpMoved = true;
      SendLots = Lot;
      StopTrading = false;
      ObjectDelete(reentrylinename);
      ObjectDelete(breakevenlinename);
      
      //SendMagicNumber = MagicNumber;
   }//if (OpenTrades == 0) 
   
   OrderSelect(TicketNo, SELECT_BY_TICKET);
   if (OrderProfit() < 0 && (Use1.1.3.3Recovery || Use2.4.2Recovery || Use1.2.4Recovery) )
   {
      RecoveryModule();
      if (OrderTakeProfit() == 0) TpMoved = false;
   }//if (OrderProfit() < 0 && (Use1.1.3.3Recovery || Use2.4.2Recovery || Use1.2.4Recovery) )
      
   //if (RecoveryInProgress && !TpMoved)
   if (!TpMoved)
   {
      buy_price = 0;
      sell_price = 0;
      CheckRecoveryTakeProfit();
      double recovery_profit;
      if (buy_price > 0) 
      {
         recovery_profit = buy_price;
         if (Use1.2.4Recovery)
         {
            if (buy_price < BottomGoldLine) recovery_profit = BottomGoldLine;
         }//if (Use1.2.4Recovery)
         ModifyTakeProfit(recovery_profit);
      }//if (buy_price > 0) 
      
      if (sell_price > 0) 
      {
         recovery_profit = sell_price;
         if (Use1.2.4Recovery)
         {
            if (sell_price > TopGoldLine) recovery_profit = TopGoldLine;
         }//if (Use1.2.4Recovery)
         ModifyTakeProfit(sell_price);
      }//if (sell_price > 0) 
      //if (ObjectFind(breakevenlinename) == -1)
      //{
         ObjectCreate(breakevenlinename,OBJ_HLINE,0,TimeCurrent(),recovery_profit);
         ObjectSet(breakevenlinename,OBJPROP_COLOR,BreakEvenLineColour);
         ObjectSet(breakevenlinename,OBJPROP_STYLE,STYLE_SOLID);
         ObjectSet(breakevenlinename,OBJPROP_WIDTH,2);     
      //}//if (ObjectFind(breakevenlinename) == -1)
   }//if (RecoveryInProgress)
   

   
   

   //Check trading hours
   bool TradeHours = TradingTimesCheck();
   if (!TradeHours)
   {
      Comment("Outside trading hours\nstart_hourm-end_hourm: ", start_hourm, "-",end_hourm, "\nstart_houre-end_houre: ", start_houre, "-",end_houre);
      if (OrdersTotal() > 0 && Period() < PERIOD_W1) ForceAllDelete = DeletePendingTrades();
      return;
   }//if (hour < start_hourm)
   
   //Sunday candle
   if (TimeDayOfWeek(TimeLocal()) == 0 && !SundayTradingAllowed) 
   {
      if (ShowUserFeedback) 
      {   
         GetTradeDirection();
         DisplayUserFeedback();
      }//if (ShowUserFeedback) 
      
      return;
   }//if (TimeDayOfWeek(TimeLocal()) == 0) 
   
   //Look for trading opportunities
   /*
   if (!OnlyAllowSingleTrade) 
   {
      LookForMultipleTradeOpps();
      if (DeleteLowerLevelPendings && NoOfTrades > 1)
      {
         ForceLowerDelete = DeleteLowerLevelPendingTrades();
      }//if (DeleteLowerLevelPendings && NoOfTrades > 1)
      
   }//if (!OnlyAllowSingleTrade) 
   
   if (OnlyAllowSingleTrade) LookForSingleTradeOpportunities();
   */
   //Beyond trading range check
   
   if (OpenTrades > 0)
   {
      if (ShowUserFeedback) DisplayUserFeedback();
      return;
   }//if (OpenTrades > 1)
   
   if (UseScoobsMarginCheck)
   {
      if(AccountMargin() > (AccountFreeMargin()/100)) return;   
   }//if (UseScoobsMarginCheck)

   
   LookForSingleTradeOpportunities();
   if (NoOfTrades > 0) ForceAllDelete = CheckTradingRange();

   if (ShowUserFeedback) DisplayUserFeedback();
   
   
//----
   return(0);
}
//+------------------------------------------------------------------+5


