Блог им. fxsaber

Частичное исполнение.

    • 06 августа 2022, 15:05
    • |
    • fxsaber
  • Еще

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

 

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

 

Поиск.

Этот скрипт находит события, когда один и тот же отложенный ордер создает несколько позиций, жизни которых не пересекаются. Т.е. сначала открылась и закрылась одна позиция, затем — вторая и т.д. И все они происходят из одного и того же отложенного ордера за счет его частичных исполнений на Hedge-счете.

 

#define MT4ORDERS_BYPASS_MAXTIME 1000000 // Максимальное время (в мкс.) на ожидание синхронизации торгового окружения
#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

// Распечатывает MT4-записи с одним и тем же PositionID-идентификатором.
void PrintPositionID( const ulong PositionID )
{
  const int Size = OrdersHistoryTotal();
  
  for (int i = 0; i < Size; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderTicketID() == PositionID))
      OrderPrint();
      
  return;
}

// Строковое представление сделки.
string DealToString( const ulong &Ticket )
{
  const ENUM_DEAL_ENTRY EntryDeal = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(Ticket, DEAL_ENTRY);
  const int Digits = (int)SymbolInfoInteger(HistoryDealGetString(Ticket, DEAL_SYMBOL), SYMBOL_DIGITS);
  
  return((string)(datetime)HistoryDealGetInteger(Ticket, DEAL_TIME)) + " " +
         (string)Ticket + " " + ((EntryDeal == DEAL_ENTRY_IN) ? "+" : "-") + 
         DoubleToString(HistoryDealGetDouble(Ticket, DEAL_VOLUME), 2) + " " +
         DoubleToString(HistoryDealGetDouble(Ticket, DEAL_PRICE), Digits) + " " +
         EnumToString(EntryDeal) + " " + (string)HistoryDealGetInteger(Ticket, DEAL_POSITION_ID);
}

// Строковое представление массива сделок (с одним PositionID-идентификатором).
string DealsToString( const ulong &Deals[] )
{
  string Str = NULL;
  const int Size = ArraySize(Deals);

  double Lots = 0;
  int Amount = 0;
  
  for (int i = 0; i < Size; i++)
  {
    Lots += HistoryDealGetDouble(Deals[i], DEAL_VOLUME) *
            ((HistoryDealGetInteger(Deals[i], DEAL_ENTRY) == DEAL_ENTRY_IN) ? 1: -1);
        
    Str += DealToString(Deals[i]) + "_Lots = " + DoubleToString(Lots, 2) +
           ((MathAbs(Lots) < 1e-5) ? ": " + (string)(++Amount) : NULL) + "\n";
  }
    
  return(Str);
}

void OnStart()
{
  TRADESID TradesID;
  ulong PositionID[];

  for (int i = TradesID.GetPositionsID(PositionID) - 1; i >= 0; i--) // Бежим по всем PositionID-идентификаторам.
    if (PositionID[i]) // Торговый идентификатор (не балансовые операции).
    {
      ulong Deals[];
      double Lots = 0; // Суммарный лот порождаемых позиций.
      
      const int Size = TradesID.GetDealsByID(PositionID[i], Deals) - 1; // Получили все сделки с одинаковым PositionID-идентификаторам
      
      for (int j = 0; j < Size; j++) // Бежим по сделкам.
      {
        Lots += HistoryDealGetDouble(Deals[j], DEAL_VOLUME) *
                ((HistoryDealGetInteger(Deals[j], DEAL_ENTRY) == DEAL_ENTRY_IN) ? 1: -1);
                
        if (MathAbs(Lots) < 1e-5) // Если было порождено несколько позиций - распечатываем.
        {
          PrintPositionID(PositionID[i]); // В MT4-представлении.
          Print(DealsToString(Deals)); // Все сделки.
          
          break;
        }
      }  
    }
}

 

Пример 1.

Рассмотрим некоторые результаты выполнения скрипта.

// MT4-представление.
#2006402 2021.08.19 00:26:28.705 sell 0.03 USDJPY 109.790 0.000 109.781 2021.08.19 00:26:38.748 109.774 -0.056 -2.84 0.37 3;[0] 3
#2006466 2021.08.19 00:26:52.992 sell 0.17 USDJPY 109.790 0.000 109.782 2021.08.19 00:27:14.111 109.782 -0.32 0.00 1.06 3;[0];[0] 3
#2006474 2021.08.19 00:27:19.078 sell 0.03 USDJPY 109.790 0.000 109.782 2021.08.19 00:27:21.939 109.782 -0.06 0.00 0.19 3;[0];[0];[0];[0];[0];[0];[0] 3
#2006493 2021.08.19 00:27:24.011 sell 0.18 USDJPY 109.790 0.000 109.782 2021.08.19 00:27:45.709 109.782 -0.33 0.00 1.12 3;[0];[0];[0];[0];[0];[0];[0] 3
#2007698 2021.08.19 00:59:16.717 sell 0.26 USDJPY 109.798 0.000 109.790 2021.08.19 02:07:17.431 109.790 -0.44 0.00 1.62 3;[0];[0];[0];[0];[0];[0];[0] 3

// Все сделки.
2021.08.19 00:26:28 2006394 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.03
2021.08.19 00:26:38 2006402 -0.03 109.774 DEAL_ENTRY_OUT_BY 3426935_Lots = 0.00: 1 // Закрылась первая позиция (через CloseBy).
2021.08.19 00:26:52 2006418 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.03
2021.08.19 00:26:56 2006426 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.06
2021.08.19 00:27:00 2006431 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.09
2021.08.19 00:27:04 2006436 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.12
2021.08.19 00:27:09 2006439 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.15
2021.08.19 00:27:13 2006465 +0.02 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.17
2021.08.19 00:27:14 2006466 -0.17 109.782 DEAL_ENTRY_OUT 3426935_Lots = -0.00: 2 // Закрылась вторая позиция.
2021.08.19 00:27:19 2006471 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.03
2021.08.19 00:27:21 2006474 -0.03 109.782 DEAL_ENTRY_OUT 3426935_Lots = -0.00: 3 // Закрылась третья позиция.
2021.08.19 00:27:24 2006476 +0.02 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.02
2021.08.19 00:27:27 2006479 +0.02 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.04
2021.08.19 00:27:30 2006482 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.07
2021.08.19 00:27:33 2006484 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.10
2021.08.19 00:27:36 2006486 +0.02 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.12
2021.08.19 00:27:39 2006489 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.15
2021.08.19 00:27:42 2006491 +0.03 109.790 DEAL_ENTRY_IN 3426935_Lots = 0.18
2021.08.19 00:27:45 2006493 -0.18 109.782 DEAL_ENTRY_OUT 3426935_Lots = -0.00: 4 // Закрылась четвертая позиция.
2021.08.19 00:59:16 2006970 +0.26 109.798 DEAL_ENTRY_IN 3426935_Lots = 0.26
2021.08.19 02:07:17 2007698 -0.26 109.790 DEAL_ENTRY_OUT 3426935_Lots = 0.00:  5 // Закрылась пятая позиция.

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

 

Визуализация.

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

Частичное исполнение.

На скрине два представления рассматриваемой ситуации.

 

Верхний — штатная визуализация в виде одной строки, соответствующей всем исполнениям одного отложенного ордера (единый PositionID-идентификатор). Удобно, что одной строкой и встроено в GUI терминала. Но крайне скудно, не разобраться, что происходило.

 

Нижний (таблица) — это визуализация MT4-представления той же истории исполнения, но за счет нескольких иных сущностей: MT4-позиций, которые создает библиотека MT4Orders.

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

 

Таково различие MT5 и MT4-представлений торговой истории. Первый — лаконичный, второй — подробный.

 

Пример 2.

// MT4-представление.
#2429648 2021.11.16 23:58:39.093 sell 0.30 AUDCHF 0.67939 0.00000 0.67913 2021.11.16 23:58:42.309 0.67963 -0.964 0.00 -6.84 103;[0] 103
#2429915 2021.11.16 23:59:44.453 sell 0.50 AUDCHF 0.67939 0.00000 0.67910 2021.11.17 00:10:02.531 0.67901 -1.61 -3.48 18.05 103;[0];[0];[0] 103
#2429920 2021.11.16 23:59:44.453 sell 0.10 AUDCHF 0.67939 0.00000 0.67910 2021.11.17 00:10:03.693 0.67904 -0.32 -0.69 3.32 103;[0];[0];[0] 103
#2430627 2021.11.17 00:30:39.016 sell 0.29 AUDCHF 0.67928 0.00000 0.67906 2021.11.17 01:01:37.912 0.67906 -0.94 0.00 6.06 103;[0];[0];[0];[0];[0];[0];[0] 103

// Все сделки.
2021.11.16 23:58:39 2429630 +0.15 0.67939 DEAL_ENTRY_IN 5697587_Lots = 0.15
2021.11.16 23:58:42 2429647 +0.15 0.67939 DEAL_ENTRY_IN 5697587_Lots = 0.30
2021.11.16 23:58:42 2429648 -0.30 0.67963 DEAL_ENTRY_OUT_BY 5697587_Lots = 0.00: 1 // Закрылась первая позиция (через CloseBy).
2021.11.16 23:59:44 2429680 +0.15 0.67939 DEAL_ENTRY_IN 5697587_Lots = 0.15
2021.11.16 23:59:47 2429695 +0.15 0.67939 DEAL_ENTRY_IN 5697587_Lots = 0.30
2021.11.16 23:59:51 2429705 +0.15 0.67939 DEAL_ENTRY_IN 5697587_Lots = 0.45
2021.11.16 23:59:55 2429706 +0.15 0.67939 DEAL_ENTRY_IN 5697587_Lots = 0.60
2021.11.17 00:10:02 2429915 -0.50 0.67901 DEAL_ENTRY_OUT 5697587_Lots = 0.10     // Частичное закрытие второй позиции.
2021.11.17 00:10:03 2429920 -0.10 0.67904 DEAL_ENTRY_OUT 5697587_Lots = -0.00: 2 // Закрылась вторая позиция.
2021.11.17 00:30:39 2430264 +0.29 0.67928 DEAL_ENTRY_IN 5697587_Lots = 0.29
2021.11.17 01:01:37 2430627 -0.29 0.67906 DEAL_ENTRY_OUT 5697587_Lots = -0.00: 3 // Закрылась третья позиция.

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

 

Частичное исполнение.

Мы снова видим, что MT5-предсталение максимально лаконично. Однако, MT4-представление имеет не три, а четыре позиции. Именно такой способ выбран для визуализации частичных закрытий позиций. В таблице четко показано, что было частичное исполнение TakeProfit-позиции (зеленая рамка), реджект оставшейся части и другие подробности.

 

MT4/MT5-представления торговой истории.

На примере PartialFills продемонстрировано, что разные сущности MT4/MT5-позиций позволяют соответствующим образом видеть/оценивать хронологию торговых событий.

 

Сама концепция такого представления позиций является платформо-независимой и может быть реализована для многих торговых API и рынков.

 

Частичное исполнение.

Даже на приведенных примерах нельзя не заметить, что частичное исполнение может проходить очень мелкими лотами на FOREX-рынке. Происходит и на открытии и на закрытии позиций. Безусловно, важно правильно обрабатывать все эти события. И, наверное, MT4-представления истории (и текущего торгового состояния) дают более подготовленную основу для этого.

 

Вышеприведенный скрипт показал и другие сценарии PartialFills . Например, оставшаяся часть отложенного ордера была удалена и в MT4-представлении можно было видеть, как жизнь залитой части, так и неисполненного остатка.

 

Загромождать этим не стал пост. Благо каждый при желании может воспользоваться предложенным инструментарием на своем торговом счете и оценить исполнение именно своих ордеров.

916 | ★1

Читайте на SMART-LAB:
Фото
Почему курс доллара упал, а евро и юань выросли
  Главное • Рубль закрылся разнонаправленно: ±0,5% относительно доллара, евро и юаня. Причина расхождения — динамика глобальных валютных пар....
Фото
📊 Опубликовали рекордные результаты по МСФО за 2025 год
Вчера Группа МГКЛ раскрыла финансовую отчётность по МСФО за 12 месяцев 2025 года. Если вы пропустили — мы провели эфир, в котором...
Фото
BRENT: Дипломатия Трампа против "бычьего десанта" — кто блефует?
После сенсационного заявления Трампа о достижении двухнедельного перемирия с Ираном нефть открыла торги в среду с мощным гэпом вниз. Цена...
Фото
Кто сейчас самый дешевый сбыт? Сводный пост по сбытовым компаниям по отчетам РСБУ за 2025г.
Волгоградэнергосбыт Ставропольэнергосбыт Самараэнерго Мордовэнергосбыт Пермэнергосбыт Новосибирскэнергосбыт...

теги блога fxsaber

....все тэги



UPDONW
Новый дизайн