Pending Order Stop Loss

 

Greetings

why is closing price higher than the stop loss? As soon as it hits my stop loss, stop loss price and closing price are not the same. When my pending orders (buy stop & sell stop) are placed everything is perfect. Once it turns into a position, price changes and stop loss changes. I tried searching on the web & I came across "order filled" I assumed it might be the solution to my problem, but no. here is the EA Below: 

//+------------------------------------------------------------------+
//|                                                 forum EA MT5.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>

CTrade trade;
CPositionInfo m_position;
CSymbolInfo m_symbol;
COrderInfo m_order;
CAccountInfo m_account;

input double StopLoss=0.1;
input double PendingStopTrail=0.05;
input double point=100;
input int digit=2;

int MagicNumber;
double Price;
double Filter=0;
int Direction=0;

double Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); 
double Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
int StopLevel=(int)SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL);
int FreezeLevel=(int)SymbolInfoInteger(Symbol(),SYMBOL_TRADE_FREEZE_LEVEL);
double TickSize=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE);
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
 {
  ResetLastError();
  
  if(!m_symbol.Name(Symbol()))
  {
   return(INIT_FAILED);
  }
   
  trade.SetExpertMagicNumber(MagicNumber);
  trade.SetMarginMode();
  trade.SetTypeFillingBySymbol(m_symbol.Name());
  
  MagicNumber=(int)TimeCurrent();
             
  TesterHideIndicators(true);
  
  StopLevel=(int)SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL);
  FreezeLevel=(int)SymbolInfoInteger(Symbol(),SYMBOL_TRADE_FREEZE_LEVEL);
  TickSize=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE);
  
  return(INIT_SUCCEEDED);
 }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int CountPending()
 {
  int Pending=0;
  for(int b=OrdersTotal()-1;b>=0;b--)
  {
   bool Select=OrderSelect(OrderGetTicket(b));
   string OrderSymbol=OrderGetString(ORDER_SYMBOL);
   if(OrderSymbol==Symbol())
   {
    ENUM_ORDER_TYPE Type=(ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
    if(Type==ORDER_TYPE_BUY_STOP||Type==ORDER_TYPE_SELL_STOP)
    Pending++;
   }
  }
  return(Pending);
 }
 
double Pips()
 {
  double PipPoint=0;
  int Digit=(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS);
  if(Digit==digit){PipPoint=Point()*point;}
  return(PipPoint);
 } 
 
void FillOrder()
 {
  int Fill=0,PenFill=0;
  
  for(int f=PositionsTotal()-1;f>=0;f--)
  {
   if(m_position.SelectByIndex(f))
   if(m_position.Symbol()==Symbol())
   {
    if(m_position.Type()==POSITION_TYPE_BUY||m_position.Type()==POSITION_TYPE_SELL)
    {
     Fill=(int)m_position.Ticket();PenFill=(int)m_position.Ticket();
    }
   }
  }
 }
 
void BuyPending()
 {
  int PSAR=iSAR(Symbol(),_Period,0.02,0.2);
  double SAR[];
  ArraySetAsSeries(SAR,true);
  CopyBuffer(PSAR,0,0,Bars(Symbol(),Period()),SAR);
  
  MqlRates Candle[];
  ArraySetAsSeries(Candle,true);
  int rates=CopyRates(Symbol(),Period(),0,Bars(Symbol(),Period()),Candle);
  
  datetime Expire=TimeCurrent()+(60*15);
  
  double SLBuy=Bid-StopLoss*Pips();
  double PendingPrice=Ask+PendingStopTrail*Pips();
  
  if(OrdersTotal()==0)
  {
   if(MathAbs(PendingPrice-Ask)>FreezeLevel*Pips()||MathAbs(PendingPrice-SLBuy)>StopLevel*Pips())
   {
    if(SAR[0]<Bid)
    {
     bool BuyStop=trade.BuyStop(0.1,PendingPrice,Symbol(),SLBuy,0,ORDER_TIME_SPECIFIED,Expire,"SLClose");
    }
   }
  }   
  
 }
 
void SellPending()
 {
  int PSAR=iSAR(Symbol(),_Period,0.02,0.2);
  double SAR[];
  ArraySetAsSeries(SAR,true);
  CopyBuffer(PSAR,0,0,Bars(Symbol(),Period()),SAR);
  
  MqlRates Candle[];
  ArraySetAsSeries(Candle,true);
  int rates=CopyRates(Symbol(),Period(),0,Bars(Symbol(),Period()),Candle);
  
  datetime Expire=TimeCurrent()+(60*15);
  
  double SLSell=Bid+StopLoss*Pips();
  double PendingPrice=Bid-PendingStopTrail*Pips();
  
  if(OrdersTotal()==0)
  {
   if(MathAbs(Bid-PendingPrice)>FreezeLevel*Pips()||MathAbs(SLSell-PendingPrice)>StopLevel*Pips())
   {
   if(SAR[0]>Ask)
   {
    bool SellStop=trade.SellStop(0.1,PendingPrice,Symbol(),SLSell,0,ORDER_TIME_SPECIFIED,Expire,"SLClose");
   }
  }
 }   
  
  
 } 

void OnTick()
 {
  trade.SetExpertMagicNumber(MagicNumber);
  
  if(CountPending()<1){BuyPending();SellPending();}
  FillOrder();
   
 }

 
RedAlgo:

Greetings

why is closing price higher than the stop loss? As soon as it hits my stop loss, stop loss price and closing price are not the same. When my pending orders (buy stop & sell stop) are placed everything is perfect. Once it turns into a position, price changes and stop loss changes. I tried searching on the web & I came across "order filled" I assumed it might be the solution to my problem, but no. here is the EA Below: 

Does anyone know how to solve this? I've been searching & no luck. I came across "filling" & this the outcome I've come across: 
void FillAgain()
 {
  for(int u=OrdersTotal()-1;u>=0;u--)
  {
   if(m_order.SelectByIndex(u))
   if(m_order.Symbol()==Symbol())
   {
    bool ForceSL;
    if(m_order.Type()==ORDER_TYPE_BUY_STOP||m_order.Type()==ORDER_TYPE_SELL_STOP)
    {
     ForceSL=MathAbs(m_order.PriceCurrent()-m_order.StopLoss()<=0.5*Pips());
    }
   }
  }
  
 } 
It does not solve my problem. Hence when order turns into position everything changes opening price including the stoploss
 

My Closing price is higher than the stop lossSince I'm trading Indices, to be specific US30 (spread is 70 points). I tried using this average spread function but I'm not winning. 

double AverageSpread()
 {
  double Spread=NormalizeDouble(Ask-Bid,Digits());
  ArrayCopy(SpreadHistory,SpreadHistory,0,1,29);
  SpreadHistory[29]=Spread;
  if(SpreadHistoryCount<30)SpreadHistoryCount++;
  double SpreadHistorySum=0;
  for(int i=29;i>=30-SpreadHistoryCount;i--)SpreadHistorySum+=SpreadHistory[i];
  double SpreadAverage=SpreadHistorySum/SpreadHistoryCount;
  double SpreadWithCom=NormalizeDouble(SpreadAverage,Digits());
  
  return(SpreadWithCom);
 } 
if(spreadAmount*Pips()>AverageSpread())
  {
   //buy & sell trade 
  }
 
Same "problem" happened here. It's called slippage, a very simple and common situation in trading.

 
RedAlgo:

Greetings

why is closing price higher than the stop loss? As soon as it hits my stop loss, stop loss price and closing price are not the same. When my pending orders (buy stop & sell stop) are placed everything is perfect. Once it turns into a position, price changes and stop loss changes. I tried searching on the web & I came across "order filled" I assumed it might be the solution to my problem, but no. here is the EA Below: 


The problem isn’t with your code, it’s simply how trading works.

You’ll only get an exact execution price if you use limit orders. When you use stop orders (Stop Loss, Buy Stop or Sell Stop) your order is executed when price reaches a certain level, but it's executed as a market order. This means it fills at the best available price at that moment, which can be different from your stop price, especially during high volatility or low liquidity.

This behavior is normal and is a fundamental aspect of how financial markets operate. It’s not something that can be fixed, it’s just how stop orders are designed to work.

If you need more precise control over execution price, you’ll need to use limit orders. But they might not get filled if the market doesn't reach your specified price.

 
Fabio Cavalloni #:
Same "problem" happened here. It's called slippage, a very simple and common situation in trading.

I see, the same person is encountering the same problem as I 'am but he/she is using MT4. There are certain individuals who can limit/reduce spread or close at a minimum spread I'd like to know if it's possible?
 
Rafael Grecco #:


The problem isn’t with your code, it’s simply how trading works.

You’ll only get an exact execution price if you use limit orders. When you use stop orders (Stop Loss, Buy Stop or Sell Stop) your order is executed when price reaches a certain level, but it's executed as a market order. This means it fills at the best available price at that moment, which can be different from your stop price, especially during high volatility or low liquidity.

This behavior is normal and is a fundamental aspect of how financial markets operate. It’s not something that can be fixed, it’s just how stop orders are designed to work.

If you need more precise control over execution price, you’ll need to use limit orders. But they might not get filled if the market doesn't reach your specified price.

I prefer to use stop orders instead of limit orders & I've seen a few posts recommend limit to get execution price. 
 
RedAlgo #:
I see, the same person is encountering the same problem as I 'am but he/she is using MT4. There are certain individuals who can limit/reduce spread or close at a minimum spread I'd like to know if it's possible?
Trades are always closed at the first valid price. It can be the same exact of your stop loss or deviate by it if the tick triggering the closure is bigger.

In all cases, this is called slippage, and despite rare situation in which ticks are huge (like news release time), the slippage can be totally ignored. One time is against you, one time in your favor.
 
Fabio Cavalloni #:
Trades are always closed at the first valid price. It can be the same exact of your stop loss or deviate by it if the tick triggering the closure is bigger.

In all cases, this is called slippage, and despite rare situation in which ticks are huge (like news release time), the slippage can be totally ignored. One time is against you, one time in your favor.

I ran the My EA on a live account & I fully understand what you're saying especially indices and its slippage. 



Please help me on how to calculate commission and profit. I encounter this problem when using Breakeven & trailing when closed in profit. My commissions are higher than my profits instead profits being higher than commissions. Is this due to me not using commission and profit calculations properly or could it be another case of slippage but I use ECN Raw accounts & I trade on FX pairs & gold. 

 Is the correct way: 
void CalulateProfit()
 {
  double Profit=0;
  for(int i=PositionsTotal()-1;i>=0;i--)
  {
   if(m_position.SelectByIndex(i))
   {
    Profit=m_position.Commission()+m_position.Profit()+m_position.Swap();
   }
  }
   
 }