//+------------------------------------------------------------------+
//|     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"

/*



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()


·	Target levels refer to the Tx levels shown by my complex fib - see the Fib variable a bit lower down for details.
·	This robot takes trades based on the bounce off these levels. Therefore, long target levels refer to
	Long T1 etc. When the market crosses these boundaries, the robot will trade short to take advantabe
	of the extremes of market movement. Vice versa for long trades - market will have crossed Short T1 etc
·	Trades are pending orders at PendingPipsDistance from market.
·	Open trades are closed at the start of each new candle from W1 upwards - there will be a new fib so the open trades 
   are based on fib levels that no longer apply. Unfilled pendings are deleted at the end of trading hours 
   if trading less than W1.
·	This robot will work best on high timeframes - D1 is the lowest.

*/
extern string  gi="____General inputs----";
extern double  Lot=0.2;
extern int     DireEmergencyStopLossPips=10000;
extern int     MagicNumber=0;
extern string  TradeComment="";
extern int     PendingPipsDistance=170;
extern color   FiboColour=Yellow;
extern bool    CriminalHasSundayCandle=true;
extern string  mti="----Multi-trade inputs----";
extern bool    DeleteLowerLevelPendings=true;
extern bool    AllowLotIncrements=false;
extern int     PipsAllowedBeyondT4=500;
extern string  st="----Single trade inputs----";
extern bool    OnlyAllowSingleTrade=true;
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=true;
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=false;
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=10;
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;

//Misc
int            OldBars; 
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;
string         Gap, DisabledMessage, ScreenMessage, GvHighName, GvLowName;
double         RsiVal;
int            ChartShift = 1;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   

   
   
      
   
   if (Digits == 2 || Digits == 4)
   {
      DireEmergencyStopLossPips/= 10;
      PendingPipsDistance/= 10;
      PipsAllowedBeyondT4/= 10;
   }//if (Digits == 2 || Digits == 4)
   
   
   
   
//----
   Gap="";
   if (DisplayGapSize >0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   
   
    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: ", Lot, 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);
   if (!OnlyAllowSingleTrade)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Multiple trade settings:", NL);
      if (DeleteLowerLevelPendings) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Deleting lower level pendings:", NL);
      else ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Not deleting lower level pendings:", NL);
      if (AllowLotIncrements) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Lot increment enabled:", NL);
      else  ScreenMessage = StringConcatenate(ScreenMessage,Gap, "    Lot increment disabled:", NL);
   }//if (!OnlyAllowSingleTrade)
   if (OnlyAllowSingleTrade)
   {
      ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Only allowing single trades at target level ");
      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);
   }//if (OnlyAllowSingleTrade)
   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";
      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)  
   
   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 && OrderCloseTime() == 0)
      {
         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)
   
   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), stop, 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), stop, 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()
{

   bool OutOfRange = CheckTradingRange();
   if (OutOfRange) return;

   if (UseSqSteve)
   {
      GetTradeDirection();
      if (TradeDirection == none) return;
   }//UseSqSteve

   bool SendTrade = true;
   bool TradeExists = false;
   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;
      
      TradeExists = DoesTradeExist();
      if (TradeExists) 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, Lot, NormalizeDouble(Bid - (PendingPipsDistance * Point), Digits), stop, SwingHigh);
         }//if (SendTrade)    
      
      }//if (Ask > target && Open(0) < target)
   }//if (Ask > LongTargetLevel[0])      
      
            
   SendTrade = true;
   TradeExists = false;

   //Long
   if (Bid < LongTargetLevel[ap] && Bid > ShortTargetLevel[ap]) return;//Not in the trading zone
   
   if (Bid < ShortTargetLevel[ap])
   {
      if (UseSqSteve  && TradeDirection != up) return;
      
      TradeExists = DoesTradeExist();
      if (TradeExists) 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, Lot, NormalizeDouble(Ask + (PendingPipsDistance * Point), Digits), stop, 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()



//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----

   
   
   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();
   
   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) 

   //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 (NoOfTrades > 0) ForceAllDelete = CheckTradingRange();

   if (ShowUserFeedback) DisplayUserFeedback();
   
   
//----
   return(0);
}
//+------------------------------------------------------------------+5


