//+--------------------------------------------------------------------+
//|                                                                    |
//|                                                  SRDC III v1.0.mq4 |
//|                                                       Skyline 2007 |
//|                                                    TIMEFRAME : M15 |
//+--------------------------------------------------------------------+
// Log Modifiche 
// v1.0 (22 Gen 2006) : Inizio progetto

#property copyright "Copyright © 2007, Skyline"
#include <stdlib.mqh>

//---- Definizione parametri esterni 
extern int     MagicNumber      = 123456;
extern bool    MM               = false;
extern double  FixedLOT         = 0.3;
extern int     Risk             = 2;
extern int     CloseALLOrdersAt = 17;   // Ora in cui vengono chiusi tutti gli ordini
extern int     TakeProfit       = 180;    // Takeprofit espresso in pips
extern int     StopLoss         = 40; 
extern bool    UseBoxAsStopLoss = false;
extern int     TrailingStop     = 15;
extern int     EntryType        = 1; // 1 = Entra al breakout del box, 2 = Entra dopo la candela di 1) e quando l'open è sopra(sotto) il box, 
                                     // 3 = Aspetta 1) e 2) con 2 completamente fuori dal box e poi entra all'open della successiva candela
extern int     StartTimeBox     = 0;
extern int     EndTimeBox       = 7;

//----- Definizione parametri interni 
int Slippage = 3;     // Massimo slippage consentito per piazzare un ordine

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   // Definizione Variabili
   double SL,Lots,TP,HighBox,LowBox;
   int    Ticket,Errore;
   datetime Inizio,Fine;
   int StartBar,EndBar;  
   
   // Chiude tutti gli ordini quando scadono le EOD 
   if (Hour()>=CloseALLOrdersAt)
   {
    ChiudeOrdiniAperti(CloseALLOrdersAt);
   }

   // Calcola Box 
   Inizio  = StrToTime(Year()+"."+Month()+"."+Day()+" "+StartTimeBox+":00");
   Fine    = StrToTime(Year()+"."+Month()+"."+Day()+" "+EndTimeBox+":00"); 
   StartBar = iBarShift(NULL,0,Inizio,true);
   EndBar   = iBarShift(NULL,0,Fine,true);
   HighBox  = High[iHighest(NULL,0,MODE_HIGH,StartBar-EndBar,EndBar+1)];
   LowBox   = Low[iLowest(NULL,0,MODE_LOW,StartBar-EndBar,EndBar+1)];
   
     
   // Calcola dimensione Lot in base all'Equity
   if (MM==true) Lots = CalcolaLot(Risk);
   else Lots = FixedLOT;
   
   // Commenti vari //
   Comment(
           "\nMax Lot allowed by actual broker = ",MarketInfo(Symbol(),MODE_MAXLOT),
           "\nMin Lot allowed by actual broker = ",MarketInfo(Symbol(),MODE_MINLOT),
           "\nHighBox = ",DoubleToStr(HighBox,Digits),
           "\nLowBox = ",DoubleToStr(LowBox,Digits)
          );
      
   int total = OrdersTotal();
   
   if(total<1 && Hour()<CloseALLOrdersAt) // al massimo 1 ordine
   {           
    // Controlla BUY Order
    if (
       (
        CheckBuyOrder()==0             && 
        OrdiniChiusiSullaCandela()==0  && 
        EntryType == 1                 &&
        Ask >= HighBox+(0.0003)                 &&
        Hour()>8                     
       )
       ||
       (
        CheckBuyOrder()==0             && 
        OrdiniChiusiSullaCandela()==0  && 
        EntryType == 2                 &&
        Low[1]<=HighBox                && High[1]>=HighBox &&
        Open[0] > HighBox              &&
        Hour()>8                   
       )
       ||
       (
        CheckBuyOrder()==0             && 
        OrdiniChiusiSullaCandela()==0  && 
        EntryType == 3                 && 
        Low[2]<=HighBox                && High[2]>=HighBox &&
        Low[1]>HighBox                 &&
        Open[0]>HighBox                &&
        Hour()>8                    
       )         
       )
     {
      if (UseBoxAsStopLoss == true) {SL = LowBox;}
      else { SL = Ask-StopLoss*Point; }
      if (TakeProfit == 0) TP = 0;
      else TP = Ask+TakeProfit*Point;
      Ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,"SRDC III BUY ORDER",MagicNumber,0,Blue);
      if(Ticket<0)
      {
       Errore=GetLastError();
       Print("error BUYSTOP (",Errore,") : ",ErrorDescription(Errore));
      }   
     } 
      
     // Controlla SELL Order
    if (
       (
        CheckSellOrder()==0            && 
        OrdiniChiusiSullaCandela()==0  && 
        EntryType == 1                 &&
        Bid <= LowBox-(0.0003)                  &&
        Hour()>8                     
       )
       ||
       (
        CheckSellOrder()==0            && 
        OrdiniChiusiSullaCandela()==0  && 
        EntryType == 2                 &&
        Low[1]<=LowBox                 && High[1]>=LowBox &&
        Open[0] < LowBox               &&
        Hour()>8                      
       )
       ||
       (
        CheckSellOrder()==0            && 
        OrdiniChiusiSullaCandela()==0  && 
        EntryType == 3                 && 
        Low[2]<=LowBox                 && High[2]>=LowBox &&
        Low[1]<LowBox                  &&
        Open[0]<LowBox                 &&
        Hour()>8                      
       )         
       )
     {
      if (UseBoxAsStopLoss == true) {SL = HighBox;}
      else { SL = Bid+StopLoss*Point; }
      if (TakeProfit == 0) TP = 0;
      else TP = Bid-TakeProfit*Point;  
      Ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,"SRDC III SELL ORDER",MagicNumber,0,Blue);
      if(Ticket<0)
      {
       Errore=GetLastError();
       Print("error SELLSTOP(",Errore,") : ",ErrorDescription(Errore));
      } 
     }    
    } // if (total<1)
    TrailingStop(); 
   return(0);
  }

// ===== Routine per controllare ordini BUY aperti =====
int CheckBuyOrder()
{ int i,Bought=0;
   for (i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()==OP_BUY && OrderMagicNumber()==MagicNumber) Bought++;
   }
   return(Bought);
}

// ===== Routine per controllare ordini SELL aperti =====
int CheckSellOrder()
{ int i,Sold=0;
   for (i=0;i<OrdersTotal();i++)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()==OP_SELL && OrderMagicNumber()==MagicNumber) Sold++;
   }
   return(Sold);
}

// ===== Routine per chiudere precedenti ordini aperti allo scadere di EOD =====

void ChiudeOrdiniAperti(int EndOfDay)
{int total,cnt;
 
 total = OrdersTotal();
 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  
}

// ===== Routine per evitare di aprire più ordini sulla stessa candela H1 =====
int OrdiniChiusiSullaCandela()
{int i;
 int OrdiniChiusi=0;
 int hstTotal=HistoryTotal();
 int Bar;
 for(i=0;i<hstTotal;i++)
 {
  //---- check selection result
  if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
  {
   Bar = iBarShift(NULL,0,OrderCloseTime());   
   if (Time[Bar]==Time[0]) OrdiniChiusi++;
  } 
 }
 return(OrdiniChiusi);
}

// ===== Routine per il calcolo del Lot nel caso di 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); } // Max numero di Lot permessi dal broker  
  if (Lot < MarketInfo(Symbol(),MODE_MINLOT)) { Lot = MarketInfo(Symbol(),MODE_MINLOT); } // Min numero di Lot permessi dal broker  
 return(Lot);
}




// ===== Routine to handle the Trailing Stop automatically  =====
void TrailingStop()
{  int cnt,err;
   int total = OrdersTotal();
   for(cnt=0;cnt<total;cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
       if(OrderType()==OP_BUY && OrderMagicNumber()==MagicNumber)   // 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();
                      if (err>1) Print("error(",err,"): ",ErrorDescription(err));
                     }
                     else return(0);
                    }
                 }
               }
          } // if(OrderType()==OP_BUY)  
         if(OrderType()==OP_SELL && OrderMagicNumber()==MagicNumber)   // Short position is opened
           {
            // 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();
                      if (err>1) Print("error(",err,"): ",ErrorDescription(err));
                     }
                     else return(0);                     
                    }
                 }
               } // if(TrailingStop>0)  
           }// if(OrderType()==OP_BUY) 
     }  // for 
}









//+------------------------------------------------------------------+