FORTS: To help beginners - page 5

 
Mikhail Filimonov:

Frequently used and useful functions:

Redesigned GetPositionPrice() function:

This function shows the wrong result, or rather the wrong result. I looked into it and found out that the Position ID does not change at U-turn (i.e. during an in/out trade), as described in documentation:

https://www.mql5.com/ru/docs/constants/tradingconstants/positionproperties

A position reversal changes its ID to the order ticket that resulted in the reversal.

Your GetPositionPrice can pile up 2 or more oppositely directed positions if there is a reversal, and calculates an average price for them. Such an average price of a position is of no practical use.

So, does the Position ID change on reversal or not?

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
the position number does not change when turning
 
How can you tell which volume closed a previous position and which opened a new one from an in/out trade?
 
igorbel:
How can you tell from an in/out trade which volume closed a previous position and which opened a new one?
You can compare it with the current open. But it's better to examine the history of the position by its id, which does not change when you flip it... Buy/sell volumes to help.
 
Dennis Kirichenko:
It can be compared with the current open position. But it is better to examine the history of the position by its id, which does not change when the position is reversed... Buy/sell volumes to help.

As of recently, the Position ID CHANGES when you turn around. Documentation on this has already been updated....

POSITION_IDENTIFIER

The Position ID is a unique number, which is assigned to each newly opened position and does not change throughout its lifetime. It corresponds to the ticket of the order with which the position was opened.

The position identifier is specified in each order (ORDER_POSITION_ID) and each trade (DEAL_POSITION_ID) which opened, changed or closed it. Use this property to search for orders and trades related to the position.

A reversal of a position changes its identifier to the order ticket which resulted in the reversal.

long

 
Dennis Kirichenko:
You could compare it with the current open. But it is better to examine the history of the position by the id, which does not change during a reversal... Buy/sell volumes to help.

This is not an option at all. The previous position could also be open due to a reversal etc. Could be an option, but clearly not an optimal one.

 
Andrey Barinov:

As of recently, the Position ID CHANGES when you turn around. Documentation on this has already been updated....

POSITION_IDENTIFIER

The Position ID is a unique number, which is assigned to each newly opened position and does not change throughout its lifetime. It corresponds to the ticket of the order with which the position was opened.

The position identifier is specified in each order (ORDER_POSITION_ID) and each trade (DEAL_POSITION_ID) which opened, changed or closed it. Use this property to search for orders and trades associated with the position.

A reversal of a position changes its identifier to the order ticket which resulted in the reversal.

long

It's written like this, but in reality nothing changes.

If you like, my code:

long pos_id1,pos_id2,pos_id3;
   ulong deal1_ticket=xxx;
   ulong deal2_ticket=xxx;
   ulong deal3_ticket=xxx;
   if(!HistoryDealSelect(deal1_ticket))
      Print(__FUNCTION__+": deal 1 not selected. Error=",GetLastError());   
   pos_id1=HistoryDealGetInteger(deal1_ticket,DEAL_POSITION_ID);
   Print(__FUNCTION__+": ticket=",deal1_ticket,", position ID=",pos_id1);
   if(!HistoryDealSelect(deal2_ticket))
      Print(__FUNCTION__+": deal 2 not selected. Error=",GetLastError());
   pos_id2=HistoryDealGetInteger(deal2_ticket,DEAL_POSITION_ID);
   Print(__FUNCTION__+": ticket=",deal2_ticket,", position ID=",pos_id2);
   if(!HistoryDealSelect(deal3_ticket))
      Print(__FUNCTION__+": deal 3 not selected. Error=",GetLastError());
   pos_id3=HistoryDealGetInteger(deal3_ticket,DEAL_POSITION_ID);
   Print(__FUNCTION__+": ticket=",deal3_ticket,", position ID=",pos_id3);

Where deal2_ticket is the in/out transaction ticket, deal1_ticket is the ticket preceding the in/out transaction, deal3_ticket is the ticket after the in/out transaction. In all three cases I get the same Position ID.

 
igorbel:

It says so, but in reality nothing changes.

If you like, my code:

Where deal2_ticket is the in/out transaction ticket, deal1_ticket is the ticket preceding the in/out transaction, deal3_ticket is the ticket after the in/out transaction. In all three cases I get the same Position ID.

Mine is changing. Try on the most recent build 1340.
 
igorbel:
And how can we determine from an in/out trade which volume closed the previous position and which opened the new one?

This Expert Advisor is run in "Debugging on History" mode on a netting account. The example is a little rough, because it is calculated that there is only one deal of "IN/OUT" type in the deal history.

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#include <Trade\Trade.mqh>
CTrade my_trade;
long deal_positions_id_in_out=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   static int t=0;
   if(t==20)
     {
      my_trade.Buy(0.02);
     }
   if(t==25)
     {
      my_trade.Buy(0.01);
     }
   if(t==30)
     {
      my_trade.Sell(0.07);
     }
   if(t==40)
     {
      my_trade.PositionClose(Symbol());
     }
   if(t==50)
     {
      //--- request trade history 
      HistorySelect(0,TimeCurrent());
      long     deal_positions_id=0;
      double   deal_volume=0;
      long     deal_entry=0;
      long     deal_type=0;
      ulong    ticket=0;
      for(int i=0;i<HistoryDealsTotal();i++)
        {
         if((ticket=HistoryDealGetTicket(i))>0)
           {
            deal_positions_id=HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
            deal_volume=HistoryDealGetDouble(ticket,DEAL_VOLUME);
            deal_entry=HistoryDealGetInteger(ticket,DEAL_ENTRY);
            deal_type=HistoryDealGetInteger(ticket,DEAL_TYPE);
            if(deal_entry==DEAL_ENTRY_INOUT)
               deal_positions_id_in_out=deal_positions_id;
            Print("DEAL_POSITION_ID ",deal_positions_id,
                  ", DEAL_VOLUME ",DoubleToString(deal_volume,2),
                  ", DEAL_ENTRY ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),
                  ", DEAL_TYPE ",EnumToString((ENUM_DEAL_TYPE)deal_type));
           }
        }
     }
   if(t==55)
     {
      //--- request trade history 
      HistorySelect(0,TimeCurrent());
      long     deal_positions_id=0;
      double   deal_volume=0;
      long     deal_entry=0;
      long     deal_type=0;
      ulong    ticket=0;
      double   volume_in=0;
      double   volume_out=0;
      for(int i=0;i<HistoryDealsTotal();i++)
        {
         if((ticket=HistoryDealGetTicket(i))>0)
           {
            deal_positions_id=HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
            deal_volume=HistoryDealGetDouble(ticket,DEAL_VOLUME);
            deal_entry=HistoryDealGetInteger(ticket,DEAL_ENTRY);
            deal_type=HistoryDealGetInteger(ticket,DEAL_TYPE);
            if(deal_positions_id==deal_positions_id_in_out && deal_entry==DEAL_ENTRY_IN)
               volume_in+=deal_volume;
            else if(deal_positions_id==deal_positions_id_in_out && deal_entry==DEAL_ENTRY_INOUT)
               volume_out=deal_volume;
           }
        }
      Print("DEAL_POSITION_ID ",deal_positions_id_in_out,
            ": volume in ",DoubleToString(volume_in,2),", volume out ",DoubleToString(volume_out,2));
     }
   t++;
  }
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//---

  }
//+------------------------------------------------------------------+

At first, after all executed deals and complete closing of a position, the descriptions of all deals are shown(DEAL_POSITION_ID, DEAL_VOLUME, DEAL_ENTRY,DEAL_TYPE), at that DEAL_POSITION_ID for a deal of IN/OUT type is memorized.

Then it goes through the history again and sums all entries for trades with DEAL_POSITION_ID.

This is approximately what we obtain:

10:58:23.963    Test (EURUSD,H1)        2016.01.04 00:06:42   CTrade::OrderSend: instant buy 0.04 EURUSD at 1.08732 [done at 1.08732]
10:58:30.692    Test (EURUSD,H1)        2016.01.04 00:07:10   DEAL_POSITION_ID 0, DEAL_VOLUME 0.00, DEAL_ENTRY DEAL_ENTRY_IN, DEAL_TYPE DEAL_TYPE_BALANCE
10:58:30.784    Test (EURUSD,H1)        2016.01.04 00:07:10   DEAL_POSITION_ID 2, DEAL_VOLUME 0.02, DEAL_ENTRY DEAL_ENTRY_IN, DEAL_TYPE DEAL_TYPE_BUY
10:58:32.074    Test (EURUSD,H1)        2016.01.04 00:07:10   DEAL_POSITION_ID 2, DEAL_VOLUME 0.01, DEAL_ENTRY DEAL_ENTRY_IN, DEAL_TYPE DEAL_TYPE_BUY
10:58:33.826    Test (EURUSD,H1)        2016.01.04 00:07:10   DEAL_POSITION_ID 2, DEAL_VOLUME 0.07, DEAL_ENTRY DEAL_ENTRY_INOUT, DEAL_TYPE DEAL_TYPE_SELL
10:58:37.237    Test (EURUSD,H1)        2016.01.04 00:07:10   DEAL_POSITION_ID 4, DEAL_VOLUME 0.04, DEAL_ENTRY DEAL_ENTRY_OUT, DEAL_TYPE DEAL_TYPE_BUY
10:59:07.397    Test (EURUSD,H1)        2016.01.04 00:07:19   DEAL_POSITION_ID 2: volume in 0.03, volume out 0.07
Files:
Test.mq5  5 kb
 
Andrey Barinov:
It's changing for me. Try it on the latest build 1340.
That's what I tried. What market do you change on?