//+------------------------------------------------------------------+
//| 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