Time Based Stop Loss


Mar 28, 2016
Hi All Coders,

I have zero knowledge of MQL. If someone here could kindly code this extremely useful a risk management EA with two functionality:

Time Based Stop Loss (most important):
  1. EA will cancel all open orders which are in Loss after specified seconds. If trade is in Profit then don't close the trade.
  2. User can input: seconds (for example: 75424 seconds)
  3. User can input to close order for: current chart order OR all open orders in all charts (as the user can choose to apply different seconds for different symbols).

Partial Stop Loss Levels (secondary):
  1. For all open order which has a stop loss (SL) order attached. If price is currently trading between 50% of SL and Entry, then close 50% of the position size.
  2. There should be 3 such levels of 25%, 50%, 75% (these levels are % distance between SL and entry order). The user can manually select how much position size % to close at each level.
  3. Please note that user can manually change/drag the stop loss order in MT4 this should also automatically change the levels (25%/50%/75%) above.
  4. User can choose the above settings to: current chart OR all open orders in all charts.

Any help from anyone would be extremely as I think this EA would be very popular and immensely help traders to manage risk.

Many thanks.


Mar 28, 2016
Time Stop:
  1. EA will cancel all open orders which are in Loss after specified seconds.
extern bool FilterByMagicNumber = FALSE;
extern bool CurrentPairOnly     = FALSE;
extern int  MagicNumber         = 0;
extern string  tbslh="----Time based StopLoss----";
bool    UseTimeBasedStopLoss    = TRUE;
extern string  tsmh="1:days, 2:hours, 3:minuts, 4:bars";
extern int     TimeBasedSLmode         = 4;
extern double  TimeBasedSLperiodProfit = 5;
extern double  TimeBasedSLperiodLoss   = 5;
extern string  bth="true:Sends 2 orders everytime OrdersTotal is = 0";
extern bool    Send2OrdersFrequently = FALSE;
string shmode;
int totalopenorders;//simple stats
int init() {
//simple userinfo
  shmode="ERROR - check your settings!";
  if (TimeBasedSLmode==1) shmode="days";
  if (TimeBasedSLmode==2) shmode="hours";
  if (TimeBasedSLmode==3) shmode="minutes";
  if (TimeBasedSLmode==4) shmode="bars";
int deinit() {
int start() {
" current day is "+DayToStr(GetDayOfWeek(0))+", SETTINGS: Send2OrdersFrequently="+bool2txt(Send2OrdersFrequently)+"\n"+
"   FilterByMagicNumber="+bool2txt(FilterByMagicNumber)+" (MagicNumber="+MagicNumber+"), CurrentPairOnly="+bool2txt(CurrentPairOnly)+" (pair: "+Symbol()+"), total open trades to manage: "+totalopenorders+"\n"+
"   close trades in profit after "+DoubleToStr(TimeBasedSLperiodProfit,2)+" "+shmode+", close trades in loss after "+DoubleToStr(TimeBasedSLperiodLoss,2)+" "+shmode);
if (Send2OrdersFrequently && OrdersTotal()==0) {
  OrderSend(Symbol(),OP_BUY,MarketInfo(Symbol(),MODE_MINLOT),MarketInfo(Symbol(),MODE_ASK),5000,0,0,"TESTORDER BUY", MagicNumber,0,Blue);
  OrderSend(Symbol(),OP_SELL,MarketInfo(Symbol(),MODE_MINLOT),MarketInfo(Symbol(),MODE_BID),0500,0,0,"TESTORDER SELL", MagicNumber,0,Red);
    //OrderSend(Symbol(),OP_BUYSTOP,MarketInfo(Symbol(),MODE_MINLOT),MarketInfo(Symbol(),MODE_ASK)+350*Point,5000,0,0,"TESTORDER BUYSTOP", MagicNumber,0,Blue);
    //OrderSend(Symbol(),OP_SELLSTOP,MarketInfo(Symbol(),MODE_MINLOT),MarketInfo(Symbol(),MODE_BID)-350*Point,5000,0,0,"TESTORDER SELLSTOP", MagicNumber,0,Red);
}//if (IsTesting() && SendOrdersAtStartAtBacktesting) {
if (UseTimeBasedStopLoss) TimeBasedSL(Symbol(),MagicNumber,TimeBasedSLperiodProfit,TimeBasedSLperiodLoss,TimeBasedSLmode,-1);
/* if you would like to delete pending orders only, the call should be (e.g. for BUYSTOP) */
   if (UseTimeBasedStopLoss) TimeBasedSL(Symbol(),MagicNumber,TimeBasedSLperiodProfit,TimeBasedSLperiodLoss,TimeBasedSLmode,OP_BUYSTOP);
//mode - 1:days, 2:hours, 3:minuts, 4:bars
//type - if not -1 only the specified ordertypes will be closed, for example if type=OP_BUY it will only close buy-orders, or if type=OP_BUYSTOP it will delete pending buystop orders (nice if you broker does not support pending order expiration times)
void TimeBasedSL(string symbol,int magicnumber,double TimeBasedSLperiodProfit,double TimeBasedSLperiodLoss,int mode=4,int type=-1) {
bool result;
if (TimeBasedSLmode>4 || TimeBasedSLmode<=0) { Print("TimeBasedSL(): *** ERROR - mode must be 1,2,3 or 4 ..."); return; }//simple errorchecking
double TimeBasedSL=0.0;
string smode="unknown";
if (mode==1) smode="days";
if (mode==2) smode="hours";
if (mode==3) smode="minutes";
if (mode==4) smode="bars";
string sTimeBasedSLperiod;
for (int cnt=OrdersTotal()-1; cnt>=0; cnt--) {
  if (!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)) continue;
  if (CurrentPairOnly && OrderSymbol()!=symbol) continue;
  if (FilterByMagicNumber && OrderMagicNumber()!=magicnumber) continue;
  if (type!=-1 && OrderType()!=type) continue;
    double profit = (OrderProfit()+OrderCommission()+OrderSwap());
    //Order is in profit
    if (profit>0.0) {
     if (mode==1) TimeBasedSL = TimeBasedSLperiodProfit * 86400;//days
     if (mode==2) TimeBasedSL = TimeBasedSLperiodProfit * 3600;//hours
     if (mode==3) TimeBasedSL = TimeBasedSLperiodProfit * 60;//minutes
     if (mode==4) TimeBasedSL = TimeBasedSLperiodProfit * Period() * 60;//bars
     sTimeBasedSLperiod = "closed (timebased SL="+DoubleToStr(TimeBasedSLperiodProfit,2)+" "+smode+") at PROFIT";
    //Order is in loss
    if (profit<0.0) {
     if (mode==1) TimeBasedSL = TimeBasedSLperiodLoss * 86400;//days
     if (mode==2) TimeBasedSL = TimeBasedSLperiodLoss * 3600;//hours
     if (mode==3) TimeBasedSL = TimeBasedSLperiodLoss * 60;//minutes
     if (mode==4) TimeBasedSL = TimeBasedSLperiodLoss * Period() * 60;//bars
     sTimeBasedSLperiod = "closed (timebased SL="+DoubleToStr(TimeBasedSLperiodLoss,2)+" "+smode+") at LOSS";
    if ((TimeCurrent() - OrderOpenTime()) >= TimeBasedSL) {
     while(IsTradeContextBusy()) Sleep(100);
     if (OrderType()==OP_BUY) {//buy
      if (result) Print("TimeBasedSL(): **** BUY order ticket "+OrderTicket()+" (opentime: "+TimeToStr(OrderOpenTime())+") "+sTimeBasedSLperiod+" of "+DoubleToStr(profit,2)+" "+AccountCurrency());
     if (OrderType()==OP_SELL) {//sell
      if (result) Print("TimeBasedSL(): **** SELL order ticket "+OrderTicket()+" (opentime: "+TimeToStr(OrderOpenTime())+") "+sTimeBasedSLperiod+" of "+DoubleToStr(profit,2)+" "+AccountCurrency());
    if (OrderType()>1 && OrderType()<6) {//pending orders
     if (result) Print("TimeBasedSL(): **** Pending Order ticket "+OrderTicket()+" (opentime: "+TimeToStr(OrderOpenTime())+") deleted (timebased SL="+sTimeBasedSLperiod+" "+smode+")");
    }//if (TimeCurrent() - ...
}//for (int cnt=OrdersTotal()-1; cnt>=0; cnt--) {
int GetDayOfWeek(int bar) {
string DayToStr(int day) {
switch (day)     {
  case 0: return("sunday");
  case 1: return("monday");
  case 2: return("tuesday");
  case 3: return("wednesday");
  case 4: return("thursday");
  case 5: return("friday");
  case 6: return("saturday");
  default: return("unknown");
string bool2txt(int varbool) {
if (varbool==true) return("yes");
if (varbool==false) return("no");
Last edited by a moderator: