//+------------------------------------------------------------------+
//|                                         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               = 60;
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           = "cash_register_x.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              = 0;
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()
  {
   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;
  }
//+------------------------------------------------------------------+
