Объем позиции при первом обращении к OnTradeTransaction() при одновременном исполнении нескольких лимитных ордеров.

 

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

СИТУАЦИЯ: Выставлены три лимитных ордера по 1 контракту каждый на разной цене, но очень близко друг к другу сразу за уровнем. Цена подходит к уровню, резко пробивает его и одновременно забирает все три лимитных ордера за раз. Я обрабатываю событие с помощь OnTradeTransaction(…) следующим способом:

 

void OnTradeTransaction(

   const MqlTradeTransaction&    trans,        // структура торговой транзакции

   const MqlTradeRequest&        request,      // структура запроса

   const MqlTradeResult&         result        // структура ответа

                                     )         

{   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)

     {    if(PositionSelect(_Symbol))

          {   PosVolume=PositionGetDouble(POSITION_VOLUME);

               ……..

           }

      }

}

 

Как я понимаю первое получение объема позиции в переменную PosVolume произойдет (согласно документации) по факту добавления первого из трёх исполненных лимитных ордеров в историю в результате исполнения.

ВОПРОС: При указанном первом входе в OnTradeTransaction(…) по факту события TRADE_TRANSACTION_DEAL_ADD для первого из трёх исполнившихся лимитных ордеров, PosVolume будет получен (варианты ответа):

А) всегда гарантированно равным 1 (ведь это вход от срабатывания первого лимитного ордера и еще два подобных события есть в очереди),

Б) всегда гарантированно равным 3 (ведь все три ордера по 1 контракту каждый  уже исполнились) или

В) он может быть равен 0, 1, 2 или 3 в зависимости от загрузки торгового сервера - как он успеет отработать (ведь в момент пробоя уровня большой интерес участников рынка с обеих сторон и идет большая нагрузка на сервер именуемая разработчиками ошибкой 10024 “To many requests”) ?

Инструмент – фьючерс S&P500, биржа CME.

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торговой транзакции
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торговой транзакции
  • www.mql5.com
Например, при отсылке рыночного ордера на покупку он обрабатывается, для счета создается соответствующий ордер на покупку, происходит исполнение ордера, его удаление из списка открытых, добавление в историю ордеров, далее добавляется соответствующая сделка в историю и создается новая позиция. Все эти действия являются торговыми транзакциями...
 
Посмотрите trans.volume
 
bigluck:

Как я понимаю первое получение объема позиции в переменную PosVolume произойдет (согласно документации) по факту добавления первого из трёх исполненных лимитных ордеров в историю в результате исполнения.

ВОПРОС: При указанном первом входе в OnTradeTransaction(…) по факту события TRADE_TRANSACTION_DEAL_ADD для первого из трёх исполнившихся лимитных ордеров, PosVolume будет получен (варианты ответа):

А) всегда гарантированно равным 1 (ведь это вход от срабатывания первого лимитного ордера и еще два подобных события есть в очереди),

Б) всегда гарантированно равным 3 (ведь все три ордера по 1 контракту каждый  уже исполнились) или

В) он может быть равен 1, 2 или 3 в зависимости от загрузки торгового сервера - как он успеет отработать (ведь в момент пробоя уровня большой интерес участников рынка с обеих сторон и идет большая нагрузка на сервер именуемая разработчиками ошибкой 10024 “To many requests”) ?

Инструмент – фьючерс S&P500, биржа CME.

Вариант В)

Поэтому, нужно всегда отслеживать и ордера, а не только сделки.

У Вас частный случай (объем = 1), а если будет больше, то без ордеров (т.к они отложенные) вовсе не обойтись.

 
Alexey Viktorov:
Посмотрите trans.volume

Посмотрел. А что там надо было смотреть? Уточните пжлста Вашу рекомендацию.

Что увидел я: trans.volume в структуре MqlTradeTransaction имеет отношение к размеру позиции только при событии TRADE_TRANSACTION_POSITION. Однако, в документации в отношении этого идентификатора заявлено: "Изменение позиции (добавление, изменение или ликвидация) в результате совершения сделки не влечет за собой появление транзакции TRADE_TRANSACTION_POSITION." Из моего изначального вопроса явно следует, что речь идет об изменении позиции исключительно в результате совершения сделки. Я не получаю событий TRADE_TRANSACTION_POSITION в OnTradeTransaction(). Более того я не догоняю как моя позиция вообще может быть изменена не на основании сделок, разъясните пжлста? Это когда ранее совершенные и учтенные сделки позже были что ли отменены? Кроме того, в описании volume для транзакции TRADE_TRANSACTION_POSITION в документации указано "volume - объем позиции в лотах, если он был изменен." А что там будет если он не был изменен? 0? -1? Уважаемые разработчики описываете пжлста все варианты в документации (так как события TRADE_TRANSACTION_POSITION не поступают, то выяснить это экспериментальным путем не представляется возможным, поэтому полнота документации важна, чтобы понимать что вы там хотя бы логически имели ввиду).

 
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торговой транзакции
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торговой транзакции
  • www.mql5.com
Например, при отсылке рыночного ордера на покупку он обрабатывается, для счета создается соответствующий ордер на покупку, происходит исполнение ордера, его удаление из списка открытых, добавление в историю ордеров, далее добавляется соответствующая сделка в историю и создается новая позиция. Все эти действия являются торговыми транзакциями...
 
prostotrader:

Вариант В)

Поэтому, нужно всегда отслеживать и ордера, а не только сделки.

У Вас частный случай (объем = 1), а если будет больше, то без ордеров (т.к они отложенные) вовсе не обойтись.

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

Как описано в разделе справочника MQL5 про OnTradeTransaction() - цитата: “Например, при отсылке рыночного ордера на покупку, он обрабатывается, для счета создается соответствующий ордер на покупку, происходит исполнение ордера, его удаление из списка открытых, добавление в историю ордеров, далее добавляется соответствующая сделка в историю и создается новая позиция.”

Разберем все элементы этого предложения в событиях OnTadeTransaction() для trans.type имеем:

В СЛУЧАЕ СОЗДАНИЯ И ПОСЛЕДУЮЩЕГО ПОЛНОГО ИСПОЛНЕНИЯ ЛИМИТНОГО ОРДЕРА:

создается соответствующий ордер на покупку – TRADE_TRANSACTION_ORDER_ADD

происходит ПОЛНОЕ исполнение лимитного ордера – НЕТ СОБЫТИЯ

добавляется соответствующая сделка в историю (bigluck: при срабатывании лимитного ордера это событие идет первым в тестере) – TRADE_TRANSACTION_DEAL_ADD

удаление ордера из списка открытых – TRADE_TRANSACTION_ORDER_DELETE

добавление ордера в историю ордеров – TRADE_TRANSACTION_HISTORY_ADD

и создается новая позиция (bigluck: ну или обновляется размер существующей позиции) – А ГДЕ ИДЕНТИФИКАТОР ДЛЯ ЭТОГО СОБЫТИЯ????

 

В СЛУЧАЕ СОЗДАНИЯ И ПОСЛЕДУЮЩЕГО ЧАСТИЧНОГО ИСПОЛНЕНИЯ ЛИМИТНОГО ОРДЕРА:

создается соответствующий ордер на покупку – TRADE_TRANSACTION_ORDER_ADD

происходит ЧАСТИЧНОЕ исполнение лимитного ордера - TRADE_TRANSACTION_ORDER_UPDATE

добавляется соответствующая сделка в историю – TRADE_TRANSACTION_DEAL_ADD

удаление ордера из списка открытых – НЕТ СОБЫТИЯ, bigluck: ордер пока только частично исполнен и поэтому не удален

добавление ордера в историю ордеров – НЕТ СОБЫТИЯ

и создается новая позиция (bigluck: ну или обновляется размер существующей позиции) – А ГДЕ ИДЕНТИФИКАТОР ДЛЯ ЭТОГО СОБЫТИЯ????

 

Если считывать размер позиции PositionGetDouble(POSITION_VOLUME) после события TRADE_TRANSACTION_DEAL_ADD, то обычно размер позы еще не обновился. В случае частичного исполнения ордера больше и нет последующих событий по этой сделке и ордеру!  

УТОЧНЕННЫЙ ВОПРОС: в какой момент - после какого события OnTradeTransaction() мне производить считывание размера позиции с помощью функции PositionGetDouble(POSITION_VOLUME) чтобы гарантированно получить актуальное значение размера позиции (то есть уже учитывая исполнившуюся последнюю сделку – это событие TRADE_TRANSACTION_DEAL_ADD)?

Документация по MQL5: Торговые функции / PositionGetDouble
Документация по MQL5: Торговые функции / PositionGetDouble
  • www.mql5.com
Функция возвращает запрошенное свойство открытой позиции, предварительно выбранной при помощи функции PositionGetSymbol или PositionSelect. Свойство позиции должно быть типа double.  Существует 2 варианта функции. 2...
 
bigluck:


ВОПРОС: в какой момент - после какого события OnTradeTransaction() мне производить считывание размера позиции с помощью функции PositionGetDouble(POSITION_VOLUME) чтобы гарантированно получить актуальное значение размера позиции (то есть уже учитывая исполнившуюся последнюю сделку – это событие TRADE_TRANSACTION_DEAL_ADD)?

Не нужно было так подробно все описывать.

Очень трудно ответить Вам, т.к неизвестна конечная цель, но

попробую.

Отложенный ордер (у Вас лимитный)

1. Если ордер исполнился не всем объемом

можно смотреть

 а) Сообщение TRADE_TRANSACTION_DEAL_ADD

 или 

б) Сообщение TRADE_TRANSACTION_ORDER_UPDATE

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

Возможно только сравнение объемов ордера(ов) и объема позиции.

2. Ордер исполнился полностью, тогда нужно смотреть TRADE_TRANSACTION_HISTORY_ADD вместе с этим событием изменяется окружение в том числе объем позиции.

В любом случае ордер первичен, ведь он порождает позицию, значит за ним(и) нужно следить.

И не забывайте, что ордер может быть отменен, и Вы будете ждать "до посинения" свою позицию :)

Добавлено

И вообще-то глупо устанавливать отложенные ордера один над другим, Вы заведомо ухудшаете свою позицию.

 
bigluck:

Посмотрел. А что там надо было смотреть? Уточните пжлста Вашу рекомендацию.

Что увидел я: trans.volume в структуре MqlTradeTransaction имеет отношение к размеру позиции только при событии TRADE_TRANSACTION_POSITION. Однако, в документации в отношении этого идентификатора заявлено: "Изменение позиции (добавление, изменение или ликвидация) в результате совершения сделки не влечет за собой появление транзакции TRADE_TRANSACTION_POSITION." Из моего изначального вопроса явно следует, что речь идет об изменении позиции исключительно в результате совершения сделки. Я не получаю событий TRADE_TRANSACTION_POSITION в OnTradeTransaction(). Более того я не догоняю как моя позиция вообще может быть изменена не на основании сделок, разъясните пжлста? Это когда ранее совершенные и учтенные сделки позже были что ли отменены? Кроме того, в описании volume для транзакции TRADE_TRANSACTION_POSITION в документации указано "volume - объем позиции в лотах, если он был изменен." А что там будет если он не был изменен? 0? -1? Уважаемые разработчики описываете пжлста все варианты в документации (так как события TRADE_TRANSACTION_POSITION не поступают, то выяснить это экспериментальным путем не представляется возможным, поэтому полнота документации важна, чтобы понимать что вы там хотя бы логически имели ввиду).

Вы неправильно понимаете работу MqlTradeTransaction вообще. Тип транзакции TRADE_TRANSACTION_POSITION может произойти только при изменении уже существующей позиции. А вы ищете объём позиции собранной из трёх ордеров и сделок. Если случилось так, что три ордера активировались за один тик, то последовательно будет три события MqlTradeTransaction в котором будет поочерёдно, не факт что именно в той последовательности как были расставлены ордера (надо проверять), обработаны эти три ордера и три сделки каждая из которых имеет свой объём именно trans.volume из которых в результате и будет сформирована позиция.

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

 
prostotrader:

...

Очень трудно ответить Вам, т.к неизвестна конечная цель

....

И не забывайте, что ордер может быть отменен, и Вы будете ждать "до посинения" свою позицию :)

....

Цель заключена в вопросе - понять в какой момент обновляется размер позиции, что бы именно после этого получить корректное значение через PositionGetDouble(POSITION_VOLUME);

То что вы описали соответствует моему описанию. Этими извращениями приходится заниматься из-за того что нет события типа "ДАННЫЕ ПО ПОЗИЦИИ БЫЛИ ОБНОВЛЕНЫ".

Что там происходит с ордерами после выставления обычно не имеет смысла отслеживать - управлять то надо позицией, а вот когда обновляются данные по позиции узнать то и невозможно в MQL5.

 
Alexey Viktorov:

Вы неправильно понимаете работу MqlTradeTransaction вообще. Тип транзакции TRADE_TRANSACTION_POSITION может произойти только при изменении уже существующей позиции. А вы ищете объём позиции собранной из трёх ордеров и сделок. Если случилось так, что три ордера активировались за один тик, то последовательно будет три события MqlTradeTransaction в котором будет поочерёдно, не факт что именно в той последовательности как были расставлены ордера (надо проверять), обработаны эти три ордера и три сделки каждая из которых имеет свой объём именно trans.volume из которых в результате и будет сформирована позиция.

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

Да всё я понимаю.

Давайте оставим TRADE_TRANSACTION_POSITION - это событие не имеет отношения к моему вопросу - у меня про создание, изменение и закрытие позиции только с помощью сделок.

Как я понял про trans.volume  вы имели ввиду объем только для ордеров в событиях типа TRADE_TRANSACTION_ORDER_ADD, TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_ORDER_DELETE, TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE и TRADE_TRANSACTION_DEAL_DELETE. Это тот изврат, который уже описан выше в диалоге с другим коллегой.

Напомню, что мой вопрос касается выявления момента для получения актуального размера позиции. Метод получения информации о том когда якобы позиция уже могла бы быть изменена на основании косвенных данных про события случившиеся с ордерами понятен, неточен и неудобен.

Как я понял узнать когда обновляются данные по позиции в MQL5 невозможно, так как для этого нет событий типа "ДАННЫЕ ПО ПОЗИЦИИ БЫЛИ ОБНОВЛЕНЫ" / "ПОЗИЦИЯ ОТКРЫТА" / "ПОЗИЦИЯ ИЗМЕНЕНА" / "ПОЗИЦИЯ ЗАКРЫТА".

Спасибо.

 
bigluck:

Да всё я понимаю.

Давайте оставим TRADE_TRANSACTION_POSITION - это событие не имеет отношения к моему вопросу - у меня про создание, изменение и закрытие позиции только с помощью сделок.

Как я понял про trans.volume  вы имели ввиду объем только для ордеров в событиях типа TRADE_TRANSACTION_ORDER_ADD, TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_ORDER_DELETE, TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE и TRADE_TRANSACTION_DEAL_DELETE. Это тот изврат, который уже описан выше в диалоге с другим коллегой.

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

Как я понял узнать когда обновляются данные по позиции в MQL5 невозможно, так как для этого нет событий типа "ДАННЫЕ ПО ПОЗИЦИИ БЫЛИ ОБНОВЛЕНЫ" / "ПОЗИЦИЯ ОТКРЫТА" / "ПОЗИЦИЯ ИЗМЕНЕНА" / "ПОЗИЦИЯ ЗАКРЫТА".

Спасибо.

Наверное вы забываете о том, что любое изменение позиции рождено совершением сделки. Именно сделку и надо контролировать для понимания что происходит с позицией. Именно сделка может нам сказать, что объём позиции увеличен, часть позиции закрыта, или вся позиция закрыта.

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

 
Alexey Viktorov:

.... Именно сделку и надо контролировать для понимания что происходит с позицией. Именно сделка может нам сказать, что объём позиции увеличен, часть позиции закрыта, или вся позиция закрыта.

.....

А вот при обработке третьего события из имитируемых трёх, позиция будет уже точно полным объёмом.

Вы забыли добавить (добавлено жирным): В MQL5 именно сделку и надо контролировать для понимания что происходит с позицией, так как в MQL5 нет событий типа "ДАННЫЕ ПО ПОЗИЦИИ БЫЛИ ОБНОВЛЕНЫ" / "ПОЗИЦИЯ ОТКРЫТА" / "ПОЗИЦИЯ ИЗМЕНЕНА" / "ПОЗИЦИЯ ЗАКРЫТА".

"Именно сделка может нам сказать, что объём позиции увеличен, часть позиции закрыта, или вся позиция закрыта" - мне не нужно можествование при принятии решений по алгоритму. Мне нужен факт наступления событий вида: "ДАННЫЕ ПО ПОЗИЦИИ БЫЛИ ОБНОВЛЕНЫ" / "ПОЗИЦИЯ ОТКРЫТА" / "ПОЗИЦИЯ ИЗМЕНЕНА" / "ПОЗИЦИЯ ЗАКРЫТА". Этого нет.

"А вот при обработке третьего события из имитируемых трёх, позиция будет уже точно полным объёмом" - не факт. На практике обычно бывает 1 или 2 ну или 0 - как сервера успели (есть же ещё биржа), но практически всегда не 3.

Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Тикет позиции. Уникальное число, которое присваивается каждой вновь открытой позиции. Как правило, соответствует тикету ордера, в результате которого она была открыта, за исключением случаев изменения тикета в результате служебных операций на сервере. Например, начисления свопов переоткрытием позиции. Для нахождения ордера, которым была открыта...
Причина обращения: