Что такое trade markout и как оценить качество исполнения
Разбираем понятие trade markout и знаковую конвенцию. Узнайте, как измерить изменение средней цены на временных горизонтах от одной секунды до пяти минут для оценки сделок.
Trade markout — это изменение средней цены (mid price) за фиксированный временной горизонт после исполнения заявки, измеряемое с момента фиксации сделки (print). Положительное значение означает, что рынок пошел в вашу сторону после совершения сделки. Отрицательное значение означает, что рынок пошел против вас; в профессиональной среде это называют неблагоприятным отбором (adverse selection). Выбранный вами горизонт — одна секунда или пять минут — определяет, на какой именно вопрос отвечает полученное число.
Что такое trade markout?
Начнем со средней цены (mid price): это точка посередине между лучшей ценой покупки (best bid) и лучшей ценой продажи (best offer), середина NBBO. Markout берет это значение на выбранном горизонте после исполнения вашей заявки, вычитает из него базовую цену и присваивает результат с учетом направления вашей сделки.
**markout на горизонте h = направление * (mid в момент t+h - базовая цена)**, где направление равно плюс один, если вы купили, и минус один, если вы продали.
Путаница обычно возникает из-за знака. Если после покупки средняя цена падает, markout будет отрицательным: вы купили, цена снизилась, и тот, кто вам продал, оказался в выигрыше. Это и есть неблагоприятный отбор, выраженный числом. Если после продажи средняя цена падает, markout будет положительным, так как знак меняется вместе с направлением сделки. У каждой сделки две стороны, и markout одной стороны — это markout другой стороны с обратным знаком.
Три базовые цены
От того, какую базовую цену вы вычитаете, зависит, что именно измеряет markout.
- Цена исполнения. Markout превращается в денежный показатель: сколько стоит позиция в момент t+h по сравнению с тем, что вы заплатили. Спред, который вы уплатили или заработали, уже включен в этот показатель.
- Средняя цена (mid) в момент исполнения. Это позволяет исключить влияние спреда и изолировать движение рынка после сделки, что дает наиболее точное представление о неблагоприятном отборе.
- Котировка на стороне вашей сделки. Измерение относительно уровня, по которому вы совершили сделку (или выставили лимитную заявку), показывает, насколько исполнение соотносится с ценой, которая была реально доступна.
Анализ качества исполнения (execution quality) опирается на второй вариант для оценки неблагоприятного отбора и на первый — для оценки прибыли и убытков. Оба показателя представлены на первом графике ниже для одного набора сделок.
Кривая markout и значение ее формы
Если рассчитать этот показатель для множества горизонтов, получится кривая. Ее форма дает больше информации, чем любое отдельное число.
- Кривая, которая резко падает в течение первой секунды и остается на низком уровне, описывает поток заявок, который «собирают» (picked off): цена движется против сделки почти мгновенно.
- Кривая, которая продолжает падать в течение нескольких минут, описывает поток, содержащий реальную информацию о дальнейшем направлении цены.
- Плоская кривая около нуля описывает нейтральный поток. Через пять минут средняя цена выглядит так же, как в момент исполнения.
- Кривая, которая начинается с отрицательных значений и возвращается к нулю, — это форма, которую ищет пассивный маркет-мейкер, собирающий рибейты. Ранний спад — это спред плюс немедленное влияние на рынок, а восстановление — это возврат рынка к прежним уровням.
Выбор горизонта — это само по себе решение о том, что именно вы измеряете. На интервале менее секунды markout в основном отражает задержку (latency) и позицию в очереди. На интервале в минуту он отражает краткосрочную информацию в потоке заявок. После пяти минут обычный рыночный дрейф начинает перекрывать эффект самой сделки.
Реальная кривая markout, сделка за сделкой
На графике ниже представлены все сделки по INTC за основную торговую сессию 10 июня 2026 года. Каждая сделка классифицируется как инициированная покупкой или продажей относительно последней котировки за секунду до ее исполнения, а затем рассчитывается средний markout на 5 горизонтах. Две серии построены по одним и тем же сделкам: одна измеряется от средней цены в момент исполнения, другая — от цены исполнения.
Точный SQL-код для каждого числа
WITH
mid_by_second AS
(
SELECT
dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
argMax((toFloat64(bid_price) + toFloat64(ask_price)) / 2, sip_timestamp) AS mid
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'INTC'
AND sip_timestamp >= toDateTime('2026-06-10 13:30:00', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 20:00:00', 'UTC')
AND bid_price > 0
AND ask_price > bid_price
GROUP BY sec
),
signed_fills AS
(
SELECT
t.sec AS sec,
t.fill_price AS fill_price,
q.mid AS ref_mid,
if(t.fill_price > q.mid, 1, -1) AS side
FROM
(
SELECT
dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
sec - 1 AS ref_sec,
toFloat64(price) AS fill_price
FROM global_markets.stocks_trades
WHERE ticker = 'INTC'
AND sip_timestamp >= toDateTime('2026-06-10 13:30:01', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 19:55:00', 'UTC')
AND price > 0
AND size > 0
) AS t
INNER JOIN mid_by_second AS q ON q.sec = t.ref_sec
WHERE t.fill_price != q.mid
)
SELECT
multiIf(f.horizon_s < 60,
concat(toString(f.horizon_s), ' sec'),
concat(toString(intDiv(f.horizon_s, 60)), ' min')) AS horizon,
round(avg(f.side * (fut.mid - f.ref_mid) / f.ref_mid) * 10000, 3) AS mid_basis_bps,
round(avg(f.side * (fut.mid - f.fill_price) / f.fill_price) * 10000, 3) AS fill_basis_bps,
count() AS fill_count
FROM
(
SELECT
sec,
fill_price,
ref_mid,
side,
horizon_s,
sec + horizon_s AS future_sec
FROM signed_fills
ARRAY JOIN [1, 5, 15, 60, 300] AS horizon_s
) AS f
INNER JOIN mid_by_second AS fut ON fut.sec = f.future_sec
GROUP BY f.horizon_s
ORDER BY f.horizon_sДля 900593 классифицированных сделок серия на базе mid составляет 3.068 базисных пунктов на горизонте 1 sec и 2.977 базисных пунктов на горизонте 5 min. Базисный пункт — это одна сотая процента от цены, поэтому одна сделка дает погрешность округления, а миллион акций — реальные деньги.
Серия на базе цены исполнения начинается с -0.488 базисных пунктов. Расстояние между двумя сериями на кратчайшем горизонте — это эффективный полуспред: насколько цена сделки отклонилась от средней. Тейкер платит это при входе, а мейкер зарабатывает. Все, что происходит после первого горизонта, — это движение рынка.
Размер сделки и форма кривой
Неблагоприятный отбор распределяется по сделкам неравномерно. Если разделить одну и ту же сессию по размеру сделок, можно увидеть на одних осях мелкие заявки и крупные блоки от тысячи акций и более.
Точный SQL-код для каждого числа
WITH
mid_by_second AS
(
SELECT
dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
argMax((toFloat64(bid_price) + toFloat64(ask_price)) / 2, sip_timestamp) AS mid
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'INTC'
AND sip_timestamp >= toDateTime('2026-06-10 13:30:00', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 20:00:00', 'UTC')
AND bid_price > 0
AND ask_price > bid_price
GROUP BY sec
),
signed_fills AS
(
SELECT
t.sec AS sec,
t.fill_size AS fill_size,
q.mid AS ref_mid,
if(t.fill_price > q.mid, 1, -1) AS side
FROM
(
SELECT
dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
sec - 1 AS ref_sec,
toFloat64(price) AS fill_price,
size AS fill_size
FROM global_markets.stocks_trades
WHERE ticker = 'INTC'
AND sip_timestamp >= toDateTime('2026-06-10 13:30:01', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 19:55:00', 'UTC')
AND price > 0
AND size > 0
) AS t
INNER JOIN mid_by_second AS q ON q.sec = t.ref_sec
WHERE t.fill_price != q.mid
)
SELECT
multiIf(f.horizon_s < 60,
concat(toString(f.horizon_s), ' sec'),
concat(toString(intDiv(f.horizon_s, 60)), ' min')) AS horizon,
round(avgIf(f.side * (fut.mid - f.ref_mid) / f.ref_mid, f.fill_size < 1000) * 10000, 3) AS small_fill_bps,
round(avgIf(f.side * (fut.mid - f.ref_mid) / f.ref_mid, f.fill_size >= 1000) * 10000, 3) AS block_fill_bps,
countIf(f.fill_size >= 1000) AS block_fill_count
FROM
(
SELECT
sec,
fill_size,
ref_mid,
side,
horizon_s,
sec + horizon_s AS future_sec
FROM signed_fills
ARRAY JOIN [1, 5, 15, 60, 300] AS horizon_s
) AS f
INNER JOIN mid_by_second AS fut ON fut.sec = f.future_sec
GROUP BY f.horizon_s
HAVING countIf(f.fill_size < 1000) > 0
AND countIf(f.fill_size >= 1000) > 0
ORDER BY f.horizon_sНа горизонте 5 min сделки объемом менее тысячи акций в среднем дают 2.983 базисных пунктов, тогда как 11588 сделок объемом от тысячи акций и более — 2.495. Две котировки, исполнившие одинаковый совокупный объем по этим двум группам, к концу дня окажутся в разных финансовых результатах.
Как markout становится показателем спреда в отчетах об исполнении
Markout — это недостающий элемент в стандартной декомпозиции спреда. Эффективный спред — это то, что реально заплатил тейкер: удвоенное расстояние от средней цены до цены сделки. Разделим его на две части. Первая — это реализованный спред, который остается у мейкера после того, как рынок совершил движение. Вторая — это неблагоприятный отбор, который равен markout на базе mid, умноженному на два. Тождество абсолютно: эффективный спред = реализованный спред + неблагоприятный отбор.
Точный SQL-код для каждого числа
WITH
mid_by_second AS
(
SELECT
dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
argMax((toFloat64(bid_price) + toFloat64(ask_price)) / 2, sip_timestamp) AS mid
FROM global_markets.cache_stocks_quotes
WHERE ticker = 'INTC'
AND sip_timestamp >= toDateTime('2026-06-10 13:30:00', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 20:00:00', 'UTC')
AND bid_price > 0
AND ask_price > bid_price
GROUP BY sec
),
signed_fills AS
(
SELECT
t.sec + 60 AS future_sec,
t.et_time AS et_time,
t.fill_price AS fill_price,
q.mid AS ref_mid,
if(t.fill_price > q.mid, 1, -1) AS side
FROM
(
SELECT
dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
sec - 1 AS ref_sec,
toFloat64(price) AS fill_price,
formatDateTime(toStartOfInterval(toTimeZone(sip_timestamp, 'America/New_York'), toIntervalMinute(30)), '%H:%i') AS et_time
FROM global_markets.stocks_trades
WHERE ticker = 'INTC'
AND sip_timestamp >= toDateTime('2026-06-10 13:30:01', 'UTC')
AND sip_timestamp < toDateTime('2026-06-10 19:55:00', 'UTC')
AND price > 0
AND size > 0
) AS t
INNER JOIN mid_by_second AS q ON q.sec = t.ref_sec
WHERE t.fill_price != q.mid
)
SELECT
f.et_time AS et_time,
round(avg(2 * f.side * (f.fill_price - f.ref_mid) / f.ref_mid) * 10000, 3) AS effective_spread_bps,
round(avg(2 * f.side * (f.fill_price - fut.mid) / f.ref_mid) * 10000, 3) AS realized_spread_bps,
round(avg(2 * f.side * (fut.mid - f.ref_mid) / f.ref_mid) * 10000, 3) AS adverse_selection_bps,
count() AS fill_count
FROM signed_fills AS f
INNER JOIN mid_by_second AS fut ON fut.sec = f.future_sec
GROUP BY f.et_time
ORDER BY f.et_timeЗа полчаса, начиная с 09:30 по восточному времени, эффективный спред в среднем составляет 10.651 базисных пунктов, из которых 8.313 — это неблагоприятный отбор на 60-секундном горизонте, а 2.338 — доход мейкера. График охватывает 13 получасовых интервалов.
Эти компоненты являются величинами, суммируемыми по каждой площадке в отчетах об исполнении по правилам 605 и 606, и именно они лежат в основе заявлений об улучшении цены (price improvement), которые опираются на правило sub-penny и улучшение цены. Рибейт — это фиксированный кредит на акцию. Неблагоприятный отбор — это переменные издержки на акцию по сделкам, которые реально получает котировка. Сопоставление одного с другим на основе измеренной кривой, а не рекламных тарифов, является методом проверки комиссий и рибейтов maker-taker и стоит в одном ряду с механизмами, объясняющими, почему маркет-мейкеры теряют деньги.
Как рассчитывались эти показатели
Каждый график использует котировки и сделки по INTC за основную торговую сессию 10 июня 2026 года, с 09:30 до 16:00 по восточному времени. Котировки сводятся к одной средней цене в секунду (последняя зафиксированная внутри этой секунды). Сделка классифицируется как инициированная покупкой, если она прошла выше средней цены предыдущей секунды, и как инициированная продажей, если ниже — это стандартное правило для котировок. Сделки, прошедшие точно по средней цене, исключаются из выборки, чтобы не использовать допущения. Использование средней цены предыдущей секунды в качестве базовой предотвращает «заглядывание в будущее». Горизонты — это целые секунды, отсчитываемые от секунды сделки; сделка попадает в горизонт только при наличии котировки в целевой секунде.
Часто задаваемые вопросы
Что такое markout в трейдинге?
Markout — это знаковое изменение средней цены за фиксированный горизонт после исполнения сделки. Положительное значение означает, что рынок двигался в направлении вашей сделки после ее исполнения. Отрицательное означает, что он двигался в обратную сторону, что и является определением неблагоприятного отбора.
Является ли отрицательный markout всегда плохим исполнением?
Нет. Отрицательный markout на горизонте в одну секунду для рыночной заявки — это в основном спред, который эта заявка уплатила, то есть цена немедленного исполнения. Важнее то, продолжает ли кривая падать на более длинных горизонтах или выравнивается.
В чем разница между markout и проскальзыванием (slippage)?
Проскальзывание сравнивает исполнение с ценой принятия решения или ценой прихода, оценивая весь путь заявки. Markout сравнивает исполнение со средней ценой на горизонте после сделки, оценивая то, что произошло дальше. Одно оценивает родительскую заявку, другое — конкретную сделку.
Какой горизонт следует использовать для markout?
Это зависит от целей сделки. Горизонты менее секунды оценивают исполнение, чувствительное к задержкам, в то время как одна минута — стандарт для оценки неблагоприятного отбора по ликвидным инструментам. Публикация горизонта рядом с числом — это то, что делает два показателя markout сопоставимыми.
Как markout связан с эффективным спредом?
Эффективный спред делится на реализованный спред и компонент неблагоприятного отбора, причем этот компонент равен markout на базе mid, умноженному на два. При изменении горизонта распределение между ними меняется, поэтому опубликованная статистика спреда неполна без указания горизонта.
Каждый график здесь поставляется с SQL-кодом, который его создал. Откройте его, замените тикер или дату, и та же кривая markout будет построена с нуля в терминале Strasmore.