//+-------------------------------------------------------------------+
//|jiva34's MA cross Fractals combo auto trading robot by Steve Hopwood.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"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"
#define  up "Up"
#define  down "Down"
#define  none "No swing"
#define  nocross "No cross withing the specified candles"
#define  confused "Mixed, and so unable to trade"
#define  high "High"
#define  low "Low"

//D1 pivot and H4 open price
#define  vline "Period start line"
#define  hline "Open price line"
#define  pline "Daily pivot"


/*

This ea attempts to automate the strategy described at http://www.forexfactory.com/showthread.php?t=312339.
I have no idea whether the ea can be successful.


Matt Kennel has provided the code for bool O_R_CheckForHistory(int ticket). Cheers Matt, You are a star.



Code for adding debugging Sleep
Alert("G");
int x = 0;
while (x == 0) Sleep(100);

FUNCTIONS LIST
int init()
int start()

----Trading----

void LookForTradingOpportunities()
bool IsTradingAllowed()
bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
bool DoesTradeExist()
bool CheckTradingTimes()

----Trade direction----
void DrawLines()
void GetPivot()
void DrawPivot(double pivot)


----Matt's Order Reliable library code
bool O_R_CheckForHistory(int ticket) Cheers Matt, You are a star.
void O_R_Sleep(double mean_time, double max_time)

----Indicator readings----
void GetLatestFractal()
void GetLatestCross()



*/

extern string  gen="----General inputs----";
extern double  Lot=0.01;
extern int     TakeProfit=12;
extern int     StopLoss=10;
extern int     MagicNumber=0;
extern string  TradeComment="";
extern bool    CriminalIsECN=false;
extern double  MaxSpread=40;

extern string  td="----Trading direction----";
extern bool    TradeLong=true;
extern bool    TradeShort=true;
extern bool    AutomateDirection=true;
extern string  tdl="H4 open price line";
extern bool    UseH4=true;
extern color   HorizontalLineColour=Turquoise;
extern color   VerticalLineColour=Turquoise;
extern int     TimeFrame=240;
extern string  D1="D1 Pivot";
extern bool    UsePivot=true;
extern int     PivotTimeFrame=1440;
extern bool    CriminalHasSundayCandle=true;
extern color   PivotLineColour=Blue;

extern string  fr="----Fractals inputs----";
extern int     FractalsTimeFrame=0;//Defaults to current time frame
extern int     LookBackForFractalsCandles=3;

extern string  ma="----Moving Average cross inputs----";
extern int     LookBackForCrossCandles=120;
extern int     MovingAverageTimeFrame=0;//Defaults to current time frame
extern string  fma="Faster moving average";
extern int     FasterMA=10;
extern string  mame="Method: 0=sma; 1=ema; 2=smma;  3=lwma";
extern int     FasterMode=1;
extern string  sma="Slower moving average";
extern int     SlowerMA=40;
extern int     SlowerMode=1;

extern string  tt="----Trading hours----";
extern string  Trade_Hours= "Set Morning & Evening Hours";
extern string  Trade_Hoursi= "Use 24 hour, local time clock";
extern string  Trade_Hours_M= "Morning Hours 0-12";
extern  int    start_hourm = 0;
extern  int    end_hourm = 12;
extern string  Trade_Hours_E= "Evening Hours 12-24";
extern  int    start_houre = 12;
extern  int    end_houre = 24;

extern string  mis="----Odds and ends----";
extern int     DisplayGapSize=30;

//Matt's O-R stuff
int 	         O_R_Setting_max_retries 	= 10;
double 	      O_R_Setting_sleep_time 		= 4.0; /* seconds */
double 	      O_R_Setting_sleep_max 		= 15.0; /* seconds */

//Trading variables
int            TicketNo, OpenTrades;
bool           CanTradeThisPair;//Will be false when this pair fails the currency can only trade twice filter, or the balanced trade filter
bool           BuyOpen, SellOpen;
string         direction;
string         swing;

//Pivot and H4 lines
int            OldLineBars, OldD1Bars;


//Margin status display
bool           EnoughMargin;
string         MarginMessage;

//Misc
string         Gap, ScreenMessage;
int            OldBars, OldH4Bars;
string         PipDescription=" pips";
bool           ForceTradeClosure;


void DisplayUserFeedback()
{
   
   if (IsTesting() && !IsVisualMode()) return;

   ScreenMessage = "";
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage, Gap, TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), NL );
   /*
   //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);      
   if (TradeLong) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Taking long trades",  NL);
   if (TradeShort) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Taking short trades",  NL);
   if (!TradeLong && !TradeShort) ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Not trading",  NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Lot size: ", Lot, " (Criminal's minimum lot size: ", MarketInfo(Symbol(), MODE_MINLOT), ")", NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Take profit: ", TakeProfit, PipDescription,  NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Stop loss: ", StopLoss, PipDescription,  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, "MaxSpread = ", MaxSpread, ": Spread = ", MarketInfo(Symbol(), MODE_SPREAD), 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, "            start_houre: ", DoubleToStr(start_houre, 2), 
                      ": end_houre: ", DoubleToStr(end_houre, 2), NL);
                      
   }//else
   
   
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Most recent cross: ", direction, NL);
   ScreenMessage = StringConcatenate(ScreenMessage,Gap, "Swing ", LookBackForFractalsCandles, " candles ago: ", swing, NL);


   ScreenMessage = StringConcatenate(ScreenMessage,Gap, NL);
   
   
   if (MarginMessage != "") ScreenMessage = StringConcatenate(ScreenMessage,NL, Gap, MarginMessage, NL);

   
   Comment(ScreenMessage);


}//void DisplayUserFeedback()


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----

   //Adapt to x digit criminals
   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;   
   
   if (multiplier > 1) PipDescription = " points";
   
   TakeProfit*= multiplier;
   StopLoss*= multiplier;
   
   Gap="";
   if (DisplayGapSize > 0)
   {
      for (int cc=0; cc< DisplayGapSize; cc++)
      {
         Gap = StringConcatenate(Gap, " ");
      }   
   }//if (DisplayGapSize >0)
   

   if (TradeComment == "") TradeComment = " ";
   OldBars = Bars;
   GetLatestCross();
   GetLatestFractal();
   DisplayUserFeedback();
   
   //Call sq's show trades indi
   //iCustom(NULL, 0, "SQ_showTrades",Magic, 0,0);

   
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
//----
   return(0);
}



bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take)
{
   
   
   int slippage = 10;
   if (Digits == 3 || Digits == 5) slippage = 100;
   
   color col = Red;
   if (type == OP_BUY || type == OP_BUYSTOP) col = Green;
   
   int expiry = 0;
   //if (SendPendingTrades) expiry = TimeCurrent() + (PendingExpiryMinutes * 60);

   if (!CriminalIsECN) int ticket = OrderSend(Symbol(),type, lotsize, price, slippage, stop, take, comment, MagicNumber, expiry, col);
   
   
   //Is a 2 stage criminal
   if (CriminalIsECN)
   {
      bool result;
      int err;
      ticket = OrderSend(Symbol(),type, lotsize, price, slippage, 0, 0, comment, MagicNumber, expiry, col);
      if (ticket > 0)
      {
	     
	     if (take > 0 && stop > 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           result = OrderModify(ticket, OrderOpenPrice(), stop, take, OrderExpiration(), CLR_NONE);
           if (!result)
           {
               err=GetLastError();
               Print(Symbol(), " SL/TP  order modify failed with error(",err,"): ",ErrorDescription(err));               
           }//if (!result)			  
        }//if (take > 0 && stop > 0)
      
	     if (take != 0 && stop == 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           result = OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), take, OrderExpiration(), CLR_NONE);
           if (!result)
           {
               err=GetLastError();
               Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
           }//if (!result)			  
        }//if (take == 0 && stop != 0)

        if (take == 0 && stop != 0)
        {
           while(IsTradeContextBusy()) Sleep(100);
           result = OrderModify(ticket, OrderOpenPrice(), stop, OrderTakeProfit(), OrderExpiration(), CLR_NONE);
           if (!result)
           {
               err=GetLastError();
               Print(Symbol(), " SL  order modify failed with error(",err,"): ",ErrorDescription(err));               
           }//if (!result)			  
        }//if (take == 0 && stop != 0)

      }//if (ticket > 0)
        
      
      
   }//if (CriminalIsECN)
   
   //Error trapping for both
   if (ticket < 0)
   {
      string stype;
      if (type == OP_BUY) stype = "OP_BUY";
      if (type == OP_SELL) stype = "OP_SELL";
      if (type == OP_BUYLIMIT) stype = "OP_BUYLIMIT";
      if (type == OP_SELLLIMIT) stype = "OP_SELLLIMIT";
      if (type == OP_BUYSTOP) stype = "OP_BUYSTOP";
      if (type == OP_SELLSTOP) stype = "OP_SELLSTOP";
      err=GetLastError();
      Alert(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
      Print(Symbol(), " ", stype," order send failed with error(",err,"): ",ErrorDescription(err));
      return(false);
   }//if (ticket < 0)  
   
   
   TicketNo = ticket;
   //Make sure the trade has appeared in the platform's history to avoid duplicate trades.
   //My mod of Matt's code attempts to overcome the bastard crim's attempts to overcome Matt's code.
   bool TradeReturnedFromCriminal = false;
   while (!TradeReturnedFromCriminal)
   {
      TradeReturnedFromCriminal = O_R_CheckForHistory(ticket);
      if (!TradeReturnedFromCriminal)
      {
         Alert(Symbol(), " sent trade not in your trade history yet. Turn of this ea NOW.");
      }//if (!TradeReturnedFromCriminal)
   }//while (!TradeReturnedFromCriminal)
   
   //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 DoesTradeExist()
{
   
   TicketNo = -1;
   
   if (OrdersTotal() == 0) return(false);
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      
      if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
      {
         TicketNo = OrderTicket();
         return(true);         
      }//if (OrderMagicNumber()==MagicNumber && OrderSymbol() == Symbol() )      
   }//for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)

   return(false);

}//End bool DoesTradeExist()



bool IsTradingAllowed()
{
   //Returns false if any of the filters should cancel trading, else returns true to allow trading
   
      
   //Maximum spread
   if (MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread) return(false);
 
   
   return(true);


}//End bool IsTradingAllowed()


void LookForTradingOpportunities()
{


   RefreshRates();
   double take, stop, price;
   int type;
   bool SendTrade;
   
   double SendLots = Lot;

   //Check filters
   if (!IsTradingAllowed() ) return;
   
   //Long 
   if (direction == up && swing == low && TradeLong)
   {
      //Look for a rising candle
      if (Close[LookBackForFractalsCandles] < Open[LookBackForFractalsCandles]) return;//Not a rising candle
      if (TakeProfit > 0) take = NormalizeDouble(Ask + (TakeProfit * Point), Digits);
      if (StopLoss > 0) stop = NormalizeDouble(Ask - (StopLoss * Point), Digits);
      type = OP_BUY;
      price = Ask;
      SendTrade = true;
   }//if (CciDirection == up)
   
   
   //Short
   if (direction == down && swing == high && TradeShort)
   {
      //Look for a falling candle
      if (Close[LookBackForFractalsCandles] > Open[LookBackForFractalsCandles]) return;//Not a falling candle
      if (TakeProfit > 0) take = NormalizeDouble(Bid - (TakeProfit * Point), Digits);
      if (StopLoss > 0) stop = NormalizeDouble(Bid + (StopLoss * Point), Digits);
      type = OP_SELL;
      price = Bid;
      SendTrade = true;      
   }//if (CciDirection == down)
   

   if (SendTrade)
   {
      bool result = SendSingleTrade(type, TradeComment, SendLots, price, stop, take);
   }//if (SendTrade)
   
   //Actions when trade send succeeds
   if (SendTrade && result)
   {
   
   }//if (result)
   
   //Actions when trade send fails
   if (SendTrade && !result)
   {
      OldH4Bars = 0;//Force a retry at the next tick
   }//if (!result)
   
   

}//void LookForTradingOpportunities()


////////////////////////////////////////////////////////////////////////////////////////////////
//Indicator module




/*
double CalculateVolatility(int period, int LookBack)
{
   //Calculates the volatility of a pair based on an average of their movement over LookBack periods
   
   double pips;
   for (int cc = 1; cc < LookBack; cc++)
   {
      pips+= iHigh(NULL, period, cc) - iLow(NULL, period, cc);      
   }//for (int cc = 1; cc < LookBack; cc++)
   
   pips/= LookBack;//Average pips movement per day
   //Alert(pips);

   //Convert to pips
   int multiplier;
   if (Digits == 2) multiplier = 10;
   if (Digits == 3) multiplier = 100;
   if (Digits == 4) multiplier = 1000;
   if (Digits == 5) multiplier = 10000;
   
   pips*= multiplier;
   int rpips = pips;//Convert to a simple integer - all we need
   
   return(rpips);
   
}//End double CalculateVolatility(int period, int LookBack)
*/

void GetLatestCross()
{

   //Finds the latest cross indiated by MA_Crossover_Signal
   direction = nocross;
   
   for (int cc = 1; cc <= LookBackForCrossCandles; cc++)
   {
      double MaCrossUp = iCustom(NULL, MovingAverageTimeFrame, "MA_Crossover_Signal", FasterMode, FasterMA, SlowerMode, SlowerMA, 0, cc);
      if (MaCrossUp != EMPTY_VALUE) 
      {
         direction = up;
         break;
      }//if (MaCrossUp != EMPTY_VALUE) 
      
      double MaCrossDown = iCustom(NULL, MovingAverageTimeFrame, "MA_Crossover_Signal", FasterMode, FasterMA, SlowerMode, SlowerMA, 1, cc);      
      if (MaCrossDown != EMPTY_VALUE) 
      {
         direction = down;
         break;
      }//if (MaCrossDown != EMPTY_VALUE) 
      
      //Just in case
      if (cc == Bars) break;
   }//for (int cc = 1; cc <= Bars; cc++)

}//End void GetLatestCross()

void GetLatestFractal()
{
   double fractal;
   swing = none;

   //Look for a swing low
   fractal = iFractals(NULL, FractalsTimeFrame, MODE_LOWER, LookBackForFractalsCandles);
   if (fractal != 0) 
   {
      swing = low;
      return;
   }//if (fractal != 0) 
   
   
   //Look for a swing high
   fractal = iFractals(NULL, FractalsTimeFrame, MODE_UPPER, LookBackForFractalsCandles);
   if (fractal != 0) swing = high;

}//void GetLatestFractal()



//End Indicator module
////////////////////////////////////////////////////////////////////////////////////////////////


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()


//=============================================================================
//                           O_R_CheckForHistory()
//
//  This function is to work around a very annoying and dangerous bug in MT4:
//      immediately after you send a trade, the trade may NOT show up in the
//      order history, even though it exists according to ticket number.
//      As a result, EA's which count history to check for trade entries
//      may give many multiple entries, possibly blowing your account!
//
//  This function will take a ticket number and loop until
//  it is seen in the history.
//
//  RETURN VALUE:
//     TRUE if successful, FALSE otherwise
//
//
//  FEATURES:
//     * Re-trying under some error conditions, sleeping a random
//       time defined by an exponential probability distribution.
//
//     * Displays various error messages on the log for debugging.
//
//  ORIGINAL AUTHOR AND DATE:
//     Matt Kennel, 2010
//
//=============================================================================
bool O_R_CheckForHistory(int ticket)
{
   //My thanks to Matt for this code. He also has the undying gratitude of all users of my trading robots
   
   int lastTicket = OrderTicket();

   int cnt = 0;
   int err = GetLastError(); // so we clear the global variable.
   err = 0;
   bool exit_loop = false;
   bool success=false;

   while (!exit_loop) {
      /* loop through open trades */
      int total=OrdersTotal();
      for(int c = 0; c < total; c++) {
         if(OrderSelect(c,SELECT_BY_POS,MODE_TRADES) == true) {
            if (OrderTicket() == ticket) {
               success = true;
               exit_loop = true;
            }
         }
      }
      if (cnt > 3) {
         /* look through history too, as order may have opened and closed immediately */
         total=OrdersHistoryTotal();
         for(c = 0; c < total; c++) {
            if(OrderSelect(c,SELECT_BY_POS,MODE_HISTORY) == true) {
               if (OrderTicket() == ticket) {
                  success = true;
                  exit_loop = true;
               }
            }
         }
      }

      cnt = cnt+1;
      if (cnt > O_R_Setting_max_retries) {
         exit_loop = true;
      }
      if (!(success || exit_loop)) {
         Print("Did not find #"+ticket+" in history, sleeping, then doing retry #"+cnt);
         O_R_Sleep(O_R_Setting_sleep_time, O_R_Setting_sleep_max);
      }
   }
   // Select back the prior ticket num in case caller was using it.
   if (lastTicket >= 0) {
      OrderSelect(lastTicket, SELECT_BY_TICKET, MODE_TRADES);
   }
   if (!success) {
      Print("Never found #"+ticket+" in history! crap!");
   }
   return(success);
}//End bool O_R_CheckForHistory(int ticket)

//=============================================================================
//                              O_R_Sleep()
//
//  This sleeps a random amount of time defined by an exponential
//  probability distribution. The mean time, in Seconds is given
//  in 'mean_time'.
//  This returns immediately if we are backtesting
//  and does not sleep.
//
//=============================================================================
void O_R_Sleep(double mean_time, double max_time)
{
   if (IsTesting()) {
      return;   // return immediately if backtesting.
   }

   double p = (MathRand()+1) / 32768.0;
   double t = -MathLog(p)*mean_time;
   t = MathMin(t,max_time);
   int ms = t*1000;
   if (ms < 10) {
      ms=10;
   }
   Sleep(ms);
}//End void O_R_Sleep(double mean_time, double max_time)


///////////////////////////////////////////////////////////////////////////////////////////////////////

void AutoTradeDirectionDetection()
{
   TradeLong = false;
   TradeShort = false;
   bool long = true, short = true;
   
   //H4 open price
   if (UseH4)
   {
      double target = ObjectGet(hline, OBJPROP_PRICE1);
      if (Bid < target) long = false;
      if (Bid > target) short = false;
   }//UseH4
   
   //D1 pivot
   if (UsePivot)
   {
      target = ObjectGet(pline, OBJPROP_PRICE1);
      if (Bid < target) long = false;
      if (Bid > target) short = false;
   }//if (UseD1Pivot)

   if (long) TradeLong = true;
   if (short) TradeShort = true;
   
   
}//void AutomaticTradeDirectionDetection()

void DrawLines()
{
   ObjectDelete(vline);
   ObjectDelete(hline);
   
   ObjectCreate(vline,OBJ_VLINE,0,iTime(NULL, TimeFrame, 0), 0);
   ObjectSet(vline,OBJPROP_COLOR,VerticalLineColour);
   ObjectSet(vline,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(vline,OBJPROP_WIDTH,1);    

   ObjectCreate(hline,OBJ_HLINE,0,TimeCurrent(), iOpen(NULL, TimeFrame, 0) );
   ObjectSet(hline,OBJPROP_COLOR,HorizontalLineColour);
   ObjectSet(hline,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(hline,OBJPROP_WIDTH,1);    


}//void DrawLines()

void GetPivot()
{
   int day = TimeDayOfWeek(TimeCurrent() );
   int shift = 1;
   if (PivotTimeFrame == PERIOD_D1 && day == 1 && CriminalHasSundayCandle) shift = 2;//Deal with the Sunday cabdle
   
   //double pivot = NormalizeDouble((iHigh(NULL, PivotTimeFrame, shift) + iLow(NULL, PivotTimeFrame, shift)) / 2, Digits);
   double pivot = NormalizeDouble((iHigh(NULL, PivotTimeFrame, shift) + iLow(NULL, PivotTimeFrame, shift) + iClose(NULL, PivotTimeFrame, shift)) / 3, Digits);
   DrawPivot(pivot);
}//void GetPivot()


void DrawPivot(double pivot)
{

   ObjectDelete(pline);
   
   ObjectCreate(pline,1,0,TimeCurrent(), pivot);
   ObjectSet(pline,OBJPROP_COLOR,PivotLineColour);
   ObjectSet(pline,OBJPROP_STYLE,STYLE_SOLID);
   ObjectSet(pline,OBJPROP_WIDTH,1);    

}//void DrawPivot(double pivot)


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----

   int x = 0;
   
   static bool TradeExists;
   

   ///////////////////////////////////////////////////////////////////////////////////////////////
   if (AutomateDirection) 
   {
      //H4 opend price and daily pivot lines
      if (OldLineBars != iBars(NULL, TimeFrame) && UseH4)
      {
         OldLineBars = iBars(NULL, TimeFrame);
         DrawLines();
      }//if (OldLineBars != iBars(NULL, TimeFrame)
   
      if (OldD1Bars != iBars(NULL, PERIOD_D1) && UsePivot)
      {
         GetPivot();
         OldD1Bars = iBars(NULL, PERIOD_D1);
      }//if (OldD1Bars != iBars(NULL, PERIOD_D1) )
   
   
      AutoTradeDirectionDetection();
   }//if (AutomateDirection) 
   
   ///////////////////////////////////////////////////////////////////////////////////////////////
   //Find open trades.   
   TradeExists = DoesTradeExist();

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   //Trading times
   bool TradeTimeOk = CheckTradingTimes();
   if (!TradeTimeOk)
   {
      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)
  
   ///////////////////////////////////////////////////////////////////////////////////////////////         
   //Trading
   if (OldBars != Bars)
   {
      OldBars = Bars;
      GetLatestCross();
      GetLatestFractal();
      if (TicketNo == -1)
      {   
         LookForTradingOpportunities();
      }//if (TicketNo == -1)
   }//if (OldBars != Bars)
   
   ///////////////////////////////////////////////////////////////////////////////////////////////      

   DisplayUserFeedback();
   
//----
   return(0);
}
//+------------------------------------------------------------------+