//+-----------------------------------------------------------------------------+
//|                                                Daily Scalping v1.0hATRa.mq4 |
//|                                                                Skyline 2007 |
//|                                                                             |
//+-----------------------------------------------------------------------------+
#property copyright "Skyline 2007"
#property link      ""
#include <stdlib.mqh>

// v1.0  (07 Feb 2007) : Start Project 
// v1.0a (07 Feb 2007) : Add GMT_Shift variable
// v1.0b (16 Feb 2007) : Added MagicNumber routine based on pair and timeframe
// v1.0c (17 Feb 2007) : Added routine TotalOrders to count only active order related to current EA (Thanks to Vitalykk)
//                       Added routine OrdersLossInDay to control losses in the same day. Users have the option to change how much loss trade they want setting external variable MaxLossesTradesPerDay.
// v1.0d (19 Feb 2007) : Fixed bug that prevent , when an order was not dispatched, to open reverse trade correctly. 
//                       Handled the case of doji candle that EA now will ignore to determine the trend situation from last 3 candles.
// v1.0e (19 Feb 2007) : Fixed bug on CheckTrend for doji candle routine (Thanks to Vitalykk)
//                       Added function OrdersTakeProfit to avoid EA enter again the market until next day.
// v1.0f (07 Mar 2007) : Midnight order will be opened until 00:01
// v1.0g (09 Mar 2007) : Removed v1.0f limit about order opening.Introducing FirstOrderDone to handle the first order.
// v1.0h (20 Mar 2007) : Fixed error on SL and added comment in case of error opening order to better debug EA.
//                       Add global variables MidnightOrderOpened, TradeStatus to avoid losing variable values if recompile after EA is on chart.
//                       Add TrailingStop routine, if =0 Trailing is disable otherwise it will trail using TrailingStop pips.
//v1.0hATRa (12 APR 2007): C.E.O. modified. Add EA Comment, Fridayclosehour, DaystoReverse, OverruleDirection, GoLong, Decreasefactor,
//                         Accountismicro, Use ATR asStop
//---- Definizione external parameters
extern string    EAComment              = ""; 
extern double    GMT_Shift              = 0;
extern int       HourToCloseOrders      = 23;
extern int       FridayCloseOrders      = 21;
extern bool      SundayCandleExists     = false;
extern int       DaysToReverse          = 3;
extern bool      OverruleDirection      = false;
extern bool      GoLong                 = false;
extern double    Lots                   = 1.0;
extern bool      UseMoneyManagement     = false;
extern bool      AccountIsMicro         = false;
extern int       Risk                   = 0;
extern double    DecreaseFactor         = 0; 
extern int       Slippage               = 3;
extern int       MaxLossesTradesPerDay  = 3;
extern bool      UseATRAsStop           = true; 
extern double    ATR_Period             = 6;
extern double    StopLoss_AT           = 0.3; 
extern double    TakeProfit_AT         = 0.7;      
extern double    BreakEvenAfterPips_AT = 0.3;
extern int       TrailingStop           = 0;


//----- Definizione inner parameters 
// Definition Global Variable
// MidnightOrderOpened = 0 not assigned (first EA run), =1 order still to be opened, =2 order already opened
// TradeStatus         = 0 Trades disabled , = 1 Open only Buy orders , = 2 Open only Sell orders

int MagicNumber;
int BreakEvenAfterPips = 900;  
int TakeProfit         = 900;
int StopLoss           = 900;
string EA_Comment="";
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   string TradeMode,Temp;
   EA_Comment = EAComment + " Skyline";

   manageOpened(); // Happens at every tick.

    if ( Bars < 100 ) {
        return(0); 
     }
    
  
    double N = NormalizeDouble ((iATR(NULL,1440,ATR_Period,1)),Digits);
    double N2 = NormalizeDouble ((iATR(NULL,1440,ATR_Period,2)),Digits);
    
    
   {if  (UseATRAsStop == true) 
    {if  (SundayCandleExists == true && DayOfWeek() == 1)
     {TakeProfit = NormalizeDouble((TakeProfit_AT*N2)/Point,0);      //Where to take profit out at
      StopLoss = NormalizeDouble((StopLoss_AT*N2)/Point,0);      //Stoploss
      BreakEvenAfterPips = NormalizeDouble((BreakEvenAfterPips_AT*N2)/Point,0);         // When to move to B/E
      //TrailingStop = NormalizeDouble((TrailingStop_ATR*N2)/Point,0);
     }
    else 
     {TakeProfit = NormalizeDouble((TakeProfit_AT*N)/Point,0);      //Where to take profit out at
      StopLoss = NormalizeDouble((StopLoss_AT*N)/Point,0);      //Stoploss
      BreakEvenAfterPips = NormalizeDouble((BreakEvenAfterPips_AT*N)/Point,0);         // When to move to B/E
      //TrailingStop = NormalizeDouble((TrailingStop_ATR*N)/Point,0);
     }   
     }
     else
     {TakeProfit = TakeProfit_AT;      //Where to take profit out at
      StopLoss = StopLoss_AT;      //Stoploss
      BreakEvenAfterPips = BreakEvenAfterPips_AT;  
     } 
     }
   if (UseMoneyManagement==true) Lots = CalcolaLot(Risk);   
   
   // It calculates MagicNumber to second of the brace and timeframe 
   MagicNumber = MagicFromSymbol();
    
   // Total variable management 
   GlobalVariable();
   
   // Active order to 00:00 GMT 
   OpenOrderMidnight(Lots);
 
   // It controls orders sluices in loss
   OrdersLossInDay();
   
   // It controls if TP has been caught up 
   OrdersTakeProfit();
   
   // Assets follow-up orders to you
   OpenNextOrders(Lots);
   
   // It closes orders to expiring of HourToCloseOrders
   //CloseAllOrders(HourToCloseOrders);
   if (DayOfWeek()==5) CloseAllOrders(FridayCloseOrders);
   if (DayOfWeek()!=5) CloseAllOrders(HourToCloseOrders);
   // It carries out TrailingStop
   TrailingStop();
    
   // Commenti
   
   
    
   if (GlobalVariableGet("TradeStatus_"+MagicNumber)         == 0) {TradeMode = "NONE";}
   if (GlobalVariableGet("TradeStatus_"+MagicNumber)         == 1) {TradeMode = "BUY";}
   if (GlobalVariableGet("TradeStatus_"+MagicNumber)         == 2) {TradeMode = "SELL";}
   if (GlobalVariableGet("MidnightOrderOpened_"+MagicNumber) == 0) {Temp      = "NOT ASSIGNED";}
   if (GlobalVariableGet("MidnightOrderOpened_"+MagicNumber) == 1) {Temp      = "TO BE OPENED";}
   if (GlobalVariableGet("MidnightOrderOpened_"+MagicNumber) == 2) {Temp      = "ALREADY OPENED";}
      
   Comment("\nDaily Scalping EA v1.0hATRa (Skyline 2007)",
           //"\nCompiled version on 20 Mar 2007",
           "\n\n---------------------------------------",
           "\nMagicNumber : ",MagicNumber,
           "\nMidnight Order : ",Temp,
           "\nNext Trade : ",TradeMode,  
           //"\nStopLevel : ",MarketInfo(Symbol(),MODE_STOPLEVEL), 
           //"\nMathMod(24+GMT_Shift,24) :",MathMod(24+GMT_Shift,24),
           //"\nMathMod(HourToCloseOrders+GMT_Shift,24) : ",MathMod(HourToCloseOrders+GMT_Shift,24),      
           "\n---------------------------------------");
           
   return(0);
  }
  
// ===== Ruotine in order to carry out the trailing of the orders =====
void TrailingStop()
{  int cnt,err;
   int total = TotalOrders();
   for(cnt=0;cnt<total;cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
       if(OrderType()==OP_BUY)   // long position is opened
           {
            // check for trailing stop
            if(TrailingStop>0)  
              {                 
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     if (OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green) == false)
                     {
                      err=GetLastError();
                      Print("error(",err,"): ",ErrorDescription(err));
                     }
                     else return(0);
                    }
                 }
               }
          } // if(OrderType()==OP_BUY)  
         else // go to short position
           {
            // check for trailing stop
            if(TrailingStop>0)  
              {             
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     if (OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red) == false)
                     {
                      err=GetLastError();
                      Print("error(",err,"): ",ErrorDescription(err));
                     }
                     else return(0);                     
                    }
                 }
               } // if(TrailingStop>0)  
           }// if(OrderType()==OP_BUY) 
     }  // for 
}

// ===== Ruotine in order to manage variable total MidnightOrderOpened ===== //
void GlobalVariable()
{
  // Set Global Variable MidnightOrderOpened 
  if (GlobalVariableCheck("MidnightOrderOpened_"+MagicNumber)==false) 
  {
   GlobalVariableSet("MidnightOrderOpened_"+MagicNumber,0);
  }
  // Set Global Variable TradeStatus 
  if (GlobalVariableCheck("TradeStatus_"+MagicNumber)==false) 
  {
   GlobalVariableSet("TradeStatus_"+MagicNumber,0);
  }
}

// ===== Ruotine in order to control if the TP has been caught up and to disable the trades =====
int OrdersTakeProfit()
{
 int total,cnt;
 int TradeWin=0;
 
 int hstTotal=OrdersHistoryTotal();
   
 for(cnt=0;cnt<hstTotal;cnt++)
 {
   OrderSelect(cnt, SELECT_BY_POS, MODE_HISTORY);
   if (OrderMagicNumber()==MagicNumber)
   {
    if (NormalizeDouble(OrderClosePrice(),Digits)==NormalizeDouble(OrderTakeProfit(),Digits) && TimeDay(OrderCloseTime())==Day()) TradeWin++;
   }  // if (OrderMagicNumber()==MagicNumber)
 }  // for 
 if ( TradeWin == 1 )  GlobalVariableSet("TradeStatus_"+MagicNumber,0); // disable trades
 //Print("TradeLoss = ",TradeLoss);
}

// ===== Ruotine in order to count the orders sluices in loss in the same day =====
int OrdersLossInDay()
{
 int total,cnt;
 int TradeLoss=0;
 
 int hstTotal=OrdersHistoryTotal();
   
 for(cnt=0;cnt<hstTotal;cnt++)
 {
   OrderSelect(cnt, SELECT_BY_POS, MODE_HISTORY);
   if (OrderMagicNumber()==MagicNumber)
   {
    if (NormalizeDouble(OrderClosePrice(),Digits)==NormalizeDouble(OrderStopLoss(),Digits) && TimeDay(OrderCloseTime())==Day()) TradeLoss++;
   }  // if (OrderMagicNumber()==MagicNumber)
 }  // for 
 if ( TradeLoss == MaxLossesTradesPerDay ) GlobalVariableSet("TradeStatus_"+MagicNumber,0); // disable trades
 //Print("TradeLoss = ",TradeLoss);
}
  
// ===== Ruotine in order to close all the orders =====
void CloseAllOrders(int Ora)
{
 int total,cnt;
 
 total = TotalOrders();
 //if ((DayOfWeek()== 5 && Hour()>=MathMod(FridayCloseOrders+GMT_Shift,24)) || (DayOfWeek()>= 1 && DayOfWeek()<= 4 && Hour()>=MathMod(Ora+GMT_Shift,24)))
 //if ( Hour()>=MathMod(Ora+GMT_Shift,24) )
 if ((DayOfWeek()== 5 && Hour()>=FridayCloseOrders) || (DayOfWeek()>= 1 && DayOfWeek()<= 4 && Hour()>=HourToCloseOrders))
 {
  GlobalVariableSet("TradeStatus_"+MagicNumber,0); // azzera variabile globale per non aprire più trade
  //FirstOrderDone = false;
  GlobalVariableSet("MidnightOrderOpened_"+MagicNumber,0);  
  for(cnt=0;cnt<total;cnt++)
  {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if (OrderMagicNumber()==MagicNumber)
   {
    if (OrderType() == OP_BUY)  OrderClose(OrderTicket(),OrderLots(), Bid, Slippage, LimeGreen);
    if (OrderType() == OP_SELL) OrderClose(OrderTicket(),OrderLots(), Ask, Slippage, Red);
   }  // if (OrderMagicNumber()==MagicNumber)
  }  // for 
 } // if
}
// ===== Ruotine in order to open the first order to 00:00 GMT =====
void OpenOrderMidnight(double Lot)
{  int Ticket,Errore;
   double SL,TP;
   int ActualSpread;
   
   RefreshRates();
    
   int Total = TotalOrders();
  
   if (( Total < 1                                                                           && // there's no order opened
        (Hour()>=MathMod(24+GMT_Shift,24) && Hour()<HourToCloseOrders)          && // Hour is more than 00 GMT and less than HourToCloseOrders GMT
        GlobalVariableGet("MidnightOrderOpened_"+MagicNumber) <= 1                          && // First Midnight Order has still to be opened
        DayOfWeek()>=1 && DayOfWeek()<=4 )                                                     // Days of week is between Mon..Fri
   ||
   ( Total < 1                                                                           && // there's no order opened
        (Hour()>=MathMod(24+GMT_Shift,24) && Hour()<FridayCloseOrders)       && // Hour is more than 00 GMT and less than HourToCloseOrders GMT
        GlobalVariableGet("MidnightOrderOpened_"+MagicNumber) <= 1                       && // First Midnight Order has still to be opened
        DayOfWeek()==5)) 
   {
   GlobalVariableSet("TradeStatus_"+MagicNumber,0); // azzera variabile globale 
      
   // Controlla BUY Order
   
   
   
   
  if (CheckTrend()=="BUY")
    {   
      
      // Controlla SL 
      if (StopLoss < MarketInfo(Symbol(),MODE_STOPLEVEL)) StopLoss = MarketInfo(Symbol(),MODE_STOPLEVEL);
      if (StopLoss == 0) SL = 0;
      else {SL = Ask-StopLoss*Point;}
      if (TakeProfit == 0) TP = 0;
      else {TP = Ask+TakeProfit*Point;}
      // Piazza l'ordine BUY
      Ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,EA_Comment,MagicNumber,0,Blue);
          
      if(Ticket<0)
      {
       Errore=GetLastError();
       Print(
             "ERROR ON BUY ORDER (",Errore,") : ",ErrorDescription(Errore)+
             " Lots :",Lots,
             " Ask :",DoubleToStr(Ask,Digits),
             " TP :",DoubleToStr(TP,Digits),
             " SL :",DoubleToStr(SL,Digits)
            ) ;
      } 
      else 
      {
       GlobalVariableSet("MidnightOrderOpened_"+MagicNumber,2); // Mark first order as already opened
       GlobalVariableSet("TradeStatus_"+MagicNumber,2);         // Next trade is a sell
       //Print("BUY ORDER OPENED AT ",DoubleToStr(Ask,Digits),
       //      " TP AT ",DoubleToStr(TP,Digits),
       //      " SL AT ",DoubleToStr(SL,Digits));
      } 
     } 
   }
   
   // It finds relative orders you to this EA (thanks to Vitalykk)
   Total = TotalOrders(); 
   
//   if ( Total < 1 && Hour()>=MathMod(24+GMT_Shift,24) && FirstOrderDone == false && DayOfWeek()>=1 && DayOfWeek()<=5 ) 
   
   
   
   
   if (( Total < 1                                                                           && // there's no order opened
        (Hour()>=MathMod(24+GMT_Shift,24) && Hour()<HourToCloseOrders)          && // Hour is more than 00 GMT and less than HourToCloseOrders GMT
        GlobalVariableGet("MidnightOrderOpened_"+MagicNumber) <= 1                                       && // First Midnight Order has still to be opened
        DayOfWeek()>=1 && DayOfWeek()<=5 )                                                     // Days of week is between Mon..Fri
   ||
   ( Total < 1                                                                           && // there's no order opened
        (Hour()>=MathMod(24+GMT_Shift,24) && Hour()<FridayCloseOrders)       && // Hour is more than 00 GMT and less than HourToCloseOrders GMT
        GlobalVariableGet("MidnightOrderOpened_"+MagicNumber) <= 1                       && // First Midnight Order has still to be opened
        DayOfWeek()==5))
   {
   
     // Controlla SELL Order
     
     
     
     if (CheckTrend()=="SELL")
     {
 
      // Setta SL 
      if (StopLoss < MarketInfo(Symbol(),MODE_STOPLEVEL)) StopLoss = MarketInfo(Symbol(),MODE_STOPLEVEL);
      if (StopLoss == 0) SL = 0;
      else {SL = Bid+StopLoss*Point;}
      if (TakeProfit == 0) TP = 0;
      else {TP = Bid-TakeProfit*Point;}
      
      // Piazza Ordine SELL       
      Ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,EA_Comment,MagicNumber,0,Blue);
         
      if(Ticket<0)
      {
       Errore=GetLastError();
       Print("ERROR ON SELL ORDER (",Errore,") : ",ErrorDescription(Errore),
             " Lots :",Lots,
             " Bid :",DoubleToStr(Bid,Digits),
             " TP :",DoubleToStr(TP,Digits),
             " SL :",DoubleToStr(SL,Digits)
            ) ;

      } 
      else
      {
       GlobalVariableSet("MidnightOrderOpened_"+MagicNumber,2); // Mark first order as already opened
       GlobalVariableSet("TradeStatus_"+MagicNumber,1);         // Next trade is Buy
       //Print("SELL ORDER OPENED AT ",DoubleToStr(Bid,Digits),
       //      " TP AT ",DoubleToStr(TP,Digits),
       //      " SL AT ",DoubleToStr(SL,Digits));       
      }
     }    
   }
}

// ===== Ruotine in order to open orders during the day to the attainment of SL or TP =====
void OpenNextOrders(double Lot)
{  int Ticket,Errore;
   double SL,TP;
   int ActualSpread;
   
   RefreshRates();

   int Total = TotalOrders();
   /*if ( Total < 1 && 
        Hour()<=MathMod(HourToCloseOrders+GMT_Shift,24) &&
        DayOfWeek()>=1 && DayOfWeek()<=5 )*/ 
   if (( Total < 1 && 
        Hour()<=HourToCloseOrders &&
        DayOfWeek()>=1 && DayOfWeek()<=4 ) ||
        ( Total < 1 && 
        Hour()<=FridayCloseOrders &&
        DayOfWeek()==5))
   {
   // Controlla BUY Order
   if ( GlobalVariableGet("TradeStatus_"+MagicNumber) == 1 )
    {         
      // Controlla SL 
      if (StopLoss < MarketInfo(Symbol(),MODE_STOPLEVEL)) StopLoss = MarketInfo(Symbol(),MODE_STOPLEVEL);
      if (StopLoss == 0) SL = 0;
      else {SL = Ask-StopLoss*Point;}
      if (TakeProfit == 0) TP = 0;
      else {TP = Ask+TakeProfit*Point;}
      
      // Piazza l'ordine BUY
      Ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,EA_Comment,MagicNumber,0,Blue);    
         
      if(Ticket<0)
      {
       Errore=GetLastError();
       Print(
             "ERROR ON BUY ORDER REVERSE (",Errore,") : ",ErrorDescription(Errore)+
             " Lots :",Lots,
             " Ask :",DoubleToStr(Ask,Digits),
             " TP :",DoubleToStr(TP,Digits),
             " SL :",DoubleToStr(SL,Digits)
            ) ;
      }  
      else
      {
       GlobalVariableSet("TradeStatus_"+MagicNumber,2); // Prossimo trade è Sell 
      }
     } 
   }
  
   Total = TotalOrders();
   /*if ( Total < 1 && 
        Hour()<=MathMod(HourToCloseOrders+GMT_Shift,24) &&
        DayOfWeek()>=1 && DayOfWeek()<=5 )*/ 
   if (( Total < 1 && 
        Hour()<=HourToCloseOrders &&
        DayOfWeek()>=1 && DayOfWeek()<=4 ) ||
        ( Total < 1 && 
        Hour()<=FridayCloseOrders &&
        DayOfWeek()==5)) 
   {  
     // Controlla SELL Order
     if ( GlobalVariableGet("TradeStatus_"+MagicNumber) == 2 )
     {
 
      // Setta SL 
      if (StopLoss < MarketInfo(Symbol(),MODE_STOPLEVEL)) StopLoss = MarketInfo(Symbol(),MODE_STOPLEVEL);
      if (StopLoss == 0) SL = 0;
      SL = Bid+StopLoss*Point;
      if (TakeProfit == 0) TP = 0;
      else TP = Bid-TakeProfit*Point;
      
      // Piazza Ordine SELL       
      Ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,EA_Comment,MagicNumber,0,Blue);
          
      if(Ticket<0)
      {
       Errore=GetLastError();
       Print("ERROR ON SELL ORDER REVERSE (",Errore,") : ",ErrorDescription(Errore),
             " Lots :",Lots,
             " Bid :",DoubleToStr(Bid,Digits),
             " TP :",DoubleToStr(TP,Digits),
             " SL :",DoubleToStr(SL,Digits)
            ) ;
      } 
      else
      {
       GlobalVariableSet("TradeStatus_"+MagicNumber,1); // Prossimo trade è Buy
      }
     }    
   }
}

// ===== Ruotine in order to control the trend ===== 
string CheckTrend()
{

 // Check 1 day ago candle
 int DaysShift = 1;
 string C1="NONE",C2="NONE",C3="NONE",C4="NONE",C5="NONE";
 //if ( SundayCandleExists == true && DayOfWeek() == 1 ) DaysShift++; // if today is Monday then skip the Sunday candle
 if (SundayCandleExists == true && TimeDayOfWeek(iTime(NULL,PERIOD_D1,DaysShift)) == 0)  DaysShift++; // if candle is Monday then skip Sunday candle
 if (iOpen(NULL,PERIOD_D1,DaysShift)==iClose(NULL,PERIOD_D1,DaysShift)) DaysShift++;
 if (iOpen(NULL,PERIOD_D1,DaysShift)<iClose(NULL,PERIOD_D1,DaysShift)) C1 = "BULLISH";
 if (iOpen(NULL,PERIOD_D1,DaysShift)>iClose(NULL,PERIOD_D1,DaysShift)) C1 = "BEARISH";
 // Print("C1_DaysShift = ",DaysShift); // for debug purpouse

 // Check 2 days ago candle
 DaysShift++;
 if (SundayCandleExists == true && TimeDayOfWeek(iTime(NULL,PERIOD_D1,DaysShift)) == 0)  DaysShift++; // if candle is Monday then skip Sunday candle
 if (iOpen(NULL,PERIOD_D1,DaysShift)==iClose(NULL,PERIOD_D1,DaysShift)) DaysShift++;
 if (iOpen(NULL,PERIOD_D1,DaysShift)<iClose(NULL,PERIOD_D1,DaysShift)) C2 = "BULLISH";
 if (iOpen(NULL,PERIOD_D1,DaysShift)>iClose(NULL,PERIOD_D1,DaysShift)) C2 = "BEARISH";
 //Print("C2_DaysShift = ",DaysShift); // for debug purpouse

 // Check 3 days ago candle
 DaysShift++;
 if (SundayCandleExists == true && TimeDayOfWeek(iTime(NULL,PERIOD_D1,DaysShift)) == 0) DaysShift++; // if candle is Monday then skip Sunday candle
 if (iOpen(NULL,PERIOD_D1,DaysShift)==iClose(NULL,PERIOD_D1,DaysShift)) DaysShift++;
 if (iOpen(NULL,PERIOD_D1,DaysShift)<iClose(NULL,PERIOD_D1,DaysShift)) C3 = "BULLISH";
 if (iOpen(NULL,PERIOD_D1,DaysShift)>iClose(NULL,PERIOD_D1,DaysShift)) C3 = "BEARISH";
 // Print("C3_DaysShift = ",DaysShift);
 
// Check 4 days ago candle
 DaysShift++;
 if (SundayCandleExists == true && TimeDayOfWeek(iTime(NULL,PERIOD_D1,DaysShift)) == 0) DaysShift++; // if candle is Monday then skip Sunday candle
 if (iOpen(NULL,PERIOD_D1,DaysShift)==iClose(NULL,PERIOD_D1,DaysShift)) DaysShift++;
 if (iOpen(NULL,PERIOD_D1,DaysShift)<iClose(NULL,PERIOD_D1,DaysShift)) C4 = "BULLISH";
 if (iOpen(NULL,PERIOD_D1,DaysShift)>iClose(NULL,PERIOD_D1,DaysShift)) C4 = "BEARISH";
 
 
 // Check 5 days ago candle
 DaysShift++;
 if (SundayCandleExists == true && TimeDayOfWeek(iTime(NULL,PERIOD_D1,DaysShift)) == 0) DaysShift++; // if candle is Monday then skip Sunday candle
 if (iOpen(NULL,PERIOD_D1,DaysShift)==iClose(NULL,PERIOD_D1,DaysShift)) DaysShift++;
 if (iOpen(NULL,PERIOD_D1,DaysShift)<iClose(NULL,PERIOD_D1,DaysShift)) C5 = "BULLISH";
 if (iOpen(NULL,PERIOD_D1,DaysShift)>iClose(NULL,PERIOD_D1,DaysShift)) C5 = "BEARISH";
 
 
 // Print("C1 = ",C1," C2 = ",C2," C3 = ",C3); // for debug purpouse
 
 if (OverruleDirection == true)
   {if (
      (GoLong == true)
      )
   return("BUY"); 
   // BEARISH Condition
   if (
       (GoLong == false )
      )   
   return("SELL"); 
   }  
   
 
 
 
 
 if (DaysToReverse == 0)
   // BULLISH Condition
   {if (
      (C1=="BULLISH")
      )
   return("BUY"); 
   // BEARISH Condition
   if (
       (C1=="BEARISH" )
      )   
   return("SELL"); 
   }  
 
 
 if (DaysToReverse == 1)
   // BULLISH Condition
   {if (
      (C1=="BEARISH")
      )
   return("BUY"); 
   // BEARISH Condition
   if (
       (C1=="BULLISH" )
      )   
   return("SELL"); 
   }  
 
 
 if (DaysToReverse == 2)
   // BULLISH Condition
   {if (
      (C1=="BULLISH") ||
      (C1=="BEARISH" && C2=="BEARISH")
      )
   return("BUY"); 
   // BEARISH Condition
   if (
       (C1=="BEARISH" ) ||
       (C1=="BULLISH" && C2=="BULLISH")
      )   
   return("SELL"); 
   }  
 
 
 
 if (DaysToReverse == 3)
   // BULLISH Condition
   {if (
      (C1=="BULLISH") ||     
      (C1=="BEARISH" && C2=="BEARISH" && C3=="BEARISH")
      )
   return("BUY"); 
   // BEARISH Condition
   if (
       (C1=="BEARISH" )||
       (C1=="BULLISH" && C2=="BULLISH" && C3=="BULLISH")
      )   
   return("SELL");    
   }  
   
   
   if (DaysToReverse == 4)
   // BULLISH Condition
   {if (
      (C1=="BULLISH") ||     
      (C1=="BEARISH" && C2=="BEARISH" && C3=="BEARISH" && C4=="BEARISH")
      )
   return("BUY"); 
   // BEARISH Condition
   if (
       (C1=="BEARISH" )||
       (C1=="BULLISH" && C2=="BULLISH" && C3=="BULLISH" && C4=="BULLISH")
      )   
   return("SELL"); 
   }
   
   
   if (DaysToReverse == 5)
   // BULLISH Condition
   {if (
      (C1=="BULLISH") ||     
      (C1=="BEARISH" && C2=="BEARISH" && C3=="BEARISH" && C4=="BEARISH" && C5=="BEARISH")
      )
   return("BUY"); 
   // BEARISH Condition
   if (
       (C1=="BEARISH" )||
       (C1=="BULLISH" && C2=="BULLISH" && C3=="BULLISH" && C4=="BULLISH" && C5=="BULLISH")
      )   
   return("SELL"); 
   }
}
// ===== Ruotine for the calculation of the Lot in the case of Money Management =====
/*double CalcolaLot(int Rischio)
{
  double Lot=0;
  Lot=AccountEquity()* Rischio/100/1000;
  if( Lot>=0.1 )
  {
    Lot = NormalizeDouble(Lot,1); 
  }
  else Lot = NormalizeDouble(Lot,2);
  if (Lot > MarketInfo(Symbol(),MODE_MAXLOT)) { Lot = MarketInfo(Symbol(),MODE_MAXLOT); } // Avoid possible Lot value overflow if lot exceed maximum value allowed by broker
  if (Lot < MarketInfo(Symbol(),MODE_MINLOT)) { Lot = MarketInfo(Symbol(),MODE_MINLOT); } // Avoid possible Lot value overflow if lot exceed minimum value allowed by broker
  return(Lot);
}*/


//----------------------- MONEY MANAGEMENT FUNCTION 
//----------------------- SOURCE : CODERSGURU
//----------------------- MODIFIED: MIKHAIL

//double subLotSize()
double CalcolaLot(int Risk)
{
if(UseMoneyManagement==false) return(Lots);
double lot=Lots;
int orders=HistoryTotal();
int losses=0;
int decimalPlaces=1;

if(AccountIsMicro==true) decimalPlaces=2;

lot=NormalizeDouble((AccountFreeMargin()*Risk/1000.0)/100,decimalPlaces);
if(DecreaseFactor>0)
{
for(int i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
//----
if(OrderProfit()>0) break;
if(OrderProfit()<0) losses++;
}
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,decimalPlaces);
}

if(lot<0.1 && AccountIsMicro==false) lot=0.1;
if(lot<0.01 && AccountIsMicro==true) lot=0.01;
if(lot>99) lot=99;
return(lot);

}






// ===== Ruotine in order to calculate various MagicNumber for every brace and period =====
int MagicFromSymbol() 
{ // included by Renato 
   int MagicNumber=0;  
   for (int i=0; i<5; i++) 
   {  
     MagicNumber=MagicNumber*3+StringGetChar(Symbol(),i);  
   }  
   MagicNumber=MagicNumber*3+Period();  
   return(MagicNumber);  
}

// ===== Ruotines in order to calculate how many open orders are for this EA ===== 
int TotalOrders()
{  
   int cnt; 
   int Total = 0;
   for(cnt=0;cnt<OrdersTotal();cnt++)
   {
    OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
    if (OrderMagicNumber()==MagicNumber) Total ++;
   }
  return(Total); 
}

//+--------------------MODIFIED---------------------------------------+
bool selectOrder(int pos)
{
    if ( ! OrderSelect( pos, SELECT_BY_POS ) )
        return( false );
    if ( OrderMagicNumber() != MagicNumber )
        return( false );
    return( OrderSymbol() == Symbol() );
}
void manageOpened()
{
    for ( int i = OrdersTotal() - 1; i >= 0; i-- ) {
        if ( ! selectOrder( i ) ) {
            continue;
        
        }
        if ( BreakEvenAfterPips > 0 ) {
            subBreakEvenAfterPips();
        }
    }
}



//---------------------- BREAK EVEN FUNCTION
// Uses interactive configurations:
//    BreakEvenAfterPips = price gap required

void subBreakEvenAfterPips()
{
    if ( OrderType() == OP_BUY ) {
        if ( OrderStopLoss() >= OrderOpenPrice() - Point )
            return;
        if ( Bid <= OrderOpenPrice() + Point * BreakEvenAfterPips )
            return;
        OrderModify( OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), OrderTakeProfit(), 0, Green );
    } else if ( OrderType() == OP_SELL ) {
        if ( OrderStopLoss() > 0 && OrderStopLoss() <= OrderOpenPrice() + Point )
            return;
        if ( Ask >= OrderOpenPrice() - Point * BreakEvenAfterPips )
            return;
        OrderModify( OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), OrderTakeProfit(), 0, Red );
    }
}


