//+------------------------------------------------------------------+
//|                                                      RTEntry.mq4 |
//|                                                      Ted Goulden |
//|                                                                  |
// An EA that places orders on a retrace of price to a particular 
// moving average in the direction of that particular time frame trend. 
// For example, price is falling falling, 
// and retraces to ema 10. The ea is set to place a sell order on a touch 
// of 10... or 20, or 60 as the case may be. 
// An ideal EA could also be set to alert only, and serve as an indicator
//
// Input Parameters:
//
// SetupRange - the minimum number of pips in the move.
// SetupBars - the maximum number of time periods in the move.
// EMA - the number of periods for the EMA. Crossing the EMA after the
// move triggers the order entry.
// AlertOnly - flag set to disable order entry and to only send alerts
// about the EMA crossing.
//
// Modification History:
// Oct 18 09 - Ted Goulden, Initial Version
//
//+------------------------------------------------------------------+
#property copyright "Ted Goulden"
#property link      ""


#define MAGICRT 20091018
#define RTPD 20


//---- input parameters
extern int       SetupRange=70;
extern int       SetupBars=10;
extern int       EMA=10;
extern bool      AlertOnly=false;
extern double    Lots=0.1;
extern double    Slippage=2;

// static variables  
datetime          barStart = 0, setupTime = 0, orderTime = 0;
int               totOpen = 0;
int               widthOK = 0;
bool              setupOK = false, orderOpen = false, long = true;
double            barHigh, barLow;
double            pips, pipv, pf = 1., ff = 1.;

	
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{

// conversion factors for 4 and 5 digit systems.

   pips = MarketInfo(Symbol(), MODE_TICKSIZE);
   if (Digits < 4)
      {
       pf = (0.01/pips);
       ff = (pips/0.001);
       }
   if (Digits > 3)
      {
       pf = (0.0001/pips);
       ff = (pips/0.00001);
       }
     
   return(0);
}


//+------------------------------------------------------------------+
//| expert deinitialization function - close the PENDING orders      |
//+------------------------------------------------------------------+
int deinit()
{
//----

//----
   return(0);
} // deinit
  
  
//+------------------------------------------------------------------+
//| Place Orders function to open BUY and SELL               |
//+------------------------------------------------------------------+
  
bool PlaceMktOrder( bool long)
{
   
 
 // Long 
   if (long)
      {
     int ticket1 = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, "RT BUY", MAGICRT, 0, Green);
         if(ticket1>0)
         {
            if(OrderSelect(ticket1,SELECT_BY_TICKET,MODE_TRADES)) 
              Alert(Symbol(), " BUY order opened : ", OrderPrint());
         }
         else 
         {
         Print("Error opening BUY  order : ",GetLastError(), " = ", Ask, ", ",Low[1], ", "); 
         return (false);
         }
   }
   else
   {
   
     int ticket2 = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, 0, 0, "RT SELL", MAGICRT, 0, Green);
         if(ticket2>0)
         {
            if(OrderSelect(ticket2,SELECT_BY_TICKET,MODE_TRADES)) 
              Alert(Symbol() , " SELL order opened : ",  OrderPrint());
         }
         else 
         {
         Print("Error opening SELL order : ",GetLastError(), " = ", Bid, ", ", High[1], ", "); 
         return (false);
         }
   }
   return (true);
}  




//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----

   if (barStart < Time[0] && setupTime == 0 && !orderOpen) //start of new bar 
   {
      barStart = Time[0];
      setupOK = false;
      double maxRange = High[ArrayMaximum(High, SetupBars, 0)]/Point - Low[ArrayMinimum(Low, SetupBars, 0)]/Point;
      if (maxRange > SetupRange*pf)
      {
         if (High[0] - Low[SetupBars] > 0) long = true;
         else long = false;  
         setupOK = true;
         setupTime = Time[0];
      }  
       
   } // end if barstart  
   
   
   if (setupOK)
   {
   
      if (EMA > 0) double emaVal = iMA(NULL, 0, EMA, 0, MODE_EMA, PRICE_MEDIAN, 0);
       
      if (long && Ask < emaVal + Point && !orderOpen)
      {
         if (AlertOnly) Alert(Symbol(), " Buy order signal : ", Ask);
         else if (PlaceMktOrder(long)) 
         {
            orderTime = Time[0];
            orderOpen = true;
            totOpen++;
         }
      }   // end if long && ask
      
      if (!long && Bid > emaVal + Point && !orderOpen)
      {
         if (AlertOnly) Alert(Symbol(), " Sell order signal : ", Bid);
         else if (PlaceMktOrder(long))
         { 
            orderTime = Time[0];
            orderOpen = true;
            totOpen++;
         }
      }   // end if !long && Bid
      
     if (MathCeil((Time[0] - orderTime)/(Period()*60)) > SetupBars) orderOpen = false;
      
     if (MathCeil((Time[0] - setupTime)/(Period()*60)) > SetupBars) setupTime = 0;
   
   } // if setup OK           
        
//----
   return(0);
}// end start()
//+------------------------------------------------------------------+--------------------------------------------+---------+