//+------------------------------------------------------------------+
//|                                                     OrdMgrTP.mq4 |
//|                                                      Ted Goulden |
//|                                                                  |
//  An EA that takes profits upon touching __ ema (fill in space). 
// The ideal TP function would also have a partial close function and
// a pip count function. 
//
// Input Parameters:
//
// TakeProfitEMA1 - the number of periods to be used by the EMA calculation.
// TakeProfitPips - .the number of pips for the TakeProfit value
// Lotsize - Part of the order can be closed. 0 means close the all lots. 
//
// Modification History:
// Oct 26 09 - Ted Goulden, Initial Version

//+------------------------------------------------------------------+

#property copyright "Ted Goulden"
#property link      ""

#define SLIP 2

extern int       TakeProfitPips=30;
extern int       TakeProfitEMA1=10;
extern double    Lotsize=0;



datetime          barStart = 0;
double            pips, pipv, pipf = 1., ff = 1.;
int               totOpen = 0;
bool              buy1 = false, sell1 = false;


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
   pips = MarketInfo(Symbol(), MODE_TICKSIZE);
   if (Digits < 4)
      {
       pipf = (0.01/pips);
       ff = (pips/0.001);
       }
   if (Digits > 3)
      {
       pipf = (0.0001/pips);
       ff = (pips/0.00001);
       }
    

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }

//+------------------------------------------------------------------+
//| Close Order function - close order specified by POS                                          |
//+------------------------------------------------------------------+
bool closeOrder(int pos, double lotsize)
{
        
   if(OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) 
   {
      int ticket = OrderTicket();
   
      if (lotsize == 0) double lots = OrderLots();
      else lots = lotsize;
      
      if (OrderType() == OP_BUY)
      { 
         OrderClose(ticket, lots, NormalizeDouble(Bid,Digits), SLIP, Violet); 
         if (GetLastError() == 0)
         { 
            Print(Symbol(), " Order Closed : ",ticket, " ", OrderClosePrice());
            return (true);
         }   
         else Print(Symbol(), " Order Not Closed : ",ticket, " ", GetLastError());
     }

      if (OrderType() == OP_SELL)
      {
         OrderClose(ticket, lots, NormalizeDouble(Ask,Digits), SLIP, Violet); 
         if (GetLastError() == 0)
         { 
            Print(Symbol(), " Order Closed : ",ticket, " ", OrderClosePrice());
            return (true);
         }   
         else Print(Symbol(), " Order Not Closed : ",ticket, " ", GetLastError());

      }
   }
   
   return (false);
}

//+------------------------------------------------------------------+
//| Modidfy Order function -  adjust Take Profit                                          |
//+------------------------------------------------------------------+
bool modOrder(int pos, double pipf, double takeProfit)
{
        
   double spread = MarketInfo(Symbol(),MODE_SPREAD)*Point;
   double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL)*Point;   
  
   if(OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) 
   {

      int ticket = OrderTicket();
      double openPrice = OrderOpenPrice();
   
    if (OrderType() == OP_BUY)
   { 
     double adjustTP = OrderOpenPrice() + takeProfit;
     if (adjustTP > Bid + spread + stopLevel)// check the Buy TP is OK
      OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), adjustTP, 0, Green);

   } // if == OP_BUY
      
   if (OrderType() == OP_SELL)
   {
      adjustTP = OrderOpenPrice() - takeProfit;
      if (adjustTP < Ask - spread - stopLevel)// check the Sell TP is OK
       OrderModify(ticket, OrderOpenPrice(), OrderStopLoss(), adjustTP, 0, Red);
  
   } // if == OP_SELL
      
              
   } // if OrderSelect        
   else Print (pos, ": ", "Serious error in modify order = ", GetLastError());  

   return(false);
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----
     if (TakeProfitEMA1 > 0) double EMA1 = iMA(NULL, 0, TakeProfitEMA1, 0, MODE_EMA, PRICE_MEDIAN, 0);

      double TP = TakeProfitPips*pipf*Point;   // for both 4 and 5 digit systems
      
    
   // check on open orders to adjust Take Profit
   
      int allOrders=OrdersTotal();

      for(int pos=allOrders-1;pos==0;pos--)
      {
         if(OrderSelect(pos,SELECT_BY_POS, MODE_TRADES))
         {
            if ((OrderSymbol() == Symbol()) && (OrderType() == OP_BUY || OrderType() == OP_SELL))
            {
     // Have found an open order for this pair.
     // May have to close.
               double openPrice = OrderOpenPrice();
               if (TP > 0 && NormalizeDouble( TP, Digits) != MathAbs(OrderTakeProfit() - openPrice))
                   modOrder( pos, pipf, TP);
                   
               if (Bid + Point > EMA1 && EMA1 > 0 && openPrice < EMA1 && OrderType() == OP_BUY && !buy1) 
               {
                  if (closeOrder(pos, Lotsize)) buy1 = true;
               }   
               
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
               if (Ask - Point < EMA1 && EMA1 > 0 && openPrice > EMA1 && OrderType() == OP_SELL && !sell1) 
               {
                  if (closeOrder(pos, Lotsize)) sell1 = true;
               }   
               
               
             } // end if OrderSymbol   
          } // end if OrderSelect     
       } // end for        
   
//----
   return(0);
}
//+------------------------------------------------------------------+