ORDER_POSITION_ID - страница 21

 
Mikalas:

...

Но я хотел это реализовать через ордера (у меня бывает, что частично исполненый ордер "стоит" пару-тройку дней),

 ...

Михаил, и правильно хотели! Почему же не реализовали? Поймите, при разборе нетто-позиций Вы все равно рано или поздно столкнетесь с тем, что без анализа входящих в нее ордеров не обойтись. Это я говорю Вам как человек ни один месяц посвятивший изучению этого вопроса, и наступавший на эти грабли много раз:) К тому же, если у Вас торгует ни один робот, а сразу несколько, Вам придется еще учитывать вклад каждого робота в совокупную позицию и без ордеров здесь тоже не обойтись. Вся необходимая информация присутствует в ордерах и сделках на их основе, а матчинг сделок в единую нетто-позицию наоборот необратимо удаляет информацию.

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

1. Поступила новая сделка (счетчик HistoryDealsTotal() изменился).

2. Если эта сделка инициирована каким-либо ордером, создаем новый ордер, включающий одну единственную сделку (COrder* order = new Order(deal)).

3. Далее ищем в своем списке  уже существующих виртуальных ордеров, ордер с этим же идентификатором. Если такой ордер находится, то объединяем сделку созданного ордера с сделками найденого и обновляем его свойства, а созданный ордер удаляем. Если такого же ордера еще нет в списке, просто добавляем его в список.

Таким образом система получается полностью детерменистической. С каждой новой сделкой изменится состояние нашего виртуального ордера, и неважно завис ли фактический ордер на исполнении или уже перемещен в историю, мы всегда будет видеть его в своей системе в фактически исполненном объеме.

 
Contender:
А если закрыть позицию, а неисполненную часть ордера не снимать и она откроет (или изменит) уже другую позицию?

Хороший вопрос!

Если ордер дейтвующий, то его в истории нет (это точно проверено),

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

он опять исполнится частично, то ему не присвоится ORDER_POSITION_ID.

То есть  ORDER_POSITION_ID можно увидеть только в истории.

 
C-4:

Да, такое бывает на бирже и эти ситуации надо учитывать. Это один из фундаментальных недостатков лимитных заявок. 

 В Вашем примере я думаю можно заменить:

На:

 Т.к. все сделки типа buy и sell инициированы каким-то ордером.

Нет, нельзя, потому что в клиринг происходят сделки, но они не имеют тикета ( вернее тикет = 0 ),

но имеют цену и тип (BUY и SELL) и естественно IN и OUT :( 

 
C-4:

Михаил, и правильно хотели! Почему же не реализовали? Поймите, при разборе нетто-позиций Вы все равно рано или поздно столкнетесь с тем, что без анализа входящих в нее ордеров не обойтись. Это я говорю Вам как человек ни один месяц посвятивший изучению этого вопроса, и наступавший на эти грабли много раз:) К тому же, если у Вас торгует ни один робот, а сразу несколько, Вам придется еще учитывать вклад каждого робота в совокупную позицию и без ордеров здесь тоже не обойтись. Вся необходимая информация присутствует в ордерах и сделках на их основе, а матчинг сделок в единую нетто-позицию наоборот необратимо удаляет информацию.

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

1. Поступила новая сделка (счетчик HistoryDealsTotal() изменился).

2. Если эта сделка инициирована каким-либо ордером, создаем новый ордер, включающий одну единственную сделку (COrder* order = new Order(deal)).

3. Далее ищем в своем списке  уже существующих виртуальных ордеров, ордер с этим же идентификатором. Если такой ордер находится, то объединяем сделку созданного ордера с сделками найденого и обновляем его свойства, а созданный ордер удаляем. Если такого же ордера еще нет в списке, просто добавляем его в список.

Таким образом система получается полностью детерменистической. С каждой новой сделкой изменится состояние нашего виртуального ордера, и неважно завис ли фактический ордер на исполнении или уже перемещен в историю, мы всегда будет видеть его в своей системе в фактически исполненном объеме.

Василий, я всё реализовал ( не так, как вы, но тоже не плохо ), просто я хотел уменьшить время поиска...
 
Serj_Che:

Проблему решили, отношения все выяснили )

Возник сопутствующий вопрос:

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

Получается надо искать ордер и тут и там. 

Не проще бы сделать как в четверке МТ4, если выбирается ордер то неважно где он находится.

из справки МТ4:

Кто что на это думает? 

P.S. Надеюсь Михаил не против продолжения ветки, чтобы не плодить новые? 


Mikalas:

С-4, очень приятно, что обсуждение пошло в конструктивном русле!

Так вот, "чистая" цена позиции мне нужна, чтобы знать (через месяц, например ), какой у меня профит.

...

В функции(использую сейчас):

...

Вопрос актуальный, в целом API MetaTrader5 действительно довольно низкоуровневый. Но... торговля на бирже имеет массу ньюансов: исполнение заявки множеством сделок, матчинг трейдов в нетто-позицию и перенос ее через клиринг, обилие брокерских операций и прочее прочее. Поэтому API MetaTrader5 (и сам МТ5) такой, какой и должен быть любой биржевом терминал.

Другой вопрос что его API можно обернуть в высокоуровневую обертку, написанную на MQL5 и уже через нее юзать более низкоуровневые функции МТ5. В моей обертке задача Михаила по подсчету профита и не только выглядела бы так:

for(int i = 0; i < TransactionsTotal(); i++)
{
    if(TransactionSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
         ENUM_TRANS_TYPE trans_type = TransactionType();
         if(trans_type == TRANS_HEDGE_POSITION)
         {
              if(HedgePositionGetInteger(HEDGE_POSITION_MAGIC) != myMagic)continue;  // Работаем только со своими позициями.
              if(HedgePositionGetString(HEDGE_POSITION_SYMBOL) != Symbol())continue; // Работаем только с позициями на своем инструменте.
              double profit = HedgePositionGetDouble(HEDGE_POSITION_PROFIT_POINTS); //Профит в пунктах
              double currency = HedgePositionGetDouble(HEDGE_POSITION_PROFIT_CURRENCY); //Профит в валюте депозита.
              double price_open = HedgePositionGetDouble(HEDGE_POSITION_PRICE_OPEN); //Фактическая цена открытия позиции без клирингов и пр. изменений.
              double sl = HedgePositionGetDouble(HEDGE_POSITION_SL); //Узнаем уровень стоп-лосса позиции, если он есть, если нет - вернет нормализованный 0.0.
              if(HedgeOrderSelect(ORDER_SELECTED_INIT)) //Выбираем ордер, открывающий текущую позицию.
              {
                 int deals = HedgeOrderGetInteger(HEDGE_ORDER_DEALS_TOTAL); //Получаем количество сделок, открывающего ордера.
              }
              // Ну и так далее...
         }   
    }
}
 
Mikalas:

Нет, нельзя, потому что в клиринг происходят сделки, но они не имеют тикета ( вернее тикет = 0 ),

но имеют цену и тип (BUY и SELL) и естественно IN и OUT :( 

Блин, точно:

 

Тогда печалька для Вас. 

 
Mikalas:
Василий, я всё реализовал ( не так, как вы, но тоже не плохо ), просто я хотел уменьшить время поиска...
Кстати, как справляетесь с разнонаправленностью входов Ваших роботов? Ведь вход в рынок одного эксперта может быть выходом из позиции другого робота.
 
Mikalas:

Хороший вопрос!

Если ордер дейтвующий, то его в истории нет (это точно проверено),

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

он опять исполнится частично, то ему не присвоится ORDER_POSITION_ID.

То есть  ORDER_POSITION_ID можно увидеть только в истории.

Здесь засада в другом. Часть исполненных сделок этого ордера будет принадлежать одной позиции, а другая часть уже другой, новой позиции. Тогда вопрос, какой индентификатор позиции ему присвоится, когда он рано или поздно попадет в историю?
 
C-4:
Кстати, как справляетесь с разнонаправленностью входов Ваших роботов? Ведь вход в рынок одного эксперта может быть выходом из позиции другого робота.
У меня нет пересечений.
 
C-4:
Здесь засада в другом. Часть исполненных сделок этого ордера будет принадлежать одной позиции, а другая часть уже другой, новой позиции. Тогда вопрос, какой индентификатор позиции ему присвоится, когда он рано или поздно попадет в историю?

Полностью залитый ордер, получит ID позиции, которую он открыл или изменил.

Но это будет доступно ( ID ) только в истории. 

Причина обращения: