Чтобы понять, как работают биржи, нужно разобраться с биржевыми заявками и правилами их обработки брокером.
В статье мы разберем типы ордеров, особенности их исполнения на бирже и накладываемые торговой моделью ограничения. Если вам любопытно, что значат аббревиатуры DAY, GTC, FOK, IOC, GTD, GAT, MOO, MOC, LOO, LOC, MIT, OCO, OSO, PEG, прошу под кат.
Про ордеры
Всем участникам рынка важно заключить выгодную сделку. Чтобы начать торг, необходимо создать заявку (ордер) на продажу или покупку требуемого финансового инструмента. Соответственно суммарное множество заявок формирует текущее предложение и спрос.
Биржевая заявка – инструкции от клиента брокеру на покупку или продажу финансовых инструментов на бирже.
Типичный ордер содержит следующую информацию:
- Идентификатор финансового инструмента (торгуемый актив)
- Тип заявки
- Направление сделки. Покупка или продажа
- Цена
- Количество
- Срок действия заявки (опционально)
- Дополнительные указания (опционально)
Типы ордеров
Базово ордеры можно разделить на три большие группы
- Рыночные. Подобная заявка должна быть немедленно выполнена по текущей рыночной цене, либо если необходимого объема нет, то как только появится такая возможность.
- Отложенные. Заявка позволяет контролировать максимальную цену сделки для покупки и минимальную возможную цену для продажи. Подобные ордеры могут не выполниться. Для лимитных ордеров цена всегда указывается лучше.
- С условиями. Любая заявка кроме лимитной, которая для исполнения требует выполнения дополнительных условий.
Срок действия
Наверняка вы уже видели сокращения вида DAY, GTC, FOK, IOC, GTD, GAT. Все они ограничивают время действия заявки.
- DAY. Срок действия ордеров данного типа истекает в конце торгового дня.
- GTC (Good till canceled). Заявка действительна пока ее явно не отменят. Чтобы подобные заявки не оставались на рынке бесконечно долго, вводится дополнительное ограничение для них, обычно от 30 до 90 дней.
- FOK (Fill Or Kill). Заявка должна быть исполнена полностью или немедленно отменена.
- IOC (Immediate Or Cancel). Заявка исполняется немедленно или отменяется биржей. В отличие от FOK, позволяют частичное закрытие.
- GTD (Good-til-Date/Time). Заявка действительна до указанного времени.
- GAT (Good-after-Time/Date). Заявка действительна начиная с указанного времени.
Условия выполнения ордеров
Комбинируя инструкции на цены, срок действия и дополнительные ограничения, можно получить различные условия выполнения ордеров.
Чтобы разобраться в связях, изобразим структуру типов ордеров, она представлена в самом начале статьи.
Ордеры работающие при открытии и закрытии рынка
Добавляя к рыночному ордеру ограничение срока действия мы получаем:
- MOO (Market-On-Open). Рыночный ордер такого типа может быть выполнен только в момент открытия торгового дня. Исполнение гарантировано при наличии ликвидности.
- LOO (Limit-On-Open). Как и MOO, LOO может быть выполнен только в начале торгового дня. В отличии от MOO, лимитные ордеры этого типа позволяют задать инструкции для цены. Исполнение не гарантировано.
- MOC (Market-On-Close). Аналогичен MOO, но рыночный ордер может быть закрыт только в момент закрытия торгового дня. Исполнение гарантировано при наличии ликвидности.
- LOC (Limit-On-Close). Аналогичен LOO, но лимитный ордер может быть закрыт только в момент закрытия торгового дня. Исполнение не гарантировано.
Условные ордеры
Когда мы хотим настроить наши ордеры для исполнения торговой стратегии, то на помощь приходят условные ордеры – ордеры, активация которых происходит только после наступления условия. Таким образом основная цель данных ордеров – минимизация риска больших финансовых потерь.
Стоп ордер
Стоп-ордер (stop order) – это заявка на покупку или продажу определенного количества актива по указанной цене или хуже. Как только цена инструмента станет равна или превысит указанную цену для стоп ордера на покупку, он автоматически превращается в рыночный ордер (market order) и исполняется на общих условиях. Аналогично и для стоп ордера на продажу, как только цена достигнет заданного в ордере уровня и продолжит падать, он превращается в рыночный. Таким образом выполнение активных стоп ордеров гарантированно.
Стоп ордеры позволяют минимизировать возможные потери, поэтому stop loss – синоним для stop order.
Лимитный стоп ордер (stop-limit order)
В отличии от обычных стоп-ордеров, где указывается только стоп-цена, в лимитных мы должны дополнительно указать лимитную цену.
Как только цена на актив станет равной или хуже стоп-цены, автоматически будет создана лимитная заявка с указанной лимитной ценой. Исполнение такого ордера не гарантировано.
Скользящий стоп ордер (trailing stop order)
В отличии от обычных стоп ордеров, где стоп-цена указывается в абсолютных единицах, скользящие ордеры используют проценты. После срабатывания, он превращается в обычный рыночный ордер. Таким образом, стоп цена привязана к цене на рынке и увеличивается вместе с ней. Например мы выставили заявку по цене 10 рублей и стоп цену указали 10% от текущей, т.е абсолютная стоп цена будет равна 9 рублям. Затем актив вырос до 15 рублей и, вместе с тем, стоп цена нашего ордера до 13,5 рублей.
Данный тип ордеров применяется как для минимизации убытков, так и для максимизации прибыли.
Скользящие стоп-лимитные ордеры (trailing stop-limit order)
В отличии от скользящих стоп ордеров, после срабатывания ордер превращается в лимитный а не рыночный.
PEG ордер
Является разновидностью лимитных ордеров. Ордер автоматически меняет свою цену после изменения цены спроса/предложения. В ценовых инструкциях указывается смещение в худшую сторону от текущей лучшей цены спроса/предложения.
OCO ордер (One cancels other)
Это парный ордер. Обычно состоит из стоп ордера и лимитного. Оба ордера работают с одним инструментом. В случае исполнения одного из них, второй автоматически отменяется.
Простой пример: мы купили актив по 10 рублей, наша цель, получить минимум 3 рубля прибыли, и мы хотим ограничить убытки максимум 2 рублями. Тогда стоп цена будет 8 рублей, а лимитная цена 13 рублей.
OSO ордер (One sends other)
Такой ордер состоит из основного ордера и группы связанных ордеров. Ордеры могут работать с разными инструментами. В случае исполнения основного ордера, на рынке автоматически создаются все связанные.
Мы рассмотрели теорию ордеров, теперь можно приступить к практике.
Практика
С системной точки зрения важно гибко, но точно, определить базовую для всех типов ордеров структуру. В Erlang это можно сделать с помощью записей:
-record(exchange_order, {
id :: binary(),
orig_id :: binary(),
ticker :: binary(),
owner :: binary(),
trader :: binary(),
type :: non_neg_integer(),
side :: non_neg_integer(),
time_in_force :: non_neg_integer(),
price :: binary(),
trigger_price :: binary(),
qty :: binary(),
orig_qty :: binary(),
created_ts :: non_neg_integer(),
updated_ts :: non_neg_integer(),
deals_history :: [#exchange_deal{}],
linked_orders :: [#exchange_order{}],
opts :: map()
}).
Идентификация ордера
После того, как ордер попадает на биржу, ему присваивается внутрисистемный идентификатор – поле id. Для улучшения пользовательского опыта при согласовании биржи с внешними системами необходимо дать возможность внешней по отношении к бирже системе присвоить создаваемому ордеру свой id — поле orig_id. Это даст возможность запрашивать ордеры как по id, так и по orig_id и позволит отказаться от дополнительного маппинга ордеров во внешней системе.
Принадлежность ордера
Заложим в систему возможность создания посредников. Заявки могут выставляться напрямую от участников торга, а могут от посредника, который предоставляет услуги клиентам, не имеющим прямого доступа к бирже.
В случае прямой заявки owner и trader совпадают.
Кодирование инструкций
Разберем оставшиеся поля. Для кодирования инструкций по цене служат два поля: price – лимитная цена для лимитных ордеров и tirgger_price – цена срабатывания для кастомных типов. Например, для стоп ордеров это поле будет кодировать стоп цену.
Для кодирования объема используем qty и qty_orig. Qty_orig задает начальный объем ордера, а qty – объем ордера в процессе его выполнения.
Для того чтобы иметь точную информацию о частичных выполнениях нужен массив deals_history. С его помощью, после полного заполнения ордера, можно рассчитать например среднюю цену выполненной заявки.
Поле linked_orders необходимо для кодирования информации о связанных ордерах для OCO и OSO.
Чтобы иметь возможность расширять систему без изменения записи exchange_order, внесем поле opts – динамический словарь.
Промежуточный итог
Честно говоря, я думал, что вторая часть цикла будет компактной. Однако, для целостного понимания, пришлось раскрыть тему более детально.
Теоретическая часть следующей статьи осветит вопрос книги ордеров и правил процессинга заявок. Техническая сторона раскроет схему обработки рыночных данных и вопросы хранения исторических данных.