📝

Draft article

This draft is visible to admins and superusers only. Sign in with an authorized account.

← К списку статей
July 24, 2026
5 мин. чтения

Внутри слайса: тактика дочерних ордеров между планировщиком и биржей

Внутри слайса: тактика дочерних ордеров между планировщиком и биржей
#исполнение
#дочерние ордера
#тактика исполнения ордеров
#позиция в очереди
#maker-taker
#айсберг-ордера
#микроструктура
#python

Траектория Almgren-Chriss выдает вам число: продать 4.2 BTC за следующие пять минут. Расписание VWAP выдает такое же число с другим обоснованием. Ни то, ни другое ничего не говорит о том, что происходит дальше — попадут ли эти 4.2 BTC в стакан одним маркетабельным ордером, встанут ли на лучшей цене, собирая мейкерские комиссии, спрячутся ли за отображаемым объемом в 0.3 BTC, или их перевыставят одиннадцать раз, догоняя уплывающую котировку. Этот второй слой решений и есть тактический слой, и на криптобиржах, где комиссии определяют экономику сделки, он регулярно перемещает больше PnL на слайс, чем выбор планировщика над ним. Бюджеты интервалов у планировщика отличаются между TWAP и хорошо настроенным Almgren-Chriss на несколько базисных пунктов воздействия за весь родительский ордер; а уплата тейкерских комиссий на слайсах, которые можно было исполнить мейкером, или потеря позиции в очереди из-за небрежного перевыставления обходятся в сопоставимую сумму каждый час. Эта статья — про слой, который использует каждый, но почти никто не документирует: автомат состояний, решающий, как именно каждый дочерний ордер соприкасается со стаканом.

Два слоя, один узкий интерфейс

Lehalle и Laruelle в Market Microstructure in Practice (2-е изд., 2018) формализуют то, к чему приходит любой execution-деск: стратегический слой (планировщик), распределяющий объем во времени, и тактический слой (микротрейдер), отрабатывающий каждое выделение против живого стакана. Разделение не эстетическое — оба слоя живут на разных часах и работают с разными данными. Планировщик мыслит минутами, потребляет прогнозы волатильности и объема и решает вариационную задачу. Тактический слой мыслит миллисекундами-секундами, потребляет дельты L2 и оценки очереди, и решает последовательность небольших задач об оптимальной остановке.

Двухслойная архитектура исполнения: планировщик передает бюджет слайса и срочность вниз, тактический слой возвращает исполнения и недобор вверх

Интерфейс между ними должен быть узким. Вниз, для слайса kk:

  • бюджет qkq_k — объем, который нужно исполнить за этот интервал (это nkn_k из Almgren-Chriss или приращение объемной кривой из VWAP);
  • окно τk\tau_k — длина слайса;
  • срочность — для Almgren-Chriss естественный кандидат — κ=λσ2/η\kappa = \sqrt{\lambda\sigma^2/\eta}, который уже сжимает неприятие риска, волатильность и ликвидность в одну ставку; для планировщика VWAP это обычно расстояние до полосы ("мы отстаем от целевой кривой на 1.8%").

Вверх: исполнения с таймстампами и комиссиями, неисполненный остаток и недобор исполнения (implementation shortfall) на уровне слайса, измеренный относительно средней цены интервала на момент прихода ордера. Последнее важно: параметр воздействия планировщика η\eta уже оценивает, сколько должен стоить спрос на ликвидность со скоростью qk/τkq_k/\tau_k. Вся должностная инструкция тактического слоя укладывается в одну строку: добиться исполнения дешевле, чем предполагает модель на основе η\eta, не раскрывая при этом существование родительского ордера. Если измеренный недобор по слайсам стабильно бьет модельную стоимость, откалиброванный η\eta можно снизить, планировщик ускоряется, и весь стек улучшается. Если вы не можете измерить недобор слайса отдельно от стоимости расписания, вы не можете настроить ни один из слоев — у вас одно размытое число и две ручки управления.

Политика остатка — тоже часть контракта. Когда слайс заканчивается с неисполненным объемом, тактический слой либо принудительно завершает его (перекрывает остаток спредом — стандартное поведение при срочности, заданной дедлайном), либо возвращает его планировщику для переамортизации по оставшимся слайсам (приемлемо в начале расписания с низким κ\kappa, но губительно ближе к дедлайну, где переамортизация незаметно накапливается в огромный финальный слайс).

Лестница эскалации: сначала пассивно, агрессивно к дедлайну

Старейший результат в этой области — Harris (1998), "Optimal dynamic order submission strategies in some stylized trading problems" (Financial Markets, Institutions & Instruments 7(2)): для трейдера, вынужденного завершить сделку к дедлайну, оптимальная стратегия динамична — стоять в стакане с лимитными ордерами, пока время дешево, перевыставлять цену ближе к рынку по мере приближения дедлайна и перекрывать спред в конце. Каждый производственный тактический движок — потомок этой формы: выставить на лучшей цене, состариться, эскалировать, перекрыть спред. Что добавляют современные комиссионные сетки и динамика очереди — это точная арифметика того, когда именно срабатывает каждый переход.

Безубыточность для перекрытия спреда

Работаем в расчете на единицу, цены относительно текущей средней, для покупки. Перекрытие спреда прямо сейчас стоит половину спреда плюс тейкерская комиссия:

ctake=s2+ft.c_{\text{take}} = \frac{s}{2} + f_t.

Выставление на бид на окне τ\tau исполняется с вероятностью pp; исполнение приносит половину спреда и платит мейкерскую комиссию fmf_m (отрицательную, если это ребейт). Отсутствие исполнения означает перекрытие спреда в конце окна, после того как цена в среднем сдвинулась против вас на δ(τ)=E[неблагоприятное движение среднейнет исполнения]>0\delta(\tau) = E[\,\text{неблагоприятное движение средней} \mid \text{нет исполнения}\,] > 0 — строго положительно, потому что неисполнение и неблагоприятный дрейф — это одно и то же событие: ваш бид не задевают именно тогда, когда рынок уходит от него вверх. Ожидаемая стоимость выставления:

cpost=p(s2+fm)+(1p)(s2+ft+δ).c_{\text{post}} = p\left(-\frac{s}{2} + f_m\right) + (1-p)\left(\frac{s}{2} + f_t + \delta\right).

Выставление выгоднее перекрытия спреда тогда и только тогда, когда

  p  >  p\*=δΠ+δ,Π=s+ftfm  \boxed{\; p \;>\; p^\* = \frac{\delta}{\Pi + \delta}, \qquad \Pi = s + f_t - f_m \;}

где Π\Pi — это приз: полный выигрыш от того, что вы выступаете мейкером, а не тейкером — спред плюс разница в комиссиях. Это тот же порог безубыточности, что управляет всей экономикой maker-taker в исполнении, свернутый до одного слайса.

Цифры, бессрочный BTCUSDT: средняя цена $100,000, спред один тик s = \0.10,комиссиинауровнеVIP0—мейкер2б.п./тейкер5б.п.,тоесть, комиссии на уровне VIP0 — мейкер 2 б.п. / тейкер 5 б.п., то есть f_m = $20,, f_t = $50заBTC.Призза BTC. Приз\Pi = 0.10 + 50 - 20 = $30.10 \approx 3б.п.—обратитевнимание,спредздесьпрактическиничегоневносит;наплотныхкриптомейджорахпризиестьразницавкомиссиях.Возьмемдневнуюволатильность3 б.п. — обратите внимание, спред здесь практически ничего не вносит; на плотных крипто-мейджорах приз *и есть* разница в комиссиях. Возьмем дневную волатильность 3% (\sigma_{\text{day}} = $3{,}000)и) и \delta(\tau) \approx 0.6,\sigma_{\text{day}}\sqrt{\tau/86400}$ (0.6 — это дисконт на неблагоприятный отбор, который нужно калибровать самостоятельно, а не принимать на веру):

  • τ=10\tau = 10 с: \delta \approx \19,значит, значит p^* = 19/49 \approx 0.39$. Выставляйте только если ожидаете исполнения хотя бы на 39% за 10 секунд.
  • τ=60\tau = 60 с: \delta \approx \47,значит, значит p^* = 47/77 \approx 0.61$.
  • С мейкерским ребейтом в 1 б.п. вместо комиссии 2 б.п. (f_m = -\10):): \Pi = $60.10,ипорогдля10спадаетдо, и порог для 10 с падает до p^* \approx 0.24$.

Отсюда следуют два структурных факта. Во-первых, δ\delta растет как τ\sqrt{\tau}, а Π\Pi постоянна, поэтому p\*(τ)1p^\*(\tau) \to 1: у терпения есть жесткий срок годности, и таймер устаревания — не эвристика, а точка пересечения двух кривых: вашей оцененной p(τ)p(\tau) (вогнутой, насыщающейся по мере опустошения очереди перед вами) против p\*(τ)p^\*(\tau) (растущей). Во-вторых, комиссионный уровень, на котором вы торгуете, физически двигает всю лестницу. Повышение уровня, снижающее тейкерские комиссии, делает вашу оптимальную тактику более агрессивной — связь, которую большинство обнаруживает только тогда, когда после смены VIP-уровня меняется статистика исполнений.

Cont и Kukanov, "Optimal order placement in limit order markets" (Quantitative Finance 17(1), 2017; arXiv 2012), делают это строгим для одного периода: минимизировать ожидаемую стоимость исполнения SS единиц, разделенных между рыночными и лимитными ордерами (на одной или нескольких площадках), со штрафом за недобор. Решение для одной площадки явное и имеет структуру задачи разносчика газет (newsvendor): оптимальный размер лимитного ордера определяется распределением оттока очереди — выставляйте размер агрессивно, когда очередь перед вами мала относительно ожидаемого оттока, и покрывайте хвостовой риск рыночными ордерами. Их мультиплощадочное расширение решается методом стохастической аппроксимации и составляет интеллектуальное ядро логики пассивного распределения любого smart order router. Практический вывод для тактического движка: pp в приведенном выше пороге безубыточности — не константа, а функция позиции в очереди и скорости ее опустошения, поэтому тактический слой обязан потреблять оценщик позиции в очереди как полноценный вход.

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

Параметр срочности сжимает всю эту лестницу. Высокий κ\kappa от планировщика означает, что характерное время θ=1/κ\theta = 1/\kappa коротко: окна сжимаются, p\*p^\* растет, и движок сразу переходит к перекрытию спреда — и правильно, потому что планировщик уже объявил, что риск инвентаря доминирует над экономией на комиссиях. Низкий κ\kappa растягивает пассивную фазу. Тактический слой никогда не должен заново выводить срочность из собственного взгляда на рынок; это работа планировщика, и дублирование создает два несогласованных контроллера.

Перевыставление без сжигания позиции в очереди

Стоит ордеру встать в стакан, котировка начинает дрейфовать. Наивная погоня за ней — отменить, перевыставить на новой лучшей цене, повторить — верный способ незаметно уничтожить ту самую вероятность исполнения, ради которой ордер вообще выставляли. Позиция в очереди — это актив с измеримой денежной стоимостью (Moallemi и Yuan, 2016, оценивают ее в деньгах: позиции в начале очереди в ликвидных FIFO-стаканах стоят значимую долю спреда), и каждое решение о перевыставлении — это сделка: продать текущую позицию в очереди, купить новую в конце очереди на другом ценовом уровне. Такая сделка имеет смысл только тогда, когда стоимость нового уровня превышает стоимость старого плюс издержки на сообщения. А для этого нужно знать, что именно каждое изменение (amend) делает с вашим местом в очереди на конкретной площадке — и ответ здесь дико неоднороден.

CME Globex документирует самую чистую семантику: уменьшение объема ордера сохраняет приоритет по времени; увеличение объема или изменение цены отправляет вас в конец очереди. Это эталонная модель — уменьшение объема бесплатно, все остальное — повторная постановка в очередь.

Binance spot исторически предлагал только POST /api/v3/order/cancelReplace — внешне атомарную, но явно нетранзакционную комбинацию отмены и нового ордера. Два режима: STOP_ON_FAILURE (по умолчанию — если отмена не удалась, новый ордер не выставляется) и ALLOW_FAILURE (новый ордер выставляется, даже если отмена не удалась — здравствуй, случайная двойная экспозиция). Операция может частично завершиться успехом, что сигнализируется кодом HTTP 409, так что ваш OMS обязан сверять обе ноги независимо; и новый ордер всегда начинает жизнь в очереди с нуля. Затем, в 2025 году, Binance выпустил Order Amend Keep Priority (PUT /api/v3/order/amend/keepPriority): уменьшение объема на месте с сохранением приоритета по времени, без затрат на счетчик неисполненных ордеров. Семантика CME, пятнадцать лет спустя — и только половина про уменьшение объема.

Binance USDT-M фьючерсы имеет настоящий эндпоинт модификации (PUT /fapi/v1/order), но читайте мелкий шрифт: только LIMIT-ордера, обязательно передавать и price, и quantity, и "модифицированные ордера будут переупорядочены в очереди сведения" — документация не обещает сохранение приоритета даже для чистого уменьшения объема. Относитесь к любой модификации фьючерсного ордера как к сбросу очереди, который заодно экономит одно сообщение и сохраняет ID ордера. Один острый угол, о котором стоит знать: модификация GTX-ордера (post-only) на цену, которая привела бы к пересечению спреда, приводит к отмене ордера, а не к отклонению с сохранением — реализация пеггинга, не проверяющая это, время от времени будет самоуничтожать ордер через amend.

OKX предоставляет POST /api/v5/trade/amend-order (newPx, newSz, с cxlOnFail для автоотмены при неудаче amend). Это одно сообщение, сохраняющее ID ордера и подтверждающееся асинхронно — sCode = 0 означает "запрос принят", а фактический результат приходит по каналу ордеров как amendResult. Что публичная документация демонстративно не специфицирует — это поведение приоритета в очереди. Не заполняйте этот пробел в документации оптимизмом. Измерьте его: выставьте два маркерных ордера на тихом уровне, уменьшите размер одного через amend и посмотрите, какой исполнится первым за несколько сотен попыток. Пока у вас нет этих данных, консервативное предположение — любое изменение цены переставляет вас в очередь везде, уменьшение объема сохраняет приоритет только там, где это явно задокументировано — единственно защитимое.

Матрица операций amend по площадкам, показывающая, какие операции сохраняют приоритет в очереди, а какие сбрасывают его

Практические следствия для политики:

  1. Гистерезис, а не пеггинг. Перевыставляйте только тогда, когда лучшая цена сдвинулась больше чем на полосу bb тиков от вашей текущей цены. Внутри полосы дрейф — это шум, и ваша позиция в очереди стоит больше, чем один тик улучшения цены. Разумная стартовая полоса — 1–3 тика, масштабированная по краткосрочной волатильности; правильная полоса делает предельное перевыставление EV-нейтральным: VnewVcur=cmsgV_{\text{new}} - V_{\text{cur}} = c_{\text{msg}}, где VV — стоимость очереди в духе Moallemi-Yuan, а cmsgc_{\text{msg}} — теневая цена вашего лимита на частоту запросов. Операции amend/cancel-replace расходуют бюджет частоты ордеров на обеих площадках Binance; тактический движок, пеггующий каждый тик, лишит остальную систему пропускной способности сообщений.
  2. Уменьшайте объем через amend, никогда через cancel-repost. Когда планировщик урезает бюджет слайса на лету (POV-планировщик видит иссякающий объем, Almgren-Chriss пересчитывается после частичных исполнений), используйте путь с сохранением приоритета там, где он есть. Это единственный бесплатный обед во всем этом слое.
  3. Асимметричная срочность при перевыставлении. Перевыставление к рынку (погоня) сбрасывает вашу очередь по худшей цене — оно должно срабатывать только из логики эскалации, по ее таймеру. Перевыставление от рынка (рынок сам пришел к вам) — это подарок, берите его только через пассивную полосу, потому что ваш текущий уровень все равно вот-вот исполнится.

Айсберги, отображаемый объем и что раскрывает намерение

Отображаемый объем — третье решение, и это по-настоящему двусторонняя сделка, а не бесплатная кнопка стелса. Эмпирические данные:

  • Frey и Sandås ("The Impact of Iceberg Orders in Limit Order Books", рабочий доклад 2009; Quarterly Journal of Finance, 2017), на данных Xetra: айсберг-ордера составили 9.3% выставленного и 15.9% исполненного объема, были в 12–20 раз крупнее обычных лимитных ордеров, и — главный вывод — когда другие участники обнаруживают айсберг, они реагируют встречными рыночными ордерами. Скрытый объем, будучи выявленным, притягивает поток: поиск скрытой ликвидности работает в обе стороны.
  • Bessembinder, Panayides и Venkataraman ("Hidden liquidity: an analysis of order exposure strategies in electronic stock markets", JFE 94(3), 2009), на данных Euronext Paris, где скрытые ордера составляли 44% объема выборки: сокрытие снижает недобор исполнения, но также снижает вероятность полного исполнения и удлиняет время до завершения. Раскрытие объема покупает исполнения и платит за них воздействием на цену; опцион используется ровно так, как предсказывает теория — агрессивные ордера раскрываются, чтобы привлечь контрагентов, терпеливый объем прячется.
  • Esser и Mönch ("The navigation of an iceberg", Finance Research Letters 4(2), 2007) рассматривают размер видимого пика как задачу оптимизации: больший показ исполняется быстрее, меньший показ раскрывает меньше, и оптимум находится внутри интервала.

Сначала механика, потому что именно она ограничивает оптимизацию: практически на каждой площадке, поддерживающей нативные айсберги (Binance spot через icebergQty, OKX через свои алгоритмические айсберг-ордера), каждое пополнение видимого пика встает в конец очереди по этой цене. Айсберг, таким образом, это не "один ордер со скрытым объемом" — это последовательность мелких ордеров, каждый из которых платит полное время ожидания в очереди, выставляемых автоматически. Применительно к порогу безубыточности выше это важно: эффективная pp для каждого пика — это вероятность исполнения из конца очереди, а не вашей исходной позиции. Глубокие очереди наказывают маленькие пики дважды — более медленными исполнениями и большим числом пополнений, а значит и неблагоприятного отбора.

Далее — проблема сигнализации. Собственный метод обнаружения Frey и Sandås — предостерегающий пример: их частотный детектор опирается на два самых распространенных паттерна ленивой реализации — постоянный размер пика и таймстампы пополнения, идентичные таймстампу исполняющей сделки. Любой участник, запускающий такой детектор (а на криптоплощадках таких немало — собственные метаданные сведения биржи делают это еще проще для колоцированного потока), восстанавливает ваш скрытый объем за несколько пополнений. Векторы утечки, ранжированные по частоте, с которой я вижу их в реальности:

  1. Постоянные или круглые отображаемые размеры (0.5 BTC, каждый раз).
  2. Мгновенное, детерминированное пополнение сразу после исполнения полного пика — та же таймстамп-сигнатура.
  3. Детерминированные таймеры эскалации: перекрытие спреда ровно на 30-й секунде каждого слайса, и лента выглядит как метроном.
  4. Фиксированная задержка перевыставления и полоса — каденция ваших amend-запросов является таким же идентифицирующим отпечатком, как и размеры ваших ордеров, что и есть предмет цифровых отпечатков и идентификации трейдеров.

Цена быть обнаруженным — не гипотетическая. Van Kervel и Menkveld ("High-frequency trading around large institutional orders", Journal of Finance 74(3), 2019) показывают, что HFT изначально торгуют против институциональных метаордеров — предоставляя ту самую ликвидность, которую потребляет ваша пассивная тактика, — а затем разворачиваются и начинают торговать в ту же сторону, как только устойчивость ордера раскрывает информацию, догоняя остаток и заметно повышая стоимость родительского ордера. Институциональные трейдеры в ответ начали сознательно балансировать между спекулятивной прибылью и риском обнаружения. Ваш тактический слой — это именно то место, где реализуется этот компромисс: рандомизируйте отображаемый размер (равномерно 30–70% от базы, масштабированной по волатильности, работает неплохо), добавляйте джиттер ±20–30% к каждому таймеру, иногда позволяйте пополнению подождать и никогда не давайте двум дочерним ордерам делить размер, фазу таймера и профиль задержки. Ничто из этого не стоит измеримого качества исполнения; все это поднимает уровень шума для любого, кто подгоняет детектор под ваш поток.

Минимальный тактический движок

Весь слой выше сжимается в небольшой автомат состояний на слайс: IDLE → POSTED → (цикл перевыставления) → CROSSING → DONE, с проверкой безубыточности на входе, полосой гистерезиса в состоянии выставления и эскалацией по дедлайну. Версия ниже намеренно минимальна — без адаптеров под конкретные площадки, без управления айсбергами — но она событийно-управляемая и не имеет побочных эффектов, поэтому напрямую встраивается в симулятор четвертого уровня, учитывающий очередь, из лестницы симуляции исполнений: симулятор вызывает on_tick/on_fill и интерпретирует действия как post → GTX/post-only, cross → IOC, cancel_replace/amend_down → семантика площадки из матрицы выше.

import math
from dataclasses import dataclass
from enum import Enum, auto

class State(Enum):
    IDLE = auto(); POSTED = auto(); CROSSING = auto(); DONE = auto()

@dataclass
class Fees:
    maker: float          # $ per unit; negative = rebate
    taker: float          # $ per unit

@dataclass
class Cfg:
    tick: float
    sigma_1s: float       # $ per sqrt(second), from your live vol estimator
    adverse_frac: float = 0.6   # E[adverse move | no fill] ~ 0.6 * sigma; calibrate
    reprice_band: float = 2.0   # ticks of touch drift tolerated before repricing
    escalate_frac: float = 0.7  # cross the remainder at this fraction of the window

class SliceTactic:
    """One instance per scheduler slice. Drive it from a fill simulator or OMS."""

    def __init__(self, side: str, qty: float, window: float, fees: Fees, cfg: Cfg):
        self.side, self.qty, self.window = side, qty, window
        self.fees, self.cfg = fees, cfg
        self.filled, self.state, self.px, self.t0 = 0.0, State.IDLE, None, None

    def p_star(self, spread: float, tau: float) -> float:
        """Break-even fill probability for posting over a window tau."""
        delta = self.cfg.adverse_frac * self.cfg.sigma_1s * math.sqrt(tau)
        prize = spread + self.fees.taker - self.fees.maker
        return delta / (prize + delta)

    def p_fill(self, queue_ahead: float, drain: float, tau: float) -> float:
        """Crude queue-drain estimate; swap in your calibrated fill model."""
        if drain <= 0: return 0.0
        return min(1.0, drain * tau / max(queue_ahead + self.qty, 1e-9))

    def on_tick(self, t, bid, ask, queue_ahead, drain):
        if self.state == State.DONE: return []
        if self.t0 is None: self.t0 = t
        left = self.qty - self.filled
        elapsed, remain = t - self.t0, self.window - (t - self.t0)
        touch = bid if self.side == "buy" else ask

        if elapsed >= self.cfg.escalate_frac * self.window and left > 0:
            self.state = State.CROSSING          # deadline: pay up, finish
            return [("cross", left)]

        if self.state == State.IDLE:
            if self.p_fill(queue_ahead, drain, remain) >= self.p_star(ask - bid, remain):
                self.state, self.px = State.POSTED, touch
                return [("post", touch, left)]    # GTX / post-only
            self.state = State.CROSSING           # posting is -EV here
            return [("cross", left)]

        if self.state == State.POSTED:
            if abs(touch - self.px) / self.cfg.tick > self.cfg.reprice_band:
                self.px = touch                   # hysteresis breached:
                return [("cancel_replace", touch)]  # accept the queue reset
        return []

    def on_fill(self, t, fill_qty):
        self.filled += fill_qty
        if self.filled >= self.qty - 1e-9:
            self.state = State.DONE
            return [("slice_done", self.filled)]
        return []

    def on_budget_cut(self, new_qty):
        """Scheduler revised the slice down: amend-down keeps queue priority
        where documented (CME, Binance spot amend/keepPriority)."""
        self.qty = new_qty
        left = new_qty - self.filled
        return [("amend_down", left)] if left > 0 else [("cancel",)]

Три честные оговорки. p_fill здесь — заглушка-отношение; в продакшене это должна быть корзинная, живо откалиброванная модель из статьи про симуляцию исполнений, потому что весь фильтр post/cross ровно настолько хорош, насколько хороша эта оценка. adverse_frac прячет самую сложную величину во всей статье (δ\delta зависит от режима рынка и резко возрастает именно тогда, когда выставление особенно соблазнительно); оценивайте ее по собственным исходам неисполнения, разбитым по режимам волатильности. И движок выше безусловно перевыставляет через cancel-replace — версия, учитывающая особенности площадки, должна направлять изменения с уменьшением объема через путь с сохранением приоритета и списывать каждое действие с бюджета сообщений.

Прогоните это внутри симулятора на реплей-ленте, прежде чем доверять каким-либо параметрам. Эксперимент, который имеет значение: зафиксируйте планировщик, переберите escalate_frac и reprice_band, постройте график недобора слайса против модельной стоимости, предполагаемой η\eta. Поверхность имеет плато — широкие полосы близких к оптимальным параметров — и два обрыва: эскалация слишком поздно (неисполненные остатки перекрывают спред в момент моментума) и перевыставление слишком нетерпеливое (вся ценность очереди сожжена). Вы хотите знать, где ваши обрывы, до того, как это выяснит продакшен.

Что забрать с собой

  1. Два слоя, один контракт. Планировщик решает сколько и к какому сроку; тактика решает как. Интерфейс — бюджет, окно, срочность вниз; исполнения и недобор слайса относительно средней цены на входе в интервал — вверх. Если вы не можете отнести недобор к конкретному слою, вы не можете настроить ни один из них.
  2. Фильтр post/cross — это арифметика, а не интуиция. Выставляйте тогда и только тогда, когда p>δ/(Π+δ)p > \delta/(\Pi + \delta), где Π=s+ftfm\Pi = s + f_t - f_m. На плотных крипторынках приз — это разница в комиссиях, поэтому ваш комиссионный уровень определяет тактику — пересчитывайте лестницу после каждой смены уровня.
  3. Таймеры устаревания — это точка пересечения двух кривых — насыщающейся вероятности исполнения против растущего как τ\sqrt{\tau} неблагоприятного отбора — а не константы из фольклора.
  4. Позиция в очереди — это актив; знайте семантику amend каждой площадки, прежде чем ее тратить. CME: уменьшение объема сохраняет приоритет. Binance spot: cancelReplace всегда переставляет в очередь заново, amend-keepPriority 2025 года сохраняет приоритет для уменьшения объема. Binance фьючерсы: любая модификация переставляет заново. OKX: не задокументировано — измеряйте и тем временем предполагайте худшее.
  5. Айсберги — это последовательность ордеров из конца очереди, и ленивые из них легко читаются. Постоянные пики и пополнения с одинаковым таймстампом — опубликованная сигнатура обнаружения; рандомизируйте размеры и таймеры или смиритесь с тем, что вас будут догонять.
  6. Сначала отправьте автомат состояний в свой симулятор исполнений. Тактический слой — та часть стека, где бэктест и продакшен расходятся сильнее всего, и именно поэтому ему место внутри симулятора, а не пристроенным сбоку после.

Полезные ссылки

  1. Harris, L. — Optimal Dynamic Order Submission Strategies in Some Stylized Trading Problems, Financial Markets, Institutions & Instruments 7(2), 1-76 (1998)
  2. Cont, R., Kukanov, A. — Optimal Order Placement in Limit Order Markets, Quantitative Finance 17(1), 21-39 (2017)
  3. Frey, S., Sandås, P. — The Impact of Iceberg Orders in Limit Order Books (2009)
  4. Bessembinder, H., Panayides, M., Venkataraman, K. — Hidden Liquidity: An Analysis of Order Exposure Strategies in Electronic Stock Markets, Journal of Financial Economics 94(3), 361-383 (2009)
  5. van Kervel, V., Menkveld, A. — High-Frequency Trading around Large Institutional Orders, Journal of Finance 74(3), 1091-1137 (2019)
  6. Moallemi, C., Yuan, K. — A Model for Queue Position Valuation in a Limit Order Book (2016)
  7. Lehalle, C.-A. — Market Microstructure Knowledge Needed for Controlling an Intra-Day Trading Process (2011)
  8. Binance Spot API — Order Amend Keep Priority
  9. Binance Spot API — Trading endpoints (cancelReplace semantics)
  10. Binance USDT-M Futures API — Modify Order
  11. OKX API v5 — Amend order
  12. CME Group — Order Functionalities (modification and time priority)

Цитирование

@article{soloviov2026childordertactics,
  author = {Soloviov, Eugen},
  title = {Inside the slice: child-order tactics between your scheduler and the exchange},
  year = {2026},
  url = {https://marketmaker.cc/blog/child-order-execution-tactics},
  description = {The tactics layer between execution schedulers and the exchange: passive-then-aggressive escalation with maker-taker break-even math, amend vs cancel-replace queue semantics across venues, iceberg anti-signaling, and a per-slice Python state machine for fill simulators.}
}
Дисклеймер: Информация в этой статье предоставлена исключительно в образовательных и ознакомительных целях и не является финансовым, инвестиционным или торговым советом. Торговля криптовалютами сопряжена с высоким риском убытков.

Авторы

Eugen Soloviov
Eugen Soloviov

Инженер торговых систем

Разработка торговых ботов с 2017 года: межбиржевой арбитраж (подключал до 30 бирж), парный арбитраж на коинтеграции между спотом и фьючерсами, скальпинг, фронтраннинг, торговля по новостям, сентиментный анализ, трендовые алгоритмы, а также алгоритмы управления и балансировки портфелей. Делает выставление ордеров до 1 мс, warehouse для big data, бэктестинг-движки, AI-агентов и интерфейсы для ботов (в т.ч. open-source profitmaker.cc). Стек: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, архитектура.

Newsletter

Будьте в курсе событий

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

Мы уважаем вашу конфиденциальность. Отписаться можно в любой момент.