1 (edited by Roughey 2021-11-29 21:26:41)

Topic: StopLoss Checking

Hi,

i want to let check my SL and TP before sending an Order. Cause some brokers make trouble that ea not working correctly.

I have found this on mql site. This is the function:

bool CheckStopLoss_Takeprofit(ENUM_ORDER_TYPE type,double SL,double TP)
  {
//--- get the SYMBOL_TRADE_STOPS_LEVEL level
   int stops_level=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
   if(stops_level!=0)
     {
      PrintFormat("SYMBOL_TRADE_STOPS_LEVEL=%d: StopLoss and TakeProfit must"+
                  " not be nearer than %d points from the closing price",stops_level,stops_level);
     }
//---
   bool SL_check=false,TP_check=false;
//--- check only two order types
   switch(type)
     {
      //--- Buy operation
      case  ORDER_TYPE_BUY:
        {
         //--- check the StopLoss
         SL_check=(Bid-SL>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
                        " (Bid=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,Bid-stops_level*_Point,Bid,stops_level);
         //--- check the TakeProfit
         TP_check=(TP-Bid>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
                        " (Bid=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,Bid+stops_level*_Point,Bid,stops_level);
         //--- return the result of checking
         return(SL_check&&TP_check);
        }
      //--- Sell operation
      case  ORDER_TYPE_SELL:
        {
         //--- check the StopLoss
         SL_check=(SL-Ask>stops_level*_Point);
         if(!SL_check)
            PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f "+
                        " (Ask=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),SL,Ask+stops_level*_Point,Ask,stops_level);
         //--- check the TakeProfit
         TP_check=(Ask-TP>stops_level*_Point);
         if(!TP_check)
            PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f "+
                        " (Ask=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
                        EnumToString(type),TP,Ask-stops_level*_Point,Ask,stops_level);
         //--- return the result of checking
         return(TP_check&&SL_check);
        }
      break;
     }
//--- a slightly different function is required for pending orders
   return false;
  }

and in Portfolio MT5 i add this before order send:

void OpenPosition(Signal &signal)
  {     
   int    command    = OrderDirectionToCommand(signal.Direction);
   double stopLoss   = GetStopLossPrice(command,   signal.StopLossPips);
   double takeProfit = GetTakeProfitPrice(command, signal.TakeProfitPips);

//--- This is to see in Journal what TP & SL i have
   Print("SL:"+DoubleToString(stopLoss,_Digits)+"TP:"+DoubleToString(takeProfit,_Digits));

   if(!CheckStopLoss_Takeprofit(ORDER_TYPE_BUY,stopLoss,takeProfit)) return;
   if(!CheckStopLoss_Takeprofit(ORDER_TYPE_SELL,stopLoss,takeProfit)) return;
   ManageOrderSend(command, Entry_Amount, stopLoss, takeProfit, 0, signal.MagicNumber);
  }

In Journal in get such Mistakes an no order send.

2021.11.29 20:54:44.136    Core 1    2020.03.09 11:00:00   SL:1.13446TP:1.14796
2021.11.29 20:54:44.136    Core 1    2020.03.09 11:00:00   For order ORDER_TYPE_SELL StopLoss=1.13446 must be greater than 1.14387  (Ask=1.14387 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 11:00:00   For order ORDER_TYPE_SELL TakeProfit=1.14796 must be less than 1.14387  (Ask=1.14387 - SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 11:00:00   SL:1.13066TP:1.14976
2021.11.29 20:54:44.136    Core 1    2020.03.09 11:00:00   For order ORDER_TYPE_SELL StopLoss=1.13066 must be greater than 1.14387  (Ask=1.14387 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 11:00:00   For order ORDER_TYPE_SELL TakeProfit=1.14976 must be less than 1.14387  (Ask=1.14387 - SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 17:00:00   SL:1.12091TP:1.15611
2021.11.29 20:54:44.136    Core 1    2020.03.09 17:00:00   For order ORDER_TYPE_SELL StopLoss=1.12091 must be greater than 1.14013  (Ask=1.14013 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 17:00:00   For order ORDER_TYPE_SELL TakeProfit=1.15611 must be less than 1.14013  (Ask=1.14013 - SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 17:00:00   SL:1.12251TP:1.14431
2021.11.29 20:54:44.136    Core 1    2020.03.09 17:00:00   For order ORDER_TYPE_SELL StopLoss=1.12251 must be greater than 1.14013  (Ask=1.14013 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 17:00:00   For order ORDER_TYPE_SELL TakeProfit=1.14431 must be less than 1.14013  (Ask=1.14013 - SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 22:00:00   SL:1.12902TP:1.16212
2021.11.29 20:54:44.136    Core 1    2020.03.09 22:00:00   For order ORDER_TYPE_SELL StopLoss=1.12902 must be greater than 1.14614  (Ask=1.14614 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 22:00:00   For order ORDER_TYPE_SELL TakeProfit=1.16212 must be less than 1.14614  (Ask=1.14614 - SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 22:00:00   SL:1.12852TP:1.15032
2021.11.29 20:54:44.136    Core 1    2020.03.09 22:00:00   For order ORDER_TYPE_SELL StopLoss=1.12852 must be greater than 1.14614  (Ask=1.14614 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 20:54:44.136    Core 1    2020.03.09 22:00:00   For order ORDER_TYPE_SELL TakeProfit=1.15032 must be less than 1.14614  (Ask=1.14614 - SYMBOL_TRADE_STOPS_LEVEL=0 points)

Can someone help me out? I dont know why?


when i look directly into stoploss and takeprofit without the digit.

   Print("SL:"+DoubleToString(stopLoss)+"TP:"+DoubleToString(takeProfit));

this in journal

2021.11.29 21:23:52.953    Core 1    2020.05.07 23:00:00   SL:1.06365000TP:1.09685000
2021.11.29 21:23:52.953    Core 1    2020.05.07 23:00:00   For order ORDER_TYPE_SELL StopLoss=1.06365 must be greater than 1.08297  (Ask=1.08297 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 21:23:52.953    Core 1    2020.05.07 23:00:00   For order ORDER_TYPE_SELL TakeProfit=1.09685 must be less than 1.08297  (Ask=1.08297 - SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 21:23:52.953    Core 1    2020.05.07 23:00:00   SL:1.07185000TP:1.08905000
2021.11.29 21:23:52.953    Core 1    2020.05.07 23:00:00   For order ORDER_TYPE_SELL StopLoss=1.07185 must be greater than 1.08297  (Ask=1.08297 + SYMBOL_TRADE_STOPS_LEVEL=0 points)
2021.11.29 21:23:52.953    Core 1    2020.05.07 23:00:00   For order ORDER_TYPE_SELL TakeProfit=1.08905 must be less than 1.08297  (Ask=1.08297 - SYMBOL_TRADE_STOPS_LEVEL=0 points)

Are there too much digits????

Re: StopLoss Checking

The Portfolio Expert calculates the correct SL and TP for each entry.
Please see the GetStopLossPrice and GetTakeProfitPrice functions.
You don't need to check them further.

Anyway, the problem with your code is that you check SL and TP against both long and short positions.

   if(!CheckStopLoss_Takeprofit(ORDER_TYPE_BUY,stopLoss,takeProfit)) return;
   if(!CheckStopLoss_Takeprofit(ORDER_TYPE_SELL,stopLoss,takeProfit)) return;

Imagine that the order is for a Long entry. The first function call will check the SL and TP and will continue. However, the second call will check the SL and TP if it was a short entry, but it is not. So, it will give an error every time.

You have to call your check only once with the correct position direction. The correct way is:

   if ( !CheckStopLoss_Takeprofit(signal.Direction, stopLoss, takeProfit) ) return;

But, as I said before, it is pointless in that case because the GetStopLossPrice and GetTakeProfitPrice do the same.

Re: StopLoss Checking

thanks for reply...signal.Direction doesnt work cause function need enum.

bool CheckStopLoss_Takeprofit(ENUM_ORDER_TYPE type,double SL,double TP)

Re: StopLoss Checking

Change ENUM_ORDER_TYPE with OrderDirection


bool CheckStopLoss_Takeprofit(OrderDirection type, double SL, double TP)
  {
   ...
   switch(type)
     {
      case  ORDER_DIRECTION_BUY:
        ...
      case  ORDER_DIRECTION_SELL:
        ...
      break;
     }
   ...
  }