EA Sometimes not Setting the EXACT SL and TP Targets

 

Hello,

please can someone help me to find the solution for the problem,

as you can see in the Print screen that the EA SL and TP targets are different than the Values printed in the logs (which is circled in Red and Green).

then i noticed that there is difference in the price that the EA took in the actual trade which was 1.72894 and the ASK Price printed in the log  1.72895 (which is circled with Yellow)

i tested it many times always the difference between SL and TP targets is equal to the difference between the actual price in the trade and the ASK or BID Price printed in the logs.

Please note that the this differences not happing always.

This is the code and Thanks in advance,


input string MoneyManagement = "///////////////////////";
input double Risk_Percentage = 0.5;

input string SL_AND_TP = "///////////////////////";
input double ATR_Period = 14;
input double ATR_SL = 1;
input double ATR_TP = 3;


// Global Variables
double point;
datetime gBarTime;
int buyticket;
int sellticket;
color bcol = Lime;
color scol = Red;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
if(Digits == 5 || Digits == 3) point=Point*10;
   else point=Point;

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   //new local variable to hold the current open time of the furhest right bar
  datetime rightbartime = iTime(_Symbol,_Period,0);
// check if the furthest right bar has the same open time as our global variable
  if(rightbartime != gBarTime)
  {
// set the global variable to be the time of the new bar
  gBarTime = rightbartime;
  
// call ouf onbar function
  OnBar();
 


   }

  }
//+------------------------------------------------------------------+
//The ON Bar Strategy Function
  void OnBar()
  
  {
  
  

 // ATR SL and TP
 double SL=NormalizeDouble(((iATR(NULL,0,ATR_Period,1)/Point)/10)*ATR_SL,0);
 double TP = SL* ATR_TP;
  
  if(Close[1] < Open[1]   )
  {
       
       double LotSize = GetLotSize(_Symbol,Risk_Percentage,SL);
       double ASKP = Ask;
       double SLprice = calculateSLprice(TRUE,ASKP,SL);
       double TPprice = calculateTPprice(TRUE,ASKP,TP);
   
  
       
    buyticket = OrderSend(_Symbol,OP_BUY,LotSize,ASKP,10,SLprice,TPprice,"No",123,0,bcol);
                Print("SL=",SL);
                Print("TP=",TP);
                Print("calculateSLprice(buy)=",SLprice);
                Print("calculateTPprice(buy)=",TPprice);
                Print("ASK=",ASKP);
  }
  else if(Close[1] > Open[1]  )
  {
  
  
       double LotSize = GetLotSize(_Symbol,Risk_Percentage,SL);
       double BIDP = Bid;
       double SLprice = calculateSLprice(False,BIDP,SL);
       double TPprice = calculateTPprice(False,BIDP,TP);
  
    sellticket = OrderSend(_Symbol,OP_SELL,LotSize,BIDP,10,SLprice,TPprice,"No",123,0,scol);
                Print("SL=",SL);
                Print("TP=",TP);
                Print("calculateSLprice(sell)=",SLprice);
                Print("calculateTPprice(sell)=",TPprice);
                Print("BID=",BIDP);
  }
  

  
  }
  
 


  
  



/////////////////////////////////////////////////////////////////////

double calculateTPprice(bool islong, double entryprice, int pips)
{
   double TPprice;

   if(islong)
   {
   TPprice = entryprice + pips * Getpipval();
   
   }
   else
   {
   TPprice = entryprice - pips * Getpipval();
    
   }
   return TPprice;
   
   
}

double calculateSLprice(bool islong, double entryprice, int pips)
{

   double SLprice;
   
   if(islong)
   {
   SLprice = entryprice - pips * Getpipval();
   }
   else
   {
   
   SLprice = entryprice + pips * Getpipval();
   
   }
   return SLprice;

}


//////////////////////////////////////////////////////////////////////////

  

double Getpipval()

{

if(_Digits >= 4)
{
return  0.0001;
}

else
{
return  0.01;
}



}
////////////////////////////////////   

double GetLotSize(string symbol, double risk, double SL)
{
double tickvalue = MarketInfo(Symbol(), MODE_TICKVALUE);
double lotstep = MarketInfo (Symbol(), MODE_LOTSTEP);
double minlot = MarketInfo(Symbol(), MODE_MINLOT);
double maxlot = MarketInfo(Symbol(), MODE_MAXLOT);
double lotsize;
 
 
 if (StringFind(symbol, "jpy") != -1)
 {
     lotsize = ((AccountBalance() * risk) / ( SL * tickvalue ))*Point;   
 }
 else
 {
     lotsize = ((AccountBalance() * risk) / ( SL * tickvalue ))/1000;
 }
 
 // Ensure that the calculated lot size is within the minimum and maximum allowed by the broker
 lotsize = MathMin(lotsize, maxlot);
 lotsize = MathMax(lotsize, minlot);
 
    // Round the lot size to the nearest step size allowed by the broker
    lotsize = MathRound(lotsize/lotstep)*lotstep;
 
 
 double pipval = (AccountBalance() * risk) /  SL /100;
 
 Print( "   tickvalue=", tickvalue, "     lotstep =", lotstep,  "     Lotsize=", lotsize,     "        Pipval=",pipval );
 
 return lotsize;
}

/////////////////////
Files:
Error.png  67 kb
 
   TPprice = entryprice - pips * Getpipval();
⋮
   SLprice = entryprice - pips * Getpipval();

You buy at the Ask and sell at the Bid. Pending Buy Stop orders become market orders when hit by the Ask.

  1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid / OrderClosePrice reaches it. Using Ask±n, makes your SL shorter and your TP longer, by the spread. Don't you want the specified amount used in either direction?

  2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask / OrderClosePrice reaches it. To trigger close at a specific Bid price, add the average spread.
              MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25

  3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)

    Most brokers with variable spreads widen considerably at end of day (5 PM ET) ± 30 minutes.
    My GBPJPY shows average spread = 26 points, average maximum spread = 134.
    My EURCHF shows average spread = 18 points, average maximum spread = 106.
    (your broker will be similar).
              Is it reasonable to have such a huge spreads (20 PIP spreads) in EURCHF? - General - MQL5 programming forum (2022)

 

Thank you for the reply Mr William,

I tested if the problem is from the spread before posting here.

correct me if i am wrong please,

As you can see from the new Print Screen that the spread is 0.6 Pips and the SL is 28 pips as it's printed in the log but the actual SL that the EA set is 28.2 ( not 28.6).

The 0.2 difference in the print screen is from the Ask Printed in the logs which is 1.73356 and the actual price in the trade which is  1.733568.

And i tested it many times in different spread environment and i noticed even if the spread is 0, Sometimes the EA sets the SL not equal to the printed SL in the logs.

And tested it in when the spread is more than 1 Pip spread and the EA set the SL accurately as it is printed in the logs.

if the problem is from the Spread shouldn't be always wrong calculation?

Please note that the SL is not always not accurate that what's making me confused.

Any help will be very appreciated thanks in advance.

Files:
Error2.png  48 kb