Как узнать номер ордера по( или из) которому открылась позиция?

 

Вопрос очень простой но для меня пока через чур загадочный.

У нас есть позиция. От какого лимитного ордера она появилась? Что надо делать чтобы угадать тикет ордера если у нас есть тикет позиции?

Я конечно понимаю схему что можно на каждом тике проверять не ушёл ли ордер в историю и вылавливать новую позицию, что конечно далеко не айс. А вот как-то можно через OnTradeTransaction сделать вылавливание тикета позиции? Например если у меня есть массив ордеров и позиций, то как мне сделать чтобы в обработке события OnTradeTransaction мой массив обновлялся где у меня вносится номер соответствующей позиции по ордеру.

class CTradeSeries
  {
public:
                     CTradeSeries()
     {
      MasterOrderTicket                   =
         MasterPositionTicket             =
            Pct50OrderTiket               =
               Pct50PositionTiket         =
                  FloatOrderTiket         =
                     FloatPositionTiket   = 0;
     }
   ulong               MasterOrderTicket, MasterPositionTicket;
   ulong               Pct50OrderTiket, Pct50PositionTiket;
   ulong               FloatOrderTiket, FloatPositionTiket;
  };

CTradeSeries TradeSeries[];

Тикеты лимитных ордеров заполняются после вызова функции OrderSend.

Что нужно добавить чтобы по соответствующей лимитному ордеру после его выполнения заполнять тикеты позиций?

Всем спасибо.

Документация по MQL5: Торговые функции / OrderGetTicket
Документация по MQL5: Торговые функции / OrderGetTicket
  • www.mql5.com
OrderGetTicket - Торговые функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

  Вероятно, все это должно находиться в документации.  Идем в документацию. Ордера, позиции - вероятно, торговые функции. Проверим. Имеем  позицию ( не имеем ордера ) - можем получить свойства позиции. PositionGetxxxxxxx - получить нужное. Заходим в любое. Внизу - свойства позиции. Переходим в свойства .

Нашли :   https://www.mql5.com/ru/docs/constants/tradingconstants/positionproperties   


POSITION_IDENTIFIER
Идентификатор позиции - это уникальное число, которое присваивается каждой вновь открытой позиции и не изменяется в течение всей ее жизни. Соответствует тикету ордера, которым была открыта позиция.
Идентификатор позиции указывается в каждом ордере (ORDER_POSITION_ID) и сделке (DEAL_POSITION_ID), которая ее открыла, изменила или закрыла. Используйте это свойство для поиска ордеров и сделок, связанных с позицией.
При развороте позиции в режиме неттинга (единой сделкой in/out) идентификатор позиции POSITION_IDENTIFIER не изменяется. Однако при этом POSITION_TICKET изменяется на тикет ордера, в результате которого произошел разворот. В режиме хеджинга разворот позиции не предусмотрен.


Что об этом есть в поиске : https://www.mql5.com/ru/search#!keyword=POSITION_IDENTIFIER%20%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80   

Первый пример :  https://www.mql5.com/ru/forum/11707#comment_507577  

Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Свойства позиций - Торговые константы - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
DDFedor #:

  Вероятно, все это должно находиться в документации.  Идем в документацию. Ордера, позиции - вероятно, торговые функции. Проверим. Имеем  позицию ( не имеем ордера ) - можем получить свойства позиции. PositionGetxxxxxxx - получить нужное. Заходим в любое. Внизу - свойства позиции. Переходим в свойства .

Нашли :   https://www.mql5.com/ru/docs/constants/tradingconstants/positionproperties   

Спасибо большое, буду иметь ввиду данный метод. Но вот как можно увязать вышесказанное с практикой?

Например, у нас есть вызов OnTradeTransaction, как из этого выловить то что надо?

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)

Вы предлагаете перебирать в истории все позиции и вылавливать ордер на котором открыта позиция, но это будет медленно выполняться. Нужно чтобы тикет позиции вылавливался в одну строчку. Перебирать позиции, не очень хотелось бы.

struct MqlTradeTransaction
  {
   ulong                         deal;             // Тикет сделки
   ulong                         order;            // Тикет ордера
   string                        symbol;           // Имя торгового инструмента
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Тип торговой транзакции
   ENUM_ORDER_TYPE               order_type;       // Тип ордера
   ENUM_ORDER_STATE              order_state;      // Состояние ордера
   ENUM_DEAL_TYPE                deal_type;        // Тип сделки
   ENUM_ORDER_TYPE_TIME          time_type;        // Тип ордера по времени действия
   datetime                      time_expiration;  // Срок истечения ордера
   double                        price;            // Цена 
   double                        price_trigger;    // Цена срабатывания стоп-лимитного ордера
   double                        price_sl;         // Уровень Stop Loss
   double                        price_tp;         // Уровень Take Profit
   double                        volume;           // Объем в лотах
   ulong                         position;         // Тикет позиции
   ulong                         position_by;      // Тикет встречной позиции
  };

Передается структура в которой второй элемент 

   ulong                         order;            // Тикет ордера

Соответствует какому-то ордеру.

Вместе с тем предпоследний элемент

   ulong                         position;         // Тикет позиции

Вероятно соответствует тикету позиции.

Сейчас хотелось бы выяснить Второй и Предпоследний элемент как-то связаны или нет? Вот тогда можно было бы сразу определять тикет ордера на базе которого открылась сделка без всякого перебора и вносить тикет позиции в структуру.

Но вот опять остаётся открытым вопрос на сколько это сопоставление уместно и будет ли оно работать?

PS:

Порылся в документации и там как раз нашёл:

TRADE_TRANSACTION_DEAL_*

Для торговых транзакций, касающихся обработки сделок (TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE и TRADE_TRANSACTION_DEAL_DELETE), в структуре MqlTradeTransaction заполняются следующие поля:

  • deal - тикет сделки;
  • order - тикет ордера, на основе которого совершена сделка;

...


...

  • position - тикет позиции, открытой, измененной или закрытой в результате исполнения сделки.

Это то что в моём случае решит вопрос или нет? Просто не представляю чего можно ожидать. 

Кто-нибудь так делал? 

 
Для хеджа.
POSITION_TICKET = POSITION_ID = ORDER_TICKET


При частичном исполнении живой отложенный ордер и порожденная от него позиция будут с одинаковым тикетом.

Как следствие, ранее закрытая позиция и текущая живая позиция могут иметь одинаковый тикет (и другие параметры из равенства выше).

 
fxsaber #:
Для хеджа.


При частичном исполнении живой отложенный ордер и порожденная от него позиция будут с одинаковым тикетом.

Как следствие, ранее закрытая позиция и текущая живая позиция могут иметь одинаковый тикет (и другие параметры из равенства выше).

Извините Уважаемый, может я немного придираюсь к словам но для меня важно уточнить.

Вы пишите:

Как следствие, ранее закрытая позиция и текущая живая позиция могут иметь одинаковый тикет

Одинаковый тикет чего? Сделки или позиции, или ордера?

 
ROMAN KIVERIN #:

Извините Уважаемый, может я немного придираюсь к словам но для меня важно уточнить.

Вы пишите:

Как следствие, ранее закрытая позиция и текущая живая позиция могут иметь одинаковый тикет

Одинаковый тикет чего? Сделки или позиции, или ордера?

Позиции будут иметь одинаковый тикет, разное время открытия или закрытия при частичном исполнении приказов / ордеров именно.

 
ROMAN KIVERIN #:

Спасибо большое, буду иметь ввиду данный метод. Но вот как можно увязать вышесказанное с практикой?

Например, у нас есть вызов OnTradeTransaction, как из этого выловить то что надо?

Вы предлагаете перебирать в истории все позиции и вылавливать ордер на котором открыта позиция, но это будет медленно выполняться. Нужно чтобы тикет позиции вылавливался в одну строчку. Перебирать позиции, не очень хотелось бы.

Передается структура в которой второй элемент 

Соответствует какому-то ордеру.

Вместе с тем предпоследний элемент

Вероятно соответствует тикету позиции.

Сейчас хотелось бы выяснить Второй и Предпоследний элемент как-то связаны или нет? Вот тогда можно было бы сразу определять тикет ордера на базе которого открылась сделка без всякого перебора и вносить тикет позиции в структуру.

Но вот опять остаётся открытым вопрос на сколько это сопоставление уместно и будет ли оно работать?

PS:

Порылся в документации и там как раз нашёл:

TRADE_TRANSACTION_DEAL_*

Для торговых транзакций, касающихся обработки сделок (TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE и TRADE_TRANSACTION_DEAL_DELETE), в структуре MqlTradeTransaction заполняются следующие поля:

  • deal - тикет сделки;
  • order - тикет ордера, на основе которого совершена сделка;

...


...

  • position - тикет позиции, открытой, измененной или закрытой в результате исполнения сделки.

Это то что в моём случае решит вопрос или нет? Просто не представляю чего можно ожидать. 

Кто-нибудь так делал? 

Поля структуры заполняются не все. При каждом типе транзакции заполняются только некоторые поля, остальные не меняются. Там и мусор может быть и какие-то значения не соответствующее данной транзакции…

 

ROMAN KIVERIN #:

Например, у нас есть вызов OnTradeTransaction, как из этого выловить то что надо?

Для перестраховки, если не нравится вариант 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Как узнать номер ордера по( или из) которому открылась позиция?

fxsaber, 2023.08.15 10:13

Для хеджа.
POSITION_TICKET = POSITION_ID = ORDER_TICKET


При частичном исполнении живой отложенный ордер и порожденная от него позиция будут с одинаковым тикетом.

Как следствие, ранее закрытая позиция и текущая живая позиция могут иметь одинаковый тикет (и другие параметры из равенства выше).


  1. Отлавливаете тип транзакции  TRADE_TRANSACTION_DEAL_ADD
  2. По тикету сделки выбираете её
  3. Получаете POSITION_ID
  4. bool  HistorySelectByPosition(
       long   position_id     // идентификатор позиции - POSITION_IDENTIFIER
       );
    
  5. Из этого списка получить тикет ордера.


 
Alexey Viktorov #:

Для перестраховки, если не нравится вариант 

  1. Отлавливаете тип транзакции  TRADE_TRANSACTION_DEAL_ADD
  2. По тикету сделки выбираете её
  3. Получаете POSITION_ID
  4. Из этого списка получить тикет ордера.

Спасибо! Краткость сестра таланта. Буду пробовать разбираться дальше. Код обязательно выложу.

 
Valeriy Yastremskiy #:

Позиции будут иметь одинаковый тикет, разное время открытия или закрытия при частичном исполнении приказов / ордеров именно.

Спасибо. С мира по нитке, глядишь, вместе осилим.

 

Вот что получилось. Пока вроде устраивает.

//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   if(trans.type == TRADE_TRANSACTION_DEAL_ADD)
     {
      if(PositionSelectByTicket(trans.position))
         for(int Index = 0; Index <= CountSeries; Index++)
           {
            HistoryDealSelect(trans.deal);
            ulong ParentOrderTicket = HistoryDealGetInteger(trans.deal, DEAL_ORDER);
            if(TradeSeries[CountSeries].MasterOrderTicket !=ParentOrderTicket)
               if(TradeSeries[CountSeries].Pct50OrderTiket !=ParentOrderTicket)
                 {
                  if(TradeSeries[CountSeries].FloatOrderTiket !=ParentOrderTicket)
                  continue ;
                  TradeSeries[CountSeries].FloatPositionTiket = trans.position;
	          break;
                 }
               else
                  TradeSeries[CountSeries].Pct50PositionTiket = trans.position;
            else
               TradeSeries[CountSeries].MasterPositionTicket = trans.position;
           }
     }
  }