How to get the last known (modified) SL and TP from a closed position (history order) correctly?

 

I found some old topic with the same problem, but it was not resolved: https://www.mql5.com/en/forum/4387

 

It looks that this issue is pretty old. Ok, here is what to do:

 

1. Open position without stops, SL = 0 and TP = 0

2. Modify stops. SL => X and TP => Y

3. Close that position

4. Try to get SL and TP from that position that is already closed. Well, now the position is history.. whatever, order or deal.

 

The result is always SL = 0 and TP = 0, or whatever the initial SL and TP are.

So, how to get the correct values?

 

Here is some script that I use to test things:

 

void OnStart()
{
   int i = 0;
   ulong ticket=0;
   int history_minutes = 10;

   Print("^^^ history ORDERS ^^^");
   HistorySelect(TimeCurrent()-(history_minutes * 60), TimeCurrent());
 
   for(i=0; i < HistoryOrdersTotal(); i++)
   {
      ticket=HistoryOrderGetTicket(i);
      Print(
         "Order Ticket = " + ticket
         + "; SL = " + HistoryOrderGetDouble(ticket,ORDER_SL)
         + "; TP = " + HistoryOrderGetDouble(ticket,ORDER_TP)
      );
   }
   
   Print("^^^ history DEALS ^^^");
   for(i=0; i < HistoryDealsTotal(); i++)
   {
      ticket=HistoryDealGetTicket(i);
      
      long order=HistoryDealGetInteger(ticket, DEAL_ORDER);
      //order = HistoryDealGetInteger(ticket, DEAL_POSITION_ID);
      
      Print(
         "Deal Ticket = " + ticket
         + "; SL = " + HistoryOrderGetDouble(order,ORDER_SL)
         + "; TP = " + HistoryOrderGetDouble(order,ORDER_TP)
      );
   }
}
ORDER_TP and ORDER_SL not reflected by OrderGetDouble or HistoryOrderGetDouble when applied after initial placing
ORDER_TP and ORDER_SL not reflected by OrderGetDouble or HistoryOrderGetDouble when applied after initial placing
  • www.mql5.com
Can anyone help how to get stop and loss for those orders ? - - Category: general
 

The big question is : what to do ? If you are modifying stoploss from your EA, aren't you supposed to know its value ?

 

Who asks that big question, it's not me :)

 I personally don't really care, I don't use MT5 and I don't even like it, but I own one of the EA builders and some people use it. So, if someone wants to make a Script where he needs to know the last known SL or TP of the last closed position, what can I say to him? That MT5 has tons of features -positions, orders, deals in, deals out... but there is no way to get something that simple.

 Maybe this is a bug. And also maybe people don't care, because it seems to be at least 3 years old :)

 

Hi

I am also a programmer and I understand that you have to give the customer what the request. I do not use MT5 but some of my clients if they use it. I can give you the code I use to find the latest Lots. Modifying it maybe you could find the last stoploss.

Best Regards

HistorySelect(0,TimeCurrent());
//--- create objects
   uint     total=HistoryDealsTotal();
   ulong    ticket=0;
   double   price;
   double   vol;
   datetime time;
   datetime lasttime=0;
   string   symbol;
   long     entry;
   double   lot=volume;
//--- for all deals
   for(uint i=0;i<total;i++)
   {
      //--- try to get deals ticket
      if((ticket=HistoryDealGetTicket(i))>0)
      {
         //--- get deals properties
         price =HistoryDealGetDouble(ticket,DEAL_PRICE);
         vol=HistoryDealGetDouble(ticket,DEAL_VOLUME);
         time  =(datetime)HistoryDealGetInteger(ticket,DEAL_TIME);
         symbol=HistoryDealGetString(ticket,DEAL_SYMBOL);
         entry =HistoryDealGetInteger(ticket,DEAL_ENTRY);
         
         //--- only for current symbol
         if(symbol == Symbol() && entry == DEAL_ENTRY_OUT && time > lasttime)
         {  
            lasttime = time;
            lot=vol;
         }
      }
   }
     
   return(lot);
 
JDeel:

Who asks that big question, it's not me :)

 I personally don't really care, I don't use MT5 and I don't even like it, but I own one of the EA builders and some people use it. So, if someone wants to make a Script where he needs to know the last known SL or TP of the last closed position, what can I say to him? That MT5 has tons of features -positions, orders, deals in, deals out... but there is no way to get something that simple.

 Maybe this is a bug. And also maybe people don't care, because it seems to be at least 3 years old :)

It's not possible to get this information, as modification of SL/TP are not registered in history data. I don't know why, if you need to know, you have to write to ServiceDesk.
 

Old thread, found a workaround if anyone else stumbles across this, and is running an EA on the chart.

Intercept the TRADE_TRANSACTION_POSITION event and store the SL and TP prices into global variables, since the modified values come through here.

void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) {
        if (trans.type == TRADE_TRANSACTION_POSITION) {
              GlobalVariableSet(StringFormat("%lli_SL", trans.position), trans.price_sl);
              GlobalVariableSet(StringFormat("%lli_TP", trans.position), trans.price_tp);
        }
}
 
Alain Verleyen:
It's not possible to get this information, as modification of SL/TP are not registered in history data. I don't know why, if you need to know, you have to write to ServiceDesk.

Has there been any progress with this? I'm also trying to get SL/TP that was set after the order was created for historical trades. It always returns 0.0. 

 

You can use this function:

//+------------------------------------------------------------------+
//| Print info of a closed position by its pos_ticket or pos_id.     |
//+------------------------------------------------------------------+
bool PrintClosedPosition(long position_ticket)
  {
//--- request the history of deals and orders for the specified position
   if(!HistorySelectByPosition(position_ticket))
     {
      Print(__FUNCTION__+" > Error: failed to select position ticket #",position_ticket,". Error Code: ", GetLastError());
      return(false);
     }
//---
   CDealInfo deal;
   string    pos_symbol=NULL;
   long      pos_id=-1;
   long      pos_type=-1;
   long      pos_magic=-1;
   double    pos_open_price=0;
   double    pos_close_price=0;
   double    pos_sl = 0;
   double    pos_tp = 0;
   double    pos_commission = 0;
   double    pos_swap=0;
   double    pos_profit=0;
   double    pos_open_volume= 0;
   double    pos_close_volume=0;
   datetime  pos_open_time=0;
   datetime  pos_close_time=0;
   double    pos_sum_cost=0;
   long      pos_close_reason=-1;

//--- now process the list of received deals for the specified position
   int deals=HistoryDealsTotal();
   for(int i=0; i<deals && !IsStopped(); i++)
     {
      if(!deal.SelectByIndex(i))
        {
         Print(__FUNCTION__+" > Error: failed to select deal at index #", i);
         return(false);
        }
      //---
      pos_id              = deal.PositionId();
      pos_symbol          = deal.Symbol();
      pos_commission     += deal.Commission();
      pos_swap           += deal.Swap();
      pos_profit         += deal.Profit();
      //---
      if(deal.Entry()==DEAL_ENTRY_IN)
        {
         pos_magic           = deal.Magic();
         pos_type            = deal.DealType();
         pos_open_time       = deal.Time();
         pos_open_price      = deal.Price();
         pos_open_volume     = deal.Volume();
         //---
         if(HistoryOrderSelect(deal.Order()))
           {
            pos_sl = HistoryOrderGetDouble(deal.Order(), ORDER_SL);
            pos_tp = HistoryOrderGetDouble(deal.Order(), ORDER_TP);
           }
        }
      //---
      else if(deal.Entry()==DEAL_ENTRY_OUT || deal.Entry()==DEAL_ENTRY_OUT_BY)
        {
         pos_close_time      = deal.Time();
         pos_sum_cost       += deal.Volume() * deal.Price();
         pos_close_volume   += deal.Volume();
         pos_close_price     = pos_sum_cost / pos_close_volume;
         pos_close_reason    = HistoryDealGetInteger(deal.Ticket(), DEAL_REASON);
         //---
         if(pos_close_reason==DEAL_REASON_SL)
           {
            HistoryOrderSelect(deal.Order());
            pos_sl = HistoryOrderGetDouble(deal.Order(), ORDER_PRICE_OPEN);
           }
         //---
         else if(pos_close_reason==DEAL_REASON_TP)
           {
            HistoryOrderSelect(deal.Order());
            pos_tp = HistoryOrderGetDouble(deal.Order(), ORDER_PRICE_OPEN);
           }
        }
     }
//--- If the position is still open, it will not be displayed in the history.
   if(deals<2 || MathAbs(pos_open_volume-pos_close_volume)>0.00001)
     {
      Print(__FUNCTION__+" > Error: position with ticket #",position_ticket," is still open.");
      return(false);
     }
//---
   SymbolSelect(pos_symbol,true);
   int digits=(int)SymbolInfoInteger(pos_symbol,SYMBOL_DIGITS);
//---
   Print("Position Open Time: ", (string)pos_open_time);
   Print("Position Symbol: ",      pos_symbol);
   Print("Position Ticket: ",      pos_id);
   Print("Position Type: ",        EnumToString((ENUM_DEAL_TYPE)pos_type));
   Print("Position Volume: ",      DoubleToString(pos_open_volume,2));
   Print("Position Open Price: ",  DoubleToString(pos_open_price,digits));
   Print("Position S/L: ", (pos_sl ? DoubleToString(pos_sl,digits) : ""));
   Print("Position T/P: ", (pos_tp ? DoubleToString(pos_tp,digits) : ""));
   Print("Position Close Time: ", (string)pos_close_time);
   Print("Position Close Price: ", DoubleToString(pos_close_price,(deals==2 ? digits : digits+3)));
   Print("Position Commission: ",  DoubleToString(pos_commission,2));
   Print("Position Swap: ",        DoubleToString(pos_swap,2));
   Print("Position Profit: ",      DoubleToString(pos_profit,2));
   Print("Position Magic Number",  pos_magic);
   Print("Position Close Reason",  EnumToString((ENUM_DEAL_REASON)pos_close_reason));
//---
   return(true);
  }
//+------------------------------------------------------------------+


Also, it is used in this script

https://www.mql5.com/en/code/32330