//+------------------------------------------------------------------+
//|                                         WUKAR_WB_Trail_v1.3e.mq4 |
//| Orignals WUKAR.mq4 and Wheelbarrel Trailing_v1.2.mq4             |
//| are merged. Credit goes to the original authors                  |
//--------------------------------------------------------------------

#include <stdlib.mqh>
#include <stderror.mqh>
#include <WinUser32.mqh> 

extern string  TP_SL_Settings          = "覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern bool    UseHiddenStopLoss       = true;
extern int     HiddenSL                = 100;
extern bool    UseEmergencyStopLoss    = true;
extern int     EmergencySL             = 150;
extern bool    UseHiddenTakeProfit     = true;
extern int     HiddenTP1               = 50;
extern string  Trailingstop_Settings   = "覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern bool    ProfitTrailing          = true;  
extern bool    UseHiddenTrailingStop   = true;
extern int     TrailingStop            = 35;    
extern int     TrailingStep            = 1;     
extern bool    UseSound                = false;  
extern string  NameFileSound           = "cork_pop.wav";  
extern string  Breakeven_Settings      = "覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern string  BE                      = "Break even settings";
extern bool    BreakEven               = true;
extern bool    UseHiddenBreakEven      = true;
extern int     BreakEvenPips           = 35;
extern string  Line_Settings           = "覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern string  LS                      = "Line settings";
extern bool    DrawLines               = true;
extern color   TPColor                 = Green;
extern color   SLColor                 = Red;
extern color   BEColor                 = Yellow;
extern color   TSColor                 = Magenta;
extern color   TextColor               = DimGray;
extern int     ShiftLabel              = 1;
extern bool    FullScreenLines         = true;
extern string  FSL                     = "If False, lines start at current bar";
extern string  Other_Settings          = "覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern string  OS                      = "Other settings";
extern double  Commission              = 7;
extern bool    DeleteOCO               = true;
extern string  OCO_Comment             = "Will delete remaining Pending orders";

double HSL, HTP, HBE, HTS, BEPrice;
string ObjPref = "WUKAR_";
int    LineType;
color  LineColor;
bool   IsTrade;

//+------------------------------------------------------------------+
void init()
{
   if(FullScreenLines)
      LineType = OBJ_HLINE;
   else
      LineType = OBJ_TREND;
}

//+------------------------------------------------------------------+
void deinit()
{
//   DeleteAllLines();
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void start() 
{
   IsTrade = false;
   bool result = false;
   int PendingOrder = 0;
   int totalorders = OrdersTotal();
   for(int i=totalorders-1; i>=0; i--)
   {
      result = OrderSelect(i, SELECT_BY_POS);
      if(OrderType() > OP_SELL && OrderSymbol()==Symbol())
         PendingOrder = OrderTicket();
      
      if(OrderType() <= OP_SELL && OrderSymbol()==Symbol())
      {
         IsTrade = True;

         TrailingPositions();
         
         if(UseHiddenStopLoss)
            HiddenStopLoss();
         if(UseHiddenTakeProfit)
            HiddenTakeProfit();  
         if(UseEmergencyStopLoss)
            EmergencyStopLoss();
      }
      
      if(IsTrade && DeleteOCO && PendingOrder > 0)
         OrderDelete(PendingOrder);
   }
   if(!IsTrade)
   {
      DeleteAllLines();
      HSL = 0;
      HTP = 0;
      HBE = 0;
      HTS = 0;
      BEPrice = 0;
   }
   
//   Comment("\n\n\n\n\n\n\n\nIsTrade = ",IsTrade,"\nHBE=",HBE,"\nHTS=",HTS);
   
   return;

  /* Do not uncomment the below. It does not do anything useful except to
  open orders, so as to test, trail stop, tp aand stop loss of the two EAs 
  merged. Its a work around to test the EA is working in the tester. thats all */
  
  // OpenPosition();    
}


//+------------------------------------------------------------------+
void TrailingPositions()
{
   double pBid, pAsk, pp;
   
   RefreshRates();
   pp = MarketInfo(OrderSymbol(), MODE_POINT);
   double NewStop = 0 ;

   if(ObjectFind("HBE line") == 0 && HBE == 0)
      HBE = ObjectGetDouble(0,"HBE line",OBJPROP_PRICE,0);
   if(ObjectFind("HTS line") == 0 && HTS == 0)
      HTS = ObjectGetDouble(0,"HTS line",OBJPROP_PRICE,0);

   if(OrderType()==OP_BUY)
   {
      pBid = MarketInfo(OrderSymbol(), MODE_BID);
      if((HBE != 0.0 && pBid <= HBE) || (HTS != 0.0 && pBid <= HTS))
      {
         OrderClose(OrderTicket(), OrderLots(), pBid, 5, Red);
         return;
      }   
      
      if(BreakEven == true
       && HBE == 0.0
       && BEPrice == 0.0
       && pBid > OrderOpenPrice() + BreakEvenPips * pp)
         BEPrice = OrderOpenPrice() + Commission * pp ;

      if(ProfitTrailing == true
       && pBid - OrderOpenPrice() >= (TrailingStop  + TrailingStep)* pp)
         NewStop = pBid - TrailingStop * pp ;
   }
   
   if (OrderType()==OP_SELL) 
   {
      pAsk = MarketInfo(OrderSymbol(), MODE_ASK);
      if((HBE != 0.0 && pAsk >= HBE) || (HTS != 0.0 && pAsk >= HTS))
      {
         OrderClose(OrderTicket(), OrderLots(), pAsk, 5, Red);
         return;
      }   
      
      if(BreakEven == true
       && HBE == 0.0
       && BEPrice == 0.0
       && pAsk < OrderOpenPrice() - BreakEvenPips * pp 
      ) 
         BEPrice = OrderOpenPrice() - Commission * pp ;
         
      if(ProfitTrailing == true
       && OrderOpenPrice() - pAsk >= (TrailingStop  + TrailingStep)* pp  
       ) 
         NewStop = pAsk + TrailingStop * pp ;
   }

   if(BEPrice != 0)
   {
      if(UseHiddenBreakEven)
      {
         if(HBE == 0)
            HBE = BEPrice;
         if(DrawLines)
         {
            LineColor = BEColor;
            DrawLine("HiddenBE label", "HBE", "HBE line", LineType, LineColor, HBE);
         }
      }
      else
         if(ModifyStopLoss(BEPrice)) 
         {
            Print("WUKAR_WB Modified Stop Loss");
            BEPrice = 0;
         }

   }
   
   if(NewStop != 0)
   {   
      if(UseHiddenTrailingStop)
      {
         if((OrderType()==OP_BUY && HTS < NewStop) || (OrderType()==OP_SELL && HTS > NewStop) || HTS == 0)
            HTS = NewStop;
         if(DrawLines)
         {
            LineColor = TSColor;
            DrawLine("HiddenTS label", "HTS", "HTS line", LineType, LineColor, HTS);
         }
      }
      else
         if((OrderType()==OP_BUY && OrderStopLoss() < NewStop) || (OrderType()==OP_SELL && OrderStopLoss() > NewStop))
            if(ModifyStopLoss(NewStop)) 
               Print("WUKAR_WB Modified Stop Loss");
   }
   
   if(ObjectFind(0,"HTS line") == 0 && ObjectFind(0,"HBE line") == 0)
   {
      ObjectDelete(0,"HBE line");
      ObjectDelete(0,"HiddenBE label");
   }
      
   return;
}
    
//+------------------------------------------------------------------+
bool ModifyStopLoss(double ldStopLoss) 
{
   bool fm; 
   fm=OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE);
   if(fm && UseSound) 
      PlaySound(NameFileSound);
   if(!fm)
   {
      int err;
      err=GetLastError();
      Print("Wheelbarrel trailing error (",err,")");
      return false;
   }
   return true;
}
//+------------------------------------------------------------------+
void HiddenTakeProfit()
{ 
   bool result = false;  
   if (OrderSymbol()==Symbol()) 
   {
      if(OrderType() == OP_BUY)
      {
         HTP = OrderOpenPrice()+(HiddenTP1+Commission)*Point;
         if(Bid >= HTP)
            result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(Symbol(), MODE_BID), 5, Red);
      }
      
      if(OrderType() == OP_SELL)
      {  
         HTP = OrderOpenPrice()-(HiddenTP1+Commission)*Point;
         if(Ask <= HTP)
            result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(Symbol(), MODE_ASK), 5, Red);  
      }
      
      if(DrawLines)
      {
         LineColor = TPColor;
         DrawLine("HiddenTP label", "HTP", "HTP line", LineType, LineColor, HTP);
      }
   }
   return;
}
//+-------------------------------------------------------------------------------------------+
void HiddenStopLoss()
{ 
   bool result = false;
   if(OrderSymbol() == Symbol()) 
   {
      if(OrderType() == OP_BUY)  
      {
         HSL = OrderOpenPrice()-HiddenSL*Point;
         if(HSL >= Bid)
            result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(Symbol(), MODE_BID), 5, Red);
      }

      if(OrderType() == OP_SELL)
      {
         HSL = OrderOpenPrice()+HiddenSL*Point;
         if(HSL <= Ask)
            result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(Symbol(), MODE_ASK), 5, Red);    
      }
      
      if(DrawLines)
      {
         LineColor = SLColor;
         DrawLine("HiddenSL label", "HSL", "HSL line", LineType, LineColor, HSL);
      }
   }
   return;
}

//+-------------------------------------------------------------------------------------------+
void EmergencyStopLoss()
{
   int totalorders = OrdersTotal();

   for(int i=totalorders-1; i>=0; i--)
   {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      bool result = false;

      if(OrderSymbol()==Symbol())
      {
         if(OrderType() == OP_BUY && OrderStopLoss()== 0.0)
            result = OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-EmergencySL*Point,OrderTakeProfit(),0,clrNONE);
         if(OrderType() == OP_SELL && OrderStopLoss()== 0.0)
            result = OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+EmergencySL*Point,OrderTakeProfit(),0,clrNONE);
      }
   }
   return;
}

//+-------------------------------------------------------------------------------------------+
void OpenPosition()
{
int ans=0;     
     if(Open[0]>Close[0]) { 
     ans = OrderSend(Symbol(),OP_BUY,0.01,Ask,25,0,0,NULL,10,Blue ); //Opening Buy        
     }
     else
     {     
     ans = OrderSend(Symbol(),OP_SELL,0.01,Bid,25,0,0,NULL,10,Blue ); //Opening Buy  
     }
     if(ans<0)
        {
         Print("Error when opening a order #",GetLastError());
         Sleep(10000);
         return;
     }       
}

//+-------------------------------------------------------------------------------------------+
//| Subroutine to draw pivot lines and labels                                |                                                                                  |
//+-------------------------------------------------------------------------------------------+
void DrawLine(string LineLabel, string LineText, string TMLine, int LnType, color LnColor, double LinePrice)
   {
      if(ObjectFind(LineLabel) != 0)
      {
         ObjectCreate(LineLabel, OBJ_TEXT, 0, Time[0]+Period()*60*ShiftLabel, LinePrice);
         ObjectSetText(LineLabel, LineText, 8, "Arial", EMPTY);
      }
      else
      {
         ObjectMove(LineLabel, 0, Time[0]+Period()*60*ShiftLabel, LinePrice);
         ObjectSetText(LineLabel, LineText, 8, "Arial", EMPTY);
      }

      if(ObjectFind(TMLine) != 0)
      {
         ObjectCreate(TMLine, LnType, 0, Time[1], LinePrice, Time[0], LinePrice);
         ObjectSet(TMLine, OBJPROP_STYLE, STYLE_DASHDOTDOT);
         ObjectSet(TMLine, OBJPROP_COLOR, LnColor);
//         ObjectSet(TMLine, OBJPROP_RAY, true);
      }
      else
      {
         ObjectMove(TMLine, 0, Time[1], LinePrice);
         ObjectMove(TMLine, 1, Time[0], LinePrice);
      }
   }
//+------------------------------------------------------------------+
void DeleteAllLines()
{
   ObjectDelete(0,"HiddenSL label");
   ObjectDelete(0,"HSL line");
   ObjectDelete(0,"HiddenTP label");
   ObjectDelete(0,"HTP line");
   ObjectDelete(0,"HiddenBE label");
   ObjectDelete(0,"HBE line");
   ObjectDelete(0,"HiddenTS label");
   ObjectDelete(0,"HTS line");
   return;
}