// ------------------------------------------------------------------------------------------ //
//                  L I N E X C U T O R S  E X P E R T   A D V I S O R                        //
//                       Trades Executor based on 2 Lines Approach                            //
//                          by fosgate_r    © January 2009                                    //
//                      URL : http://forexfreeea.blogspot.com/                                //
// ------------------------------------------------------------------------------------------ //


#property  copyright "© January 2009 fosgate_r"
#property  link "http://forexfreeea.blogspot.com/"
#include <stdlib.mqh>


// ------------------------------------------------------------------------------------------ //
//                            E X T E R N A L   V A R I A B L E S                             //
// ------------------------------------------------------------------------------------------ //

extern   bool     ShowComment = true;
extern   double   LotSize     = 0.1;
extern   double   TakeProfit  = 50;
extern   double   StopLoss    = 30;
extern   double   PipLimit    = 3;
extern   double   PipWide     = 3;
extern   bool     OneTrade    = false;


// ------------------------------------------------------------------------------------------ //
//                            I N T E R N A L   V A R I A B L E S                             //
// ------------------------------------------------------------------------------------------ //

double   I_LineLevel, I_Hlimit, I_Llimit, I_Hlimit1, I_Llimit1;
double   II_LineLevel, II_Hlimit, II_Llimit, II_Hlimit1, II_Llimit1;
string   I_lineName="Linexcutor1", II_lineName="Linexcutor2";
string   strtmp, timstr, eacmd="LinexcutorsEA";
int      I_Magic=20090206, II_Magic=20090207;


// ------------------------------------------------------------------------------------------ //
//                             I N I T I A L I S A T I O N                                    //
// ------------------------------------------------------------------------------------------ //

int init()
{
   Comment("");
   return(0);    
}


// ------------------------------------------------------------------------------------------ //
//                            D E - I N I T I A L I S A T I O N                               //
// ------------------------------------------------------------------------------------------ //

int deinit()
{
   Comment("");
   return(0);
}


// ------------------------------------------------------------------------------------------ //
//                                M A I N   P R O C E D U R E                                 //
// ------------------------------------------------------------------------------------------ //

int start()
{

   // Check for Trendline and Determine the Limits
   // ============================================
   
   if (ObjectFind(I_lineName)<0) I_LineLevel = -1;
   else                          I_LineLevel = ObjectGetValueByShift(I_lineName,0);
   I_Hlimit=0; I_Llimit=0;
   if (I_LineLevel>0)
   {
      I_Hlimit  = I_LineLevel + (PipLimit*Point);
      I_Hlimit1 = I_Hlimit    + (PipWide *Point);
      I_Llimit  = I_LineLevel - (PipLimit*Point);
      I_Llimit1 = I_Llimit    - (PipWide *Point);
   }

   if (ObjectFind(II_lineName)<0)   II_LineLevel = -1;
   else                             II_LineLevel = ObjectGetValueByShift(II_lineName,0);
   II_Hlimit=0; II_Llimit=0;
   if (II_LineLevel>0)
   {
      II_Hlimit  = II_LineLevel + (PipLimit*Point);
      II_Hlimit1 = II_Hlimit    + (PipWide *Point);
      II_Llimit  = II_LineLevel - (PipLimit*Point);
      II_Llimit1 = II_Llimit    - (PipWide *Point);
   }

   // Trade Decision
   // ==============
   
   if (I_LineLevel>0)
   {
      if (Close[0]>I_Hlimit && Close[0]<I_Hlimit1)
      {
         if (OpenOrd(I_Magic)==0)   Buy(I_Magic,LotSize,TakeProfit,StopLoss);
         else
            if (OpenLast(I_Magic)==1)
            {   
                CloseOrders(I_Magic);
                if (OneTrade && OpenOrd(II_Magic)>0)    CloseOrders(II_Magic);
                Sleep(3000);
                Buy(I_Magic,LotSize,TakeProfit,StopLoss); 
            }
      }
      if (Close[0]<I_Llimit && Close[0]>I_Llimit1)
      {
         if (OpenOrd(I_Magic)==0)   Sell(I_Magic,LotSize,TakeProfit,StopLoss);
         else
            if (OpenLast(I_Magic)==0)
            {   
                CloseOrders(I_Magic); 
                if (OneTrade && OpenOrd(II_Magic)>0)    CloseOrders(II_Magic);
                Sleep(3000); 
                Sell(I_Magic,LotSize,TakeProfit,StopLoss); 
            }
      }
   }

   if (II_LineLevel>0)
   {
      if (Close[0]>II_Hlimit && Close[0]<II_Hlimit1)
      {
         if (OpenOrd(II_Magic)==0)   Buy(II_Magic,LotSize,TakeProfit,StopLoss);
         else
            if (OpenLast(II_Magic)==1)
            {   
                CloseOrders(II_Magic); 
                if (OneTrade && OpenOrd(I_Magic)>0)    CloseOrders(I_Magic);
                Sleep(3000); 
                Buy(II_Magic,LotSize,TakeProfit,StopLoss); 
            }
      }
      if (Close[0]<II_Llimit && Close[0]>II_Llimit1)
      {
         if (OpenOrd(II_Magic)==0)   Sell(II_Magic,LotSize,TakeProfit,StopLoss);
         else
            if (OpenLast(II_Magic)==0)
            {   
                CloseOrders(II_Magic); 
                if (OneTrade && OpenOrd(I_Magic)>0)    CloseOrders(I_Magic);
                Sleep(3000); 
                Sell(II_Magic,LotSize,TakeProfit,StopLoss); 
            }
      }
   }
      
   // Comments
   // ========
   
   timstr = "[" +TimeToStr(TimeCurrent())+ "]";
   strtmp = "\nLINEXCUTORS EA - © January 2009 fosgate_r  " +timstr;

   if (I_LineLevel<0)
         strtmp = strtmp + "\nTrendline " +I_lineName+ " Not Available !!!";
   else  strtmp = strtmp + "\n" +I_lineName+ " : " + DoubleToStr(I_LineLevel,Digits)
                         + " [" + DoubleToStr(I_Llimit,Digits)
                         + "-"  + DoubleToStr(I_Hlimit,Digits) + "] "
                         + " - Profit: $ " + DoubleToStr(CalcProfit(I_Magic),2)
                         + " - " + CalcPips(I_Magic) + " pips  - "
                         + "Last Order: " + OpenLast(I_Magic);  
   if (II_LineLevel<0)
         strtmp = strtmp + "\nTrendline " +II_lineName+ " Not Available !!!";
   else  strtmp = strtmp + "\n" +II_lineName+ " : " + DoubleToStr(II_LineLevel,Digits)
                         + " [" + DoubleToStr(II_Llimit,Digits)
                         + "-"  + DoubleToStr(II_Hlimit,Digits) + "] "
                         + " - Profit: $ " + DoubleToStr(CalcProfit(II_Magic),2)
                         + " - " + CalcPips(II_Magic) + " pips  - "
                         + "Last Order: " + OpenLast(II_Magic);
   
   if (ShowComment)  Comment(strtmp);
   else              Comment(timstr);
   return(0);
}


// ------------------------------------------------------------------------------------------ //
//                                 O R D E R S   S T A T U S                                  //
// ------------------------------------------------------------------------------------------ //

int OpenLast(int mgc)
{
   int   last=-1;
      
   for (int i = 0; i < OrdersTotal(); i++)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if (OrderMagicNumber() == mgc && OrderSymbol()==Symbol() && OrderType()<=1)
          last = OrderType();
   }      
   return(last);
}

int OpenOrd(int mgc)
{
   int      ord=0;
   
   for (int i = 0; i < OrdersTotal(); i++)
   {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if (OrderMagicNumber() == mgc && OrderSymbol()==Symbol() && OrderType()<=1)
          ord++;
   }      
   return(ord);
}


// ------------------------------------------------------------------------------------------ //
//                                 C A L C U L A T E    P I P S                               //
// ------------------------------------------------------------------------------------------ //

int CalcPips(int mgc)
{
   int pips = 0;
   double p = 0;
   
   for (int i=0; i<OrdersTotal(); i++)
   {
        OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
        if  (OrderMagicNumber()==mgc && OrderSymbol()==Symbol())
        {
            if (OrderType()==OP_BUY)
            {
               p = (Ask - OrderOpenPrice()) / Point;
               pips = pips + NormalizeDouble(p,0);
            }
            if (OrderType()==OP_SELL)
            {
               p = (OrderOpenPrice() - Bid) / Point;
               pips = pips + NormalizeDouble(p,0);
            }        
        }
   }   
   return(pips);
}


// ------------------------------------------------------------------------------------------ //
//                              C A L C U L A T E    P R O F I T                              //
// ------------------------------------------------------------------------------------------ //

double CalcProfit(int mgc)
{
   double profit = 0;
   for (int i=0; i<OrdersTotal(); i++)
   {
        OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
        if  (OrderMagicNumber()==mgc && OrderSymbol()==Symbol())
             profit = profit + OrderProfit() + OrderSwap();
   }   
   return(profit);
}


// ------------------------------------------------------------------------------------------ //
//                                  B U Y   F U N C T I O N                                   //
// ------------------------------------------------------------------------------------------ //

int Buy(int mgc, double lot,  double Tpft, double Slos)
{ 
    int     Ticket = 0, err = 0;
    double  TP = 0,      SL = 0;
    
    if (Tpft>0)   TP = NormalizeDouble(Ask + (Tpft*Point), Digits);
    if (Slos>0)   SL = NormalizeDouble(Ask - (Slos*Point), Digits);

    if (IsTradeAllowed() == true)
    {       
       for(int c=0; c<5; c++)
       {
          RefreshRates();
          Ticket = OrderSend(Symbol(),OP_BUY,lot,Ask,3,SL,TP,eacmd, mgc,0,Blue);
          err    = GetLastError();
          if(err==0)  break;
          else
          {
             Print("Errors opening BUY order");
             Print(ErrorDescription(err),", error ",err);
             if(err==4 || err==137 ||err==146 || err==136)   {Sleep(5000);continue;}
             else break; //normal error                               // Busy errors
          }
       }
    } 	    
    return(Ticket);
}


// ------------------------------------------------------------------------------------------ //
//                                S E L L   F U N C T I O N                                   //
// ------------------------------------------------------------------------------------------ //

int Sell(int mgc, double lot, double Tpft, double Slos)
{        
    int     Ticket = 0, err = 0;
    double  TP = 0,      SL = 0;
    
    if (Tpft>0)   TP = NormalizeDouble(Bid - (Tpft*Point), Digits);
    if (Slos>0)   SL = NormalizeDouble(Bid + (Slos*Point), Digits);

    if (IsTradeAllowed() == true)
    { 
       for(int c=0; c<5; c++)
       { 
         RefreshRates();
         Ticket = OrderSend(Symbol(),OP_SELL,lot,Bid,3,SL,TP,eacmd,mgc,0,Red);
         err    = GetLastError();
         if(err==0)  break;
         else
         {
            Print("Errors opening SELL order");
            Print(ErrorDescription(err),", error ",err);
            if(err==4 || err==137 ||err==146 || err==136)   {Sleep(5000);continue;} 
            else  break; //normal error                              // Busy errors
         }
       }
    } 	    
    return(Ticket);      
}


// ------------------------------------------------------------------------------------------ //
//                                  C L O S E  O R D E R S                                    //
// ------------------------------------------------------------------------------------------ //

void CloseOrders(int mgc)
{
      int cnt,c,total=0,ticket=0,err=0;
      
      if (IsTradeAllowed() == true)
      { 
       total = OrdersTotal();
       for(cnt=total-1;cnt>=0;cnt--)
       {
          OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

          if(OrderMagicNumber()==mgc && OrderSymbol()==Symbol())
          {
             switch(OrderType())
             {
                case OP_BUY      :
                   for(c=0;c<5;c++)
                   {
                      RefreshRates();
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,Yellow);
                      err = GetLastError();
                      if (err==0)   break;
                      else
                      {
                         Print("Errors Closing BUY order");
                         Print(ErrorDescription(err),", error ",err);
                         if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146)
                         { Sleep(5000); continue; }                            // Busy errors
                      }
                   }   
                   break;
               
                case OP_SELL     :
                   for(c=0;c<5;c++)
                   {
                      RefreshRates();
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,Yellow);
                      err = GetLastError();
                      if (err==0) break;
                      else
                      {
                         Print("Errors Closing SELL order");
                         Print(ErrorDescription(err),", error ",err);
                         if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146)
                         { Sleep(5000); continue; }                            // Busy errors
                      }
                   }   
                   break;
             } // end of switch
          } // end of if
       } // end of for
      }       
      return(0);
}

// ------------------------------------------------------------------------------------------ //
//                        E N D   O F   E X P E R T   A D V I S O R                           //
// ------------------------------------------------------------------------------------------ //

