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);
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 :)
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); } }
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
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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: