Click-and-drag take profit and stop loss EA

Author: Steve Hopwood
Orders Execution
Checks for the total of open ordersIt can change open orders parameters, due to possible stepping strategy
Miscellaneous
It opens Message Boxes to the user
0 Views
0 Downloads
0 Favorites
Click-and-drag take profit and stop loss EA
//+------------------------------------------------------------------+
//|                  Click-and-drag take profit and stop loss EA.mq4 |
//|                                                    Steve Hopwood |
//|                                     www.hopwood3.freeserve.co.uk |
//+------------------------------------------------------------------+
#property copyright "Steve Hopwood"
#property link      "www.hopwood3.freeserve.co.uk"
#include <OrderReliable.mqh>
#define  NL    "\n"
#define GlobalPrefix "CDTN_TicketNumber"

/*
void SetStop()
void SetTp()
void DetectTrade()

*/

      
extern int        TicketNo;
extern bool       AutoDetectTrade=true;
extern bool       LeaveRunningAfterTradeCloses=false;
extern int        InstantTp=3000;
extern int        InstantSl=3000;
extern bool       TpLineCanCloseTrade=false;
extern color      Color.TakeProfit = Green;
extern color      Color.StopLoss = Red;

string            GvName;
double            SL,TP;
bool              RobotSuspended = false;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
      
      //Check for open trades
      if (OrdersTotal() == 0)
      {
         MessageBox("No trades in place, so this robot will do nothing and needs removing.");
         Comment("No trades in place, so this robot will do nothing and needs removing.");
         RobotSuspended = true;
         return;         
      }//if (OrdersTotal() == 0)
      
      //Auto-detect trade routine
      if (AutoDetectTrade) DetectTrade();
      
      GvName = StringConcatenate(GlobalPrefix, DoubleToStr(TicketNo,0));
      GlobalVariableSet(GvName, TicketNo);
      
      //Delete the global if the trade does not exist, as the user has made a mistake with the ticket number
      TicketNo = GlobalVariableGet(GvName);
      if (!OrderSelect(TicketNo, SELECT_BY_TICKET, MODE_TRADES))
      {
         GlobalVariableDel(GvName);
         string message = StringConcatenate("Trade no ", DoubleToStr(TicketNo,0), " does not exist",NL,"This robot will do nothing, and needs removing");
         MessageBox(message);
         Comment(message);
         RobotSuspended = true;
         return;         
      }//if (!OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)
      
      //Check the ea has been dragged onto the correct chart for the trade
      if (Symbol() != OrderSymbol())
      {
         MessageBox("Incorrect chart for the trade, so this robot will do nothing and needs removing.");
         Comment("Incorrect chart for the trade, so this robot will do nothing and needs removing.");
         RobotSuspended = true;
         return;              
      }//if (Symbol() != OrderSymbol()
      
      
      //Make ea draw tp and sl lines if these are already in place
      TP = OrderTakeProfit();
      SL = OrderStopLoss();
      if (TP != 0 || SL !=0)
      {
         DrawTakeStopLines();
      }//if (TP != 0 || SL !=0
      
      
      start();
      
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   Comment("");
   DeleteEAObjects(GlobalPrefix + "L"); //Ensure all previous Line Objects are deleted
   GlobalVariableDel(GvName);

//----
   return(0);
}

bool DetectTrade()
{
   //Finds the ticket number of an open trade.
   //Only called if OedersTotal() > 0
   
   for (int cc = OrdersTotal(); cc >= 0; cc--)
   {
      OrderSelect(cc, SELECT_BY_POS);
      if (OrderSymbol() == Symbol())
      {
         TicketNo = OrderTicket();
         return(true);
      }//if (OrderSymbol == Symbol())
      
   
   }//for (int cc = OrdersTotal(); cc >= 0; cc--)
   
   //Got this far, so no open trade
   return(false);
   
}//bool DetectTrade()


//+------------------------------------------------------------------+
//| Delete Objects that match ObjName                                |
//+------------------------------------------------------------------+
void DeleteEAObjects(string ObjName)
{
   for (int i=ObjectsTotal()-1; i >= 0; i--) 
   {
     string name = ObjectName(i);
     if (StringFind(name, ObjName) > -1) ObjectDelete(name);
   }
}//End void DeleteEAObjects(string ObjName)

//+------------------------------------------------------------------+

void DrawTakeStopLines()
{
   DeleteEAObjects(GlobalPrefix + "L"); //Ensure all previous Line Objects are deleted

   
   int StartTime;
   if(TimeDayOfWeek(TimeCurrent()) == 1) StartTime = 2;
   else StartTime = 1;
   CreateLine(GlobalPrefix + "LIDHI1",Time[StartTime], Time[0],TP,TP,Color.TakeProfit,1); 
   string DisplayPrice = StringConcatenate("Take Profit ", TP);
   
   CreateLine(GlobalPrefix + "LIDLO1",Time[StartTime], Time[0],SL,SL,Color.StopLoss,1); 
   DisplayPrice = StringConcatenate("Stop loss ", SL);
   
}//End void DrawFiboLines()

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

void CreateLine(string name,datetime tfrom, datetime tto, double pfrom, double pto, color Col, int width)
{
         if(ObjectFind(name) != 0)
         {
            ObjectCreate(name, OBJ_HLINE, 0, tfrom, pfrom,tto,pto);
            
            ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID);
            
            ObjectSet(name, OBJPROP_COLOR, Col);
            //ObjectSet(name,OBJPROP_WIDTH,width);
            //ObjectSet(name,OBJPROP_RAY,RayLine);
         }
         else
         {
            ObjectDelete(name);
            ObjectCreate(name, OBJ_HLINE, 0, tfrom, pfrom,tto,pto);
            
            ObjectSet(name, OBJPROP_STYLE, STYLE_SOLID);
            
            //ObjectSet(name, OBJPROP_COLOR, Col);        
            //ObjectSet(name,OBJPROP_WIDTH,width);
            //ObjectSet(name,OBJPROP_RAY,RayLine);
         }
}//End void CreateLine(string name,datetime tfrom, datetime tto, double pfrom, double pto, int width, color Col)



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+


void SetStop()
{
   //Sets up a stop when none exists
   
   if (OrderType() == OP_BUY)
   {
      SL = NormalizeDouble(Ask - (InstantSl * Point),Digits);
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT)
   {
      SL = NormalizeDouble(OrderOpenPrice() - (InstantSl * Point),Digits);
   }//if (OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT)
      
   if (OrderType() == OP_SELL)
   {
      SL = NormalizeDouble(Bid + (InstantSl * Point),Digits);
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT)
   {
      SL = NormalizeDouble(OrderOpenPrice() + (InstantSl * Point),Digits);
   }//if (OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT)
   
   
}//End void SetStop()

void SetTp()
{
   //Sets up a tp when none exists
   
   if (OrderType() == OP_BUY)
   {
      TP = NormalizeDouble(Ask + (InstantTp * Point),Digits);
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT)
   {
      TP = NormalizeDouble(OrderOpenPrice() + (InstantTp * Point),Digits);
   }//if (OrderType() == OP_BUYSTOP || OrderType() == OP_BUYLIMIT)
       
   if (OrderType() == OP_SELL)
   {
      TP = NormalizeDouble(Bid - (InstantTp * Point),Digits);
   }//if (OrderType() == OP_BUY)
   
   if (OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT)
   {
      TP = NormalizeDouble(OrderOpenPrice() - (InstantTp * Point),Digits);
   }//if (OrderType() == OP_SELLSTOP || OrderType() == OP_SELLLIMIT)
   
}//End void SetStop()


//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   
   if (RobotSuspended) return;//Nothing to do
   
   // In case user has selected LeaveRunningAfterTradeCloses but there are no open trades to monitor
   if (OrdersTotal() == 0)
   {
      MessageBox("No trades in place, so this robot will do nothing and needs removing.");
      Comment("No trades in place, so this robot will do nothing and needs removing.");
      return;         
   }//if (OrdersTotal() == 0)

   
   //Check whether the gv has been removed.
   //If so, either close down or continue to look for an open trade
   if (!GlobalVariableCheck(GvName))
   {
      if (!LeaveRunningAfterTradeCloses)
      {
         MessageBox("Nothing to do, so this robot has stopped and needs removing.");
         Comment("                                 This robot has stopped and needs removing");
         RobotSuspended = true;
         return;

      }//if (!LeaveRunningAfterTradeCloses   )
      if (LeaveRunningAfterTradeCloses)
      {
         //Auto-detect trade routine
         if (AutoDetectTrade) bool TradeExists = DetectTrade();
         if(TradeExists)
         {      
            GvName = StringConcatenate(GlobalPrefix, DoubleToStr(TicketNo,0));
            GlobalVariableSet(GvName, TicketNo);
         }//if(TradeExists)
         else
         {
            Comment("                                 Waiting for the next trade. Remember to delete me if I am not wanted.");         
            return;
         }//else
      }//if (LeaveRunningAfterTradeCloses)
      
   }//if (!GlobalVariableCheck(GvName))
   
   
   //Check to see if the trade has closed
   if (!OrderSelect(TicketNo, SELECT_BY_TICKET) || OrderCloseTime() > 0)
   {
      DeleteEAObjects(GlobalPrefix);
      GlobalVariableDel(GvName);
      if (!LeaveRunningAfterTradeCloses) 
      {
         MessageBox("The trade has closed, so this robot has stopped and needs removing.");
         RobotSuspended = true;
      }//if (!LeaveRunningAfterTradeCloses) 
      
      return;
   }//if (!OrderSelect(TicketNo, SELECT_BY_TICKET))
   
   
   //Got this far so continue 
   Comment("                                 Monitoring ticket no " + TicketNo);
   
   //Set missing tp and sl
   TP = OrderTakeProfit();
   SL = OrderStopLoss();   
   
   if (TP == 0 || SL == 0)
   {
      if (SL == 0) SetStop();
      
      if (TP == 0) SetTp();
      
      DrawTakeStopLines();
      OrderModify(TicketNo,OrderOpenPrice(),SL,TP,OrderExpiration(),CLR_NONE);
      return;
   }//if (take == 0 or stop == 0)
   
   
   
   //Check if lines have been moved\newly created, in which case
   //attempt to update the sl\tp
   string HlineName = GlobalPrefix + "LIDHI1";
   TP = ObjectGet(HlineName, OBJPROP_PRICE1);
   
   //Check to see if robot is required to close a trade
   if(TpLineCanCloseTrade)
   {
      //Buy
      if (OrderType() == OP_BUY)
      {
         if (TP < OrderTakeProfit() )
         {
            OrderCloseReliable(TicketNo, OrderLots(), OrderClosePrice(), 5, CLR_NONE);
            return;
         }//if (TP < OrderTakeProfit() )         
      }//if (OrderType() == OP_BUY
      
      //Sell
      if (OrderType() == OP_SELL)
      {
         if (TP > OrderTakeProfit() )
         {
            OrderCloseReliable(TicketNo, OrderLots(), OrderClosePrice(), 5, CLR_NONE);
            return;
         }//if (TP < OrderTakeProfit() )         
      }//if (OrderType() == OP_BUY
      
      
   }//if(TpLineCanCloseTrade)
   
   HlineName = GlobalPrefix + "LIDLO1";
   SL = ObjectGet(HlineName, OBJPROP_PRICE1);
   
   if (OrderTakeProfit() != TP || OrderStopLoss() != SL)
   {
      OrderModify(TicketNo,OrderOpenPrice(),SL,TP,OrderExpiration(),CLR_NONE);
   }//if (OrderTakeProfit() != TP)
   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments