Problem with changing a Position triggered by a Buy-Stop order

 
Hi,

I'm placing BUY_STOP and SELL_STOP orders.

E.g. SELL_STOP oder gets Position/Ticket # 11

When SELL_STOP order triggers, the Open Position has also the Position/Ticket # 11.

Now I want to change the the TAKE PROFIT value of this Position. To select the order to be changed, I use this command, which gives me the Position # 11 for the ticket:

// in this loop we're checking all opened positions
   for(i=0; i<PositionsTotal(); i++)
     {
      // processing orders with "our" symbols only
      if((Symbol()==PositionGetSymbol(i)) && (PositionGetInteger(POSITION_MAGIC) == MA_MAGIC))
        {
         ticket = PositionGetInteger(POSITION_IDENTIFIER);
         request.order= ticket;
But I always get the errror:
 failed modify #11 sell 0.10 EURUSD sl: 1.11574, tp: 0.00000 -> sl: 1.11572, tp: 1.11105 [Position doesn't exist]

From OrderCheck i get the following Errors (see Code below):

2019.11.23 21:55:13.571 2019.11.01 01:16:24   Error: ERR_TRADE_SEND_FAILED (4756): Trade request sending failed
2019.11.23 21:55:19.105 2019.11.01 01:16:24   Error: 10036: Position with the specified POSITION_IDENTIFIER has already been closed


In the Trading Tab the open Position shows the open position with ticket # 11.

I try to change the TP with this code:

if((PositionGetDouble(POSITION_SL)==0 || NormalizeDouble(PositionGetDouble(POSITION_SL)-StopLoss,_Digits)>0
                // if TakeProfit is not defined or lower than needed
                || PositionGetDouble(POSITION_TP)==0 || NormalizeDouble(atr_l[0]-PositionGetDouble(POSITION_TP),_Digits)>0)
               // is new StopLoss close to the current price?
               && NormalizeDouble(StopLoss-SymbolInfoDouble(Symbol(),SYMBOL_ASK)-StopLevel,_Digits)>0
               // is new TakeProfit close to the current price?
               && NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_ASK)-atr_l[0]-StopLevel,_Digits)>0)
              {
               // putting new value of StopLoss to the structure
               request.sl=NormalizeDouble(StopLoss,_Digits);
               // putting new value of TakeProfit to the structure
               request.tp=NormalizeDouble(atr_l[0],_Digits);
               // sending request to trade server
               if(OrderCheck(request,testresult))
                 {
                  Print("Error: ",ReturnCodeDescription(GetLastError()));
                  Print("Error: ",ReturnCodeDescription(testresult.retcode));
                 }
               else
                  OrderSend(request,result);
              }


In the Journal I can find following information:

2019.11.23 21:36:34.397 2019.11.01 01:16:24   order [#11 sell stop 0.10 EURUSD at 1.11511] triggered
2019.11.23 21:36:34.397 2019.11.01 01:16:24   deal #10 sell 0.10 EURUSD at 1.11511 done (based on order #11)
2019.11.23 21:36:34.397 2019.11.01 01:16:24   deal performed [#10 sell 0.10 EURUSD at 1.11511]
2019.11.23 21:36:34.397 2019.11.01 01:16:24   order performed sell 0.10 at 1.11511 [#11 sell stop 0.10 EURUSD at 1.11511]

Do I have to use the 'deal number' instead (and how to get them)?

Could you plese help me, how to change TP in an open position triggered by a Buy-Stop order?

 

This is the first:

Ticket position is:

(ulong)PositionGetInteger(POSITION_TICKET)

but not:

PositionGetInteger(POSITION_IDENTIFIER);


Second: the position must be bypassed TO ZERO (sample code from all my advisers)

   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of open positions
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
 
Vladimir Karputov:

This is the first:

Ticket position is:

but not:


Second: the position must be bypassed TO ZERO (sample code from all my advisers)

Thank you for your response.

I tried

(ulong)PositionGetInteger(POSITION_TICKET)

as well, but I got the same as with:

PositionGetInteger(POSITION_IDENTIFIER);

(I'll change it back :-) )

My OnTick() Functuion starts with:

void OnTick()
  {
   MqlTradeRequest request;
   MqlTradeResult result;
   MqlDateTime dt;
   ZeroMemory(request);
I use 'ZeroMemory', is that what you mean?
 
MT5-softcase:
Hi,

I'm placing BUY_STOP and SELL_STOP orders.

E.g. SELL_STOP oder gets Position/Ticket # 11

When SELL_STOP order triggers, the Open Position has also the Position/Ticket # 11.

Basic Principles

Interrelation of orders, deals and positions

The platform allows you to easily track how a position was opened or how a deal was performed. Each trading operation has its unique ID called a "ticket". Each order and deal receive a ticket relating to their relevant position. Each deal receives a ticket of an order, by which it was concluded.

If a position was affected by multiple deals, for example in the case of a partial closing or increasing volumes, each of the deals feature the position's ticket. This makes it easy to track the entire history of the position as a whole.

If trading operations are sent to an exchange or a liquidity provider, they additionally feature an ID from an external system. This allows additional tracking of the interrelation of operations away from the platform.

The history of opening a position can be tracked by tickets

Basic Principles - Trading Operations - MetaTrader 5 Help
Basic Principles - Trading Operations - MetaTrader 5 Help
  • www.metatrader5.com
is an instruction given to a broker to buy or sell a financial instrument. There are two main types of orders: Market and Pending. In addition, there are special Take Profit and Stop Loss levels. is the commercial exchange (buying or selling) of a financial security. Buying is executed at the demand price (Ask), and Sell is performed at the...
 

Add:

Position Properties

POSITION_TICKET

Position ticket. Unique number assigned to each newly opened position. It usually matches the ticket of an order used to open the position except when the ticket is changed as a result of service operations on the server, for example, when charging swaps with position re-opening. To find an order used to open a position, apply the POSITION_IDENTIFIER property.
 

POSITION_TICKET value corresponds to  MqlTradeRequest::position.

long

Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Position Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Position Properties
  • www.mql5.com
Position ticket. Unique number assigned to each newly opened position. It usually matches the ticket of an order used to open the position except when the ticket is changed as a result of service operations on the server, for example, when charging swaps with position re-opening. To find an order used to open a position, apply the...
 

And now attention to what your algorithm should look like:

* First: you need to use trading classes - they are lighter and require fewer lines

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class

* You place a pending order (DO NOT REMEMBER A TICKET)

* In the adviser, simply write the correct trailing procedure (AGAIN: THERE IS NO SENSE TO USE A SAVED TICKET OF A PENDING ORDER)

//+------------------------------------------------------------------+
//| Trailing                                                         |
//|   InpTrailingStop: min distance from price to Stop Loss          |
//+------------------------------------------------------------------+
void Trailing(const double stop_level)
  {
   /*
      Buying is done at the Ask price                 |  Selling is done at the Bid price
      ------------------------------------------------|----------------------------------
      TakeProfit        >= Bid                        |  TakeProfit        <= Ask
      StopLoss          <= Bid                        |  StopLoss          >= Ask
      TakeProfit - Bid  >= SYMBOL_TRADE_STOPS_LEVEL   |  Ask - TakeProfit  >= SYMBOL_TRADE_STOPS_LEVEL
      Bid - StopLoss    >= SYMBOL_TRADE_STOPS_LEVEL   |  StopLoss - Ask    >= SYMBOL_TRADE_STOPS_LEVEL
   */
   if(InpTrailingStop==0)
      return;
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of open positions
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
           {
            double price_current = m_position.PriceCurrent();
            double price_open    = m_position.PriceOpen();
            double stop_loss     = m_position.StopLoss();
            double take_profit   = m_position.TakeProfit();
            double ask           = m_symbol.Ask();
            double bid           = m_symbol.Bid();
            //---
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               if(price_current-price_open>m_trailing_stop+m_trailing_step)
                  if(stop_loss<price_current-(m_trailing_stop+m_trailing_step))
                     if(m_trailing_stop>=stop_level && (take_profit-bid>=stop_level || take_profit==0.0))
                       {
                        if(!m_trade.PositionModify(m_position.Ticket(),
                                                   m_symbol.NormalizePrice(price_current-m_trailing_stop),
                                                   take_profit))
                           if(InpPrintLog)
                              Print(__FILE__," ",__FUNCTION__,", ERROR: ","Modify BUY ",m_position.Ticket(),
                                    " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),
                                    ", description of result: ",m_trade.ResultRetcodeDescription());
                        if(InpPrintLog)
                          {
                           RefreshRates();
                           m_position.SelectByIndex(i);
                           PrintResultModify(m_trade,m_symbol,m_position);
                          }
                        continue;
                       }
              }
            else
              {
               if(price_open-price_current>m_trailing_stop+m_trailing_step)
                  if((stop_loss>(price_current+(m_trailing_stop+m_trailing_step))) || (stop_loss==0))
                     if(m_trailing_stop>=stop_level && ask-take_profit>=stop_level)
                       {
                        if(!m_trade.PositionModify(m_position.Ticket(),
                                                   m_symbol.NormalizePrice(price_current+m_trailing_stop),
                                                   take_profit))
                           if(InpPrintLog)
                              Print(__FILE__," ",__FUNCTION__,", ERROR: ","Modify SELL ",m_position.Ticket(),
                                    " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),
                                    ", description of result: ",m_trade.ResultRetcodeDescription());
                        if(InpPrintLog)
                          {
                           RefreshRates();
                           m_position.SelectByIndex(i);
                           PrintResultModify(m_trade,m_symbol,m_position);
                          }
                       }
              }
           }
  }


Later I will give the full advisor code ...

 
Vladimir Karputov:

And now attention to what your algorithm should look like:

* First: you need to use trading classes - they are lighter and require fewer lines

* You place a pending order (DO NOT REMEMBER A TICKET)

* In the adviser, simply write the correct trailing procedure (AGAIN: THERE IS NO SENSE TO USE A SAVED TICKET OF A PENDING ORDER)


Later I will give the full advisor code ...

Thank you very much for your detailed answer. It gave me a clearer understanding of differences between Orders, Positions, Tickets and deals.

I also found the core issue of my problem. It is in the first code snippet:

I tried do select the trading position by assigning the ticket number to the 'order' instead of the 'position'.
Using 'request.order' is correct for changing parametes of a pending order. But as soon the pending order has triggered 'request.position' has to be used.


// in this loop we're checking all opened positions
   for(i=0; i<PositionsTotal(); i++)
     {
      // processing orders with "our" symbols only
      if((Symbol()==PositionGetSymbol(i)) && (PositionGetInteger(POSITION_MAGIC) == MA_MAGIC))
        {
         ticket = PositionGetInteger(POSITION_IDENTIFIER);
         request.order= ticket;                     //Wrong, because the pending order has already triggert and we are now hav to handl 'Positions'
         request.position= ticket;                  //correct
 

Hey,

sorry, one question again about your Code, @Vladimir Kaputov:

for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of open positions
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)

The last line:

Isn't it possible that with the same Magic-No. and in the syme symbol there are two positions running (hedging mode)?
So if i want to modify just on i should have previously saved the ticket id, right?

The Code above would just find the first of the both, but which one it is, wouldn't be clear. Am i understanding it right?

Thx & Regards!

 
DojiQ :

Hey,

sorry, one question again about your Code, @Vladimir Kaputov:

The last line:

Isn't it possible that with the same Magic-No. and in the syme symbol there are two positions running (hedging mode)?
So if i want to modify just on i should have previously saved the ticket id, right?

The Code above would just find the first of the both, but which one it is, wouldn't be clear. Am i understanding it right?

Thx & Regards!

Let me explain: it makes no difference at all - netting or hedging, these are three universal lines. They work ONLY for the current symbol and for a SPECIFIC Magic. The ultimate goal is to CHOOSE A POSITION. You do not need to save any tickets.

In general, I advise you to first think about what exactly you need to get, and then apply the code.

 
Thomas G Glasmensch:

Thank you very much for your detailed answer. It gave me a clearer understanding of differences between Orders, Positions, Tickets and deals.

I also found the core issue of my problem. It is in the first code snippet:

I tried do select the trading position by assigning the ticket number to the 'order' instead of the 'position'.
Using 'request.order' is correct for changing parametes of a pending order. But as soon the pending order has triggered 'request.position' has to be used.


i still doesn't understand the differences between Orders, Positions, Tickets and Deals...:(

 
Ariel Pardo: i still doesn't understand the differences between Orders, Positions, Tickets and Deals...:(

I will try to give a world example to make it a little easier!

Suppose you go to a workshop and request them to make you 5 custom pens, so you submit them an "Order".

The workshop owner then goes to his suppliers and orders the parts, such as the metal for the casing, and ink for the cartridge and wood for the box, etc. These are the "Deals".

And finally, he is only able to make 4 pens instead of the 5 because of lack of materials and charges you even a little more due to wood becoming more expensive (slippage). So, your final "Position" is only 4 pens, instead of the 5 you ordered, and is more expensive than original estimates.

Obviously this is very simplified, but it is just to make it a little easier for you to understand.

In trading, the "Order" is what you request; the "Deals" are the individual dealings that take place between different sources in order to fulfill your request, and the "Position" is the final outcome of all those dealings, which may or may not fulfill your original request, both in price and in volume.

I hope that helps. I suggest you read the following article on the subject: Orders, Positions and Deals in MetaTrader 5

Orders, Positions and Deals in MetaTrader 5
Orders, Positions and Deals in MetaTrader 5
  • www.mql5.com
Creating a robust trading robot cannot be done without an understanding of the mechanisms of the MetaTrader 5 trading system. The client terminal receives the information about the positions, orders, and deals from the trading server. To handle this data properly using the MQL5, it's necessary to have a good understanding of the interaction between the MQL5-program and the client terminal.