Getting unique identifier to refer to and manage open trade in MQL5 hedging

 
Hi,

I'm new to programming in MQL5 (and programming in general). I'm currently writing an expert advisor, and I need it to open multiple positions at once for the purpose of scaling out and adjusting positions. 

My MT5 is in hedging mode. I've figured out how to use cTrade to open positions. But what I want to be able to do is to open positions in 3 separate trades. When I look at my list of open trades, I want to see 3 separate trades in the same direction. Right when I open each part, I want to fetch a unique identifier for each part of the trade (magic number/ticket number?) and store it in a variable. This is something I could not figure out how to do, and I've done a lot of research. How can I fetch this unique identifier once the trade is placed?

Then, say I want to close that trade, or change the stop loss. I want to be able to refer to that part of the trade using the stored unique identifier and perform these operations only on that part of the trade. What function do I use to refer to the trade by identifier and make changes? Is all of this possible to do using cTrade, or do I have to use something else? 

Any help is much appreciated. I'm just beginning to understand MQL5 and I've found it tough to find answers to these questions, especially since MT5 started off as netting only.

Thanks,
VoidSurf
 
VoidSurf:
Hi,

I'm new to programming in MQL5 (and programming in general). I'm currently writing an expert advisor, and I need it to open multiple positions at once for the purpose of scaling out and adjusting positions. 

My MT5 is in hedging mode. I've figured out how to use cTrade to open positions. But what I want to be able to do is to open positions in 3 separate trades. When I look at my list of open trades, I want to see 3 separate trades in the same direction. Right when I open each part, I want to fetch a unique identifier for each part of the trade (magic number/ticket number?) and store it in a variable. This is something I could not figure out how to do, and I've done a lot of research. How can I fetch this unique identifier once the trade is placed?

Then, say I want to close that trade, or change the stop loss. I want to be able to refer to that part of the trade using the stored unique identifier and perform these operations only on that part of the trade. What function do I use to refer to the trade by identifier and make changes? Is all of this possible to do using cTrade, or do I have to use something else? 

Any help is much appreciated. I'm just beginning to understand MQL5 and I've found it tough to find answers to these questions, especially since MT5 started off as netting only.

Thanks,
VoidSurf

Here's a quick example - once you've opened multiple positions, you can loop through all positions this way (and ticket will be the unique ID that you need in order to modify or close positions):

      for (int i=PositionsTotal()-1; i>=0; i--)
      {
         ulong ticket = PositionGetTicket(i);
         ENUM_POSITION_TYPE position = ENUM_POSITION_TYPE(PositionGetInteger(POSITION_TYPE));
         double volume = PositionGetDouble(POSITION_VOLUME);
         double profit = PositionGetDouble(POSITION_PROFIT);
         double openprice = PositionGetDouble(POSITION_PRICE_OPEN);
         Print ("Ticket = ", ticket, ", Type = ", EnumToString(position), ", Volume = ", volume, ", Profit = ", profit);
         
         if (position==POSITION_TYPE_BUY)
            trade.PositionModify(ticket,openprice-100*_Point,openprice+200*_Point);
         
         if (position==POSITION_TYPE_SELL)
            trade.PositionModify(ticket,openprice+100*_Point,openprice-200*_Point);
      }
 
VoidSurf :
Hi,

I'm new to programming in MQL5 (and programming in general). I'm currently writing an expert advisor, and I need it to open multiple positions at once for the purpose of scaling out and adjusting positions. 

My MT5 is in hedging mode. I've figured out how to use cTrade to open positions. But what I want to be able to do is to open positions in 3 separate trades. When I look at my list of open trades, I want to see 3 separate trades in the same direction. Right when I open each part, I want to fetch a unique identifier for each part of the trade (magic number/ticket number?) and store it in a variable. This is something I could not figure out how to do, and I've done a lot of research. How can I fetch this unique identifier once the trade is placed?

Then, say I want to close that trade, or change the stop loss . I want to be able to refer to that part of the trade using the stored unique identifier and perform these operations only on that part of the trade. What function do I use to refer to the trade by identifier and make changes? Is all of this possible to do using cTrade, or do I have to use something else? 

Any help is much appreciated. I'm just beginning to understand MQL5 and I've found it tough to find answers to these questions, especially since MT5 started off as netting only.

Thanks,
VoidSurf

Do you want to use three trading systems at once on a hedge account? In this case, you need to have three Magic numbers.

And now attention:

  • if you use ONE object of the CTrade class - you need to carefully apply SetExpertMagicNumber before any modification of the position (or before opening a position or before closing a position)
  • or use THREE objects of the CTrade class - for each strategy its own m_trade
Documentation on MQL5: Standard Library / Trade Classes / CTrade
Documentation on MQL5: Standard Library / Trade Classes / CTrade
  • www.mql5.com
Standard Library / Trade Classes / CTrade - Reference on algorithmic/automated trading language for MetaTrader 5
 
Vladimir Karputov:

Do you want to use three trading systems at once on a hedge account? In this case, you need to have three Magic numbers.

And now attention:

  • if you use ONE object of the CTrade class - you need to carefully apply SetExpertMagicNumber before any modification of the position (or before opening a position or before closing a position)
  • or use THREE objects of the CTrade class - for each strategy its own m_trade

I'm not running 3 separate strategies, my strategy just involves opening positions in 3 separate trades and modifying them separately.

I have tried using 3 objects of CTrade. Here's part of a simple example I wrote to test this concept:

CTrade trade1;
CTrade trade2;
CTrade trade3;

//Buy Trades
      if(some_condition_true){
         
         //Close any open sell trades
         trade1.PositionClose(_Symbol);
         trade2.PositionClose(_Symbol);
         trade3.PositionClose(_Symbol);

         //Open buy trades
         trade1.Buy(lots,_Symbol,0,0,0,"buy trade 1");
         trade2.Buy(lots,_Symbol,0,0,0,"buy trade 2");
         trade2.Buy(lots,_Symbol,0,0,0,"buy trade 3");
         }

//Sell trades   
      if(other_condition_true){
         // Close any open buy trades
         trade1.PositionClose(_Symbol); 
         trade2.PositionClose(_Symbol);
         trade3.PositionClose(_Symbol);
         
         // Open sell trades
         trade1.Sell(lots,_Symbol,0,0,0,"sell trade 1"); 
         trade2.Sell(lots,_Symbol,0,0,0,"sell trade 2");
         trade3.Sell(lots,_Symbol,0,0,0,"sell trade 3");
	 }

However, it does not behave as though positions belong to the object that opened it. I tried removing trade1.PositionClose to see if the trade opened by that object would remain open while the others were closed. It seemed to work okay on the surface, only 2 positions would close at once, but which ones seemed arbitrary.  You would think that, since there is no SL or TP, positions opened by trade1 would remain open indefinitely. But I would see the positions opened by trade1 getting closed by the PositionClose of objects 2 or 3 instead of the trades belonging to those objects.

 

So, I figured out that I can get ticket info right after a position is opened by running ResultDeal(), which gives the deal ticket, or ResultOrder(), which gives the order ticket. However, the argument that is passed to a function like PositionClose() is the position ticket, not deal or order ticket. I found this information which may give an answer:

https://www.mql5.com/en/docs/constants/structures/mqltraderequest

position

Ticket of a position. Should be filled in when a position is modified or closed to identify the position. As a rule it is equal to the ticket of the order, based on which the position was opened.

When modifying or closing a position in the hedging system, make sure to specify its ticket (MqlTradeRequest::position). The ticket can also be specified in the netting system, though a position is identified by the symbol name.


Based on this, am I right to conclude that the position ticket is always equal to the order ticket? It says "as a rule", but I'm not sure if that means "always" or "usually". Could I write some code like this?

CTrade trade;
ulong ticket1, ticket2;
double lots = 1;

if(condition_1){trade.Buy(lots,_Symbol,0,0,0,); ticket1 = ResultOrder();}
if(condition_2){trade.Buy(lots,_Symbol,0,0,0,); ticket2 = ResultOrder();}

if(condition_3){trade.PositionClose(ticket1);}
if(condition_4){trade.PositionClose(ticket2);}
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Request Structure
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Request Structure
  • www.mql5.com
Interaction between the client terminal and a trade server for executing the order placing operation is performed by using trade requests. The trade request is represented by the special predefined structure of MqlTradeRequest type, which contain all the fields necessary to perform trade deals. The request processing result is represented by...
 

You cannot use a deal ticket to close a position.

ResultDeal

Gets the deal ticket.

ulong  ResultDeal() const

Return Value
Deal ticket if the deal is executed.
bool  PositionClose(
   const ulong   ticket,                  // position ticket
   ulong         deviation=ULONG_MAX      // deviation
   )
See also here:

https://www.mql5.com/en/articles/211

Orders, Positions and Deals in MetaTrader 5
Orders, Positions and Deals in MetaTrader 5
  • www.mql5.com
The ultimate goal of a trader is to extract profits through the means of trading operations on the financial markets. This article describes the terms and processes of the MetaTrader 5 trading platform, the knowledge of which is necessary for a proper understanding of the work of trade functions of the MQL5 language. Orders — are the trade...
 
VoidSurf :

I'm not running 3 separate strategies, my strategy just involves opening positions in 3 separate trades and modifying them separately.

I have tried using 3 objects of CTrade. Here's part of a simple example I wrote to test this concept:

However, it does not behave as though positions belong to the object that opened it. I tried removing trade1.PositionClose to see if the trade opened by that object would remain open while the others were closed. It seemed to work okay on the surface, only 2 positions would close at once, but which ones seemed arbitrary.  You would think that, since there is no SL or TP, positions opened by trade1 would remain open indefinitely. But I would see the positions opened by trade1 getting closed by the PositionClose of objects 2 or 3 instead of the trades belonging to those objects.

You are welcome

  1. read help: what is a netting account and what is a hedge account
  2. check out two methods PositionClose:
    Closes a position by the specified symbol
    bool  PositionClose(
       const string  symbol,                  // symbol
       ulong         deviation=ULONG_MAX      // deviation
       )
    Closes a position with the specified ticket
    bool  PositionClose(
       const ulong   ticket,                  // position ticket
       ulong         deviation=ULONG_MAX      // deviation
       )
    Note

    For the "netting" interpretation of positions (ACCOUNT_MARGIN_MODE_RETAIL_NETTING and ACCOUNT_MARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of time. This position is a result of one or more deals. Do not confuse positions with valid pending orders, which are also displayed on the Trading tab of the Toolbox window.

    If individual positions are allowed (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING), multiple positions can be open for one symbol. In this case, PositionClose will close a position with the lowest ticket.


Documentation on MQL5: Standard Library / Trade Classes / CTrade / PositionClose
Documentation on MQL5: Standard Library / Trade Classes / CTrade / PositionClose
  • www.mql5.com
Successful completion of the PositionClose(...) method does not always mean successful execution of the trade operation. It is necessary to check the result of trade request (trade server return code) using ResultRetcode...
 
lippmaje:

You cannot use a deal ticket to close a position.

See also here:

https://www.mql5.com/en/articles/211

I made a mistake in the code I wrote. I meant to write ResultOrder() instead of ResultDeal(). I corrected it now. The reason I believe this will work is because of the text here: 

position

Ticket of a position. Should be filled in when a position is modified or closed to identify the position. As a rule it is equal to the ticket of the order, based on which the position was opened.


I will test this concept and update you here.

 
Vladimir Karputov:

You are welcome

  1. read help: what is a netting account and what is a hedge account
  2. check out two methods PositionClose:
    Closes a position by the specified symbol
    Closes a position with the specified ticket
    Note

    For the "netting" interpretation of positions (ACCOUNT_MARGIN_MODE_RETAIL_NETTING and ACCOUNT_MARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of time. This position is a result of one or more deals. Do not confuse positions with valid pending orders, which are also displayed on the Trading tab of the Toolbox window.

    If individual positions are allowed (ACCOUNT_MARGIN_MODE_RETAIL_HEDGING), multiple positions can be open for one symbol. In this case, PositionClose will close a position with the lowest ticket.


Thank you for helping, I appreciate you taking the time. I already understand hedging vs. netting, what I don't understand is how to uniquely identify positions once they are opened in the hedging system. MqlTradeResult does not return any position ticket, but based on the text in the documentation, I assume it must be equal to the order ticket. I will test this out.
 
VoidSurf :
Thank you for helping, I appreciate you taking the time. I already understand hedging vs. netting, what I don't understand is how to uniquely identify positions once they are opened in the hedging system. MqlTradeResult does not return any position ticket, but based on the text in the documentation, I assume it must be equal to the order ticket. I will test this out.

I still do not understand what exactly you want.

In principle, it doesn’t matter: you opened three positions or you opened one hundred positions. If they need to be modified - move stop loss, then the universal function is used.


In general, explain (if you cannot explain in words - draw pictures) - what you want to do.

 

I can confirm that this does work. After placing the trade using a CTrade object, use ResultOrder() to get the order ticket, which appears to always be equal to the resulting position ticket. Store this ticket in a ulong variable, and then use it in PositionModify() or PositionClose() to manipulate.


Thanks to everyone for their help.