Умный роутинг ордеров в крипте: один ордер, двенадцать площадок, никакого NBBO
Вам нужно купить 400 BTC. У Binance больше всего глубины. OKX и Bybit оба показывают приличный объем на тик шире. Coinbase котирует более привлекательную заголовочную цену, но в USD, а не в USDT. Верх стакана на Kraken выглядит прекрасно и устарел на 400 миллисекунд. На Upbit еще лучше, но у вас нет комплаенс-одобрения для Кореи, как и самих KRW. Трейдер на рынке акций, глядя на этот бардак, потянулся бы за умным роутером ордеров и перестал бы думать, потому что в акциях сложные части роутинга были встроены в регуляторную инфраструктуру два десятилетия назад. В крипте инфраструктура — это вы. Нет консолидированной ленты, нет правила защиты ордеров, нет предельной комиссии, нет неттингового расчета — и, что самое главное, нет возможности торговать там, где ваш капитал еще не находится.
Эта статья о том, как все равно построить роутер: консолидированный стакан и почему наивный роутинг по лучшей цене против него теряет деньги, задача распределения как выпуклая программа, которую реально решить в рамках дедлайна дочернего ордера, капитальное ограничение, которое делает крипто-SOR неотделимым от казначейского управления, роутинг с учетом мейкер-ордеров между площадками и цикл обратной связи TCA, который показывает, работает ли все это вообще. Это инженерный близнец статьи Сложное исполнение арбитража на Rust — та статья про наносекунды, эта — про решения.
Что роутинг в акциях получает бесплатно
Стоит точно понимать, что роутинг US-акций наследует от регулирования, потому что каждый пункт этого списка — вещь, которую вам придется либо восстановить с нуля, либо сознательно жить без нее.
Regulation NMS (SEC, 2005) сделал три важные вещи. Правило 611, Order Protection Rule, запрещает исполнение по цене хуже защищенной котировки, отображаемой на другой бирже — "trade-through" — что заставляет каждого брокера либо роутить на лучшую отображаемую цену, либо сметать ее intermarket sweep ордерами. Правило 610 ограничивает комиссию за доступ, которую любая площадка может взимать за снятие защищенной котировки, суммой $0.003 за акцию, так что отображаемые цены сопоставимы между площадками с точностью до 30 милов. А консолидированная лента (SIP) публикует National Best Bid and Offer — единый официальный ответ на вопрос "какой сейчас рынок".
Академический вердикт по этой архитектуре — она работает на удивление хорошо. O'Hara and Ye (2011), "Is market fragmentation harming market quality?" (Journal of Financial Economics 100(3), 459–474), изучили американские акции при разных уровнях фрагментации и обнаружили, что более фрагментированные акции имели более низкие транзакционные издержки и более быстрое исполнение, с ценами, ближе следующими случайному блужданию. Их итоговая формулировка — ключевая фраза: рынок US-акций ведет себя как "единый виртуальный рынок с множеством точек входа". Фрагментация безвредна, когда умные роутеры плюс защита от trade-through сшивают фрагменты обратно воедино. Foucault and Menkveld (2008), "Competition for Order Flow and Smart Order Routing Systems" (Journal of Finance 63(1), 119–158), показали механизм на голландском рынке: когда против Euronext вышла вторая книга лимитных ордеров (LSE's EuroSETS), консолидированная глубина выросла, а предложение ликвидности на площадке напрямую подавлялось ее долей trade-through — роутеры, игнорирующие площадку, убивают у нее стимул котировать.
Даже в этом регулируемом мире консолидированное представление — ложь на коротких горизонтах. Ding, Hanna, and Hendershott (2014), "How Slow Is the NBBO? A Comparison with Direct Exchange Feeds" (Financial Review 49(2), 313–332), измерили SIP NBBO против NBBO, построенного из прямых биржевых фидов в том же дата-центре, и обнаружили рассинхронизации по несколько раз в секунду в активных бумагах, обычно длящиеся одну-две миллисекунды — чистая задержка агрегации и передачи. Держите это число в уме: это эквиваленты акций проблемы, которая в крипте хуже на один-два порядка.
Теперь удалите все это. В крипте нет NBBO, потому что нет SIP. Нет правила trade-through: площадка с радостью исполнит вас по цене на пять тиков хуже котировки другой площадки, и никто ничего не зафиксирует. Нет предельной комиссии: тейкер-комиссии варьируются от долей базисного пункта по договорным тирам до 10 б.п. по розничным сеткам, так что порядок по отображаемой цене и порядок по чистой цене регулярно расходятся. И нет консолидированного клиринга: каждая биржа — свой собственный изолированный контур с предфондированными балансами. Вы одновременно SIP, роутер и клиринговая фирма.
Построение консолидированного стакана и почему наивный роутинг по лучшей цене проваливается
Инженерный базис неромантичен: N WebSocket L2-фидов, обработка пропусков в номерах последовательности по каждой площадке, нормализация символов и размера тика, нормализация валюты котировки (стакан BTC-USD и стакан BTC-USDT различаются на курс USDT/USD, который не тождественно равен 1.0, а иногда очень сильно не равен). Слейте нормализованные стаканы в единую отсортированную по цене лестницу, помечая каждый уровень площадкой и — критически важно — возрастом снапшота, из которого он взят. Если ваш объединенный стакан не несет возраст котировки по каждой площадке как поле первого класса, вы построили скринсейвер, а не роутер.

Наивный роутер жадно проходит эту объединенную лестницу: сначала лучшая чистая цена. Он проваливается по трем отдельным причинам, и их стоит держать раздельно, потому что исправления для них разные.
Устаревшие котировки и латентностный перекос. Ваши площадки не доставляют данные с одинаковой задержкой. Коллоцированный фид может быть свежим на 3 мс, когда вы на него реагируете; публичный WebSocket с площадки на другом континенте может быть устаревшим на 300 мс. Объединенный верх стакана поэтому представляет собой композит разных моментов прошлого. Когда BTC двигается на 10 б.п. за 200 мс — а это рутина — котировки устаревшей площадки выглядят систематически привлекательно именно с неправильной стороны. Роутинг на них означает участие в гонке, которую вы уже проиграли: котировка исчезла, ваш IOC возвращается пустым или частично исполненным, а к моменту повторного роутинга свежие площадки уже перекотировались. Это та же проблема рассинхронизации SIP на 1–2 мс из Ding–Hanna–Hendershott, только ваши рассинхронизации длятся сотни миллисекунд, и никто не обязан ничего соблюдать.
Фантомная ликвидность. Суммирование отображаемого объема по площадкам завышает результат, потому что один и тот же инвентарь маркет-мейкера котируется одновременно в нескольких местах. Van Kervel (2015), "Competition for Order Flow with Fast and Slow Traders" (Review of Financial Studies 28(7), 2094–2127), задокументировал это на фрагментированных акциях: за сделкой на одной площадке в течение миллисекунд следует значительная отмена лимитных ордеров на конкурирующих площадках — ровно как предсказывает модель, где быстрые поставщики ликвидности котируют дублирующий объем везде и отзывают копии, как только одна из них исполнена. Крипто-маркет-мейкеры используют тот же прием на Binance/OKX/Bybit, поэтому доступная консолидированная глубина существенно меньше отображаемой консолидированной глубины, и разрыв растет с тем, насколько последовательно (а не одновременно) вы бьете по площадкам. Если ваш роутер отправляет дочерние ордера по одной площадке за раз, дожидаясь подтверждения каждого исполнения, вы фармите сами себя: каждое исполнение сигнализирует остальному рынку об отмене.
Комиссии переупорядочивают лестницу. Площадка, показывающая лучшую сырую цену с тейкер-комиссией 7.5 б.п., часто оказывается худшей чистой ценой в стакане. Это звучит слишком очевидно, чтобы озвучивать, но именно так работает "роутинг по лучшей отображаемой цене" — то, что реализует большинство роутеров крипты первого поколения (и несколько вендорских продуктов). Сравнение чистых цен после комиссии — это минимальная планка; статья-компаньон о мейкер-тейкер комиссиях и рибейтах разбирает математику комиссий по площадкам, динамику VIP-тиров и почему ваш маржинальный тир комиссии — а не ценник на витрине — должен быть встроен в роутер.
Оптимизация роутинга
Формализуем задачу дочернего ордера. Вам нужно купить количество прямо сейчас, маркетабельно, по площадкам . Пусть — маржинальная цена аска площадки после съедения единиц ее стакана (неубывающая ступенчатая функция из L2-снапшота), — ее тейкер-комиссия, а — штраф за единицу за устаревание и неблагоприятный отбор на площадке (калибруется ниже, из ваших собственных маркаутов). Распределение решает
Каждая выпукла (интеграл неубывающей функции плюс линейный член), так что задача выпуклая, и условия KKT дают всю историю целиком: существует порог такой, что
и для площадок, не получающих ничего. Словами: лейте ордер по площадкам, как воду, выравнивая маржинальную полную стоимость везде, где торгуете. Площадка исключается ровно тогда, когда ее первая единица — лучшая цена плюс комиссия плюс штраф за устаревание — хуже маржинальной единицы где-либо еще.

Для ступенчатых стаканов решение water-filling вычисляется жадным проходом по объединенной лестнице, скорректированной на комиссии и штрафы — так что жадный проход по глубине сам по себе не ошибочен; это точное решение при условии, что вы жадно проходите по чистым маржинальным издержкам с усеченными размерами, а не по сырым отображаемым ценам. Это различие — вся разница между роутером и скринсейвером.
Каноническая трактовка общей задачи — Cont and Kukanov, "Optimal order placement in limit order markets" (Quantitative Finance 17(1), 21–39, 2017; arXiv:1210.1625). Они формализуют размещение ордеров по площадкам — включая разделение между лимитными и рыночными ордерами, комиссии и рибейты, штраф за риск исполнения — как выпуклую оптимизацию, выводят явную замкнутую форму для разделения лимит/маркет на одной площадке и дают алгоритм стохастической аппроксимации для многоплощадочного случая, вычисляющий распределение по двенадцати биржам менее чем за 200 мс. Фреймворк предшествует крипте, но переносится почти без изменений, потому что изначально не предполагал NBBO — он предполагал только стаканы по площадкам, комиссии по площадкам и неопределенность исполнения, что в точности является крипто-ситуацией.
Минимальный, честный набросок маркетабельной стороны (выпуклый water-fill с усечением на устаревание):
import math
from dataclasses import dataclass
@dataclass
class Venue:
name: str
asks: list[tuple[float, float]] # (price, displayed size), sorted
taker_fee: float # fractional, e.g. 0.0002 = 2 bps
quote_age_ms: float
kappa: float # phantom-liquidity decay rate, 1/ms
lam: float # staleness/toxicity penalty, $ per unit
def allocate(venues: list[Venue], Q: float):
ladder = [] # (marginal all-in cost, accessible qty, venue)
for v in venues:
surv = math.exp(-v.kappa * v.quote_age_ms) # P(level still there)
for price, size in v.asks:
cost = price * (1.0 + v.taker_fee) + v.lam
ladder.append((cost, size * surv, v.name))
ladder.sort()
fills, remaining = {}, Q
for cost, qty, name in ladder:
take = min(qty, remaining)
fills[name] = fills.get(name, 0.0) + take
remaining -= take
if remaining <= 1e-12:
break
return fills, remaining # remaining > 0 => book too thin: slice parent
Шестнадцать строк логики; весь интеллект живет во входных данных. (насколько быстро отображаемый объем испаряется с возрастом котировки) калибруется из ваших собственных коэффициентов исполнения IOC как функция возраста котировки в момент отправки. берется из маркаутов по площадкам (последний раздел). Оба параметра измеряются, а не угадываются.
Разобранный пример. Купить BTC по трем площадкам:
| Площадка | Тейкер-комиссия | Возраст котировки | Аски (цена × размер) |
|---|---|---|---|
| A (глубокая, свежая) | 2.0 б.п. | 10 мс | 87 000 × 3.0; 87 010 × 4.0; 87 025 × 6.0 |
| B (дешевая комиссия, устаревшая) | 1.0 б.п. | 250 мс | 86 995 × 1.5; 87 015 × 2.0 |
| C (лучшая заголовочная цена, жирная комиссия) | 7.5 б.п. | 20 мс | 86 990 × 2.0; 87 000 × 3.0 |
Сырая лента говорит, что у C лучший аск (86 990), затем B. Скорректируем на комиссию — и лестница перестраивается полностью: верхний уровень C дает чистую цену — худшую ликвидность на экране. Верх B дает чистую 87 004, верх A — 87 017. Применим усечение на устаревание 30% к отображаемому размеру B () и проведем water-fill: 1.05 BTC с первого уровня B, 3.0 с первого уровня A, 1.4 со второго уровня B, 4.0 со второго уровня A, 0.55 с третьего уровня A. Средняя цена по всей сделке: **87 038.8: на 1.9 б.п. хуже, около $166 на одном дочернем ордере в 10 BTC, и это накапливается на каждом дочернем ордере каждого родительского ордера весь день. И обратите внимание на суть: площадка с лучшей отображаемой ценой на ленте получила от оптимизированного роутера ноль потока. В крипте никто не заставляет вас торговать там — роутинг через "защищенную котировку" не является концепцией — и правильное распределение часто полностью игнорирует видимую лучшую цену.
Что выпуклая программа все еще игнорирует: одновременность (запускайте всех дочерних детей по всем площадкам в одну и ту же миллисекунду, иначе отмены по Ван Кервелу перекотируют площадки посреди исполнения), дискретные размеры лотов и минимальные номиналы (округлите непрерывное решение, жадно доводите до ума), и опцию не пересекать спред вообще — это тема раздела 5. Более глубокий вопрос о том, как крупные родительские ордера должны нарезаться по времени до того, как заработает вся эта логика площадок, разобран в оптимальном исполнении Almgren–Chriss; SOR решает, куда идет дочерний ордер, а не когда дочерние ордера случаются.
Капитальное ограничение: SOR — это казначейское управление
Все вышесказанное молча предполагало, что вы можете торговать на площадке . В акциях это предположение бесплатно: один прайм-брокер, неттинговый расчет, торгуй сейчас и перемещай деньги потом. В крипте это связывающее ограничение всей системы. Биржи требуют предфондированных балансов — вы не можете снять аск Kraken за USDT, лежащий на Binance. Так что настоящая задача — это
где — ваш доступный баланс на площадке (в котируемом активе для покупок, в базовом для продаж). Условия KKT теперь читаются как с — множителем на ограничение баланса. На ограниченных площадках : маржинальный доллар там исполняется дешевле, чем общерыночный уровень воды, и вы вынуждены направлять поток на более дорогие площадки. Этот множитель — не абстракция: — это буквально доллары за единицу, которые вы бы сэкономили, если бы на площадке прямо сейчас существовала еще одна единица баланса. Просуммированный по вашему прогнозируемому потоку, он представляет собой вашу готовность платить за трансфер для ребалансировки, и решение о ребалансировке превращается в сравнение, которое может выполнить любая казначейская система: перемещайте инвентарь, когда
Правая часть не мала и не постоянна. On-chain BTC требует 2–6 подтверждений (20–60 минут), прежде чем биржи его зачислят; ERC-20 переводы занимают минуты плюс газ, который взлетает именно тогда, когда рынки заняты; рельсы TRC-20 и Solana быстрее и дешевле, но поддерживаются не повсеместно; и каждая биржа добавляет собственную очередь обработки вывода, которая растягивается от минут до часов именно во время волатильности — когда ваш роутер больше всего хочет переместить инвентарь. Полная арифметика издержек трансфера — комиссии, распределения задержек и ценовой риск, который вы несете в процессе — разобрана в статье об арбитраже ставок финансирования и переносится дословно: ребалансировка SOR — это тот же объект, что и трансфер ноги арбитража, включая сторону издержек.
Поэтому академический результат, который здесь стоит усвоить, — не статья об исполнении, а Makarov and Schoar (2020), "Trading and Arbitrage in Cryptocurrency Markets" (Journal of Financial Economics 135(2), 293–319). Они задокументировали межбиржевые ценовые расхождения, сохраняющиеся днями и неделями — включая корейскую "кимчи-премию", превысившую 40% в начале 2018 года, — и показали, что транзакционные издержки не могут это объяснить; объяснение — медленный, ограниченный контролем капитала арбитраж. Крипто-площадки — не "единый виртуальный рынок с множеством точек входа" O'Hara–Ye. Это частично сегментированные пулы, соединенные медленными, дорогими трубами, и ваш роутер живет внутри этой сегментации. Крипто-SOR без модели казначейства — это косплей SOR для акций.

На практике это превращается в двухскоростной контроллер. Быстрый цикл (миллисекунды) решает ограниченный water-fill в рамках текущих балансов для каждого дочернего ордера. Медленный цикл (минуты-часы) наблюдает за временными рядами теневых цен и прогнозируемым потоком и планирует трансферы, когда устойчивая составляющая преодолевает порог издержек трансфера — с гистерезисом, потому что перекидывание инвентаря между площадками на шуме — это способ подарить свое преимущество сети Tron. Институциональные деск-столы сжимают проблему через внебиржевой расчет (Copper ClearLoop, Ceffu MirrorX): залог хранится у кастодиана и зеркалируется на площадки, что резко сокращает задержку трансфера для поддерживаемых площадок — это сужает ограничение, но не устраняет его, и добавляет собственную статью контрагентского риска.
Роутинг с учетом мейкер-ордеров и межплощадочные игры в очередях
Роутер, который только пересекает спреды, оставляет самую дешевую ликвидность некупленной: свою собственную. Фреймворк Cont–Kukanov уже содержит ответ — их замкнутая форма для одной площадки разделяет ордер между постановкой и снятием на основе комиссий, позиции в очереди и неприятия риска исполнения — и многоплощадочная версия обобщает это: ставьте пассивно на площадках, где (мейкер-комиссия, длина очереди, вероятность исполнения в рамках дедлайна дочернего ордера) доминируют, снимайте на площадках, где немедленность дешева, и относитесь к неисполненному пассивному остатку как к потоку, который повторно входит в тейкер-оптимизацию к дедлайну.
Две крипто-специфичные особенности делают это богаче версии для акций.
Погоня за комиссиями — измеренная ловушка. Battalio, Corwin, and Jennings (2016), "Can Brokers Have It All? On the Relation between Make-Take Fees and Limit Order Execution Quality" (Journal of Finance 71(5)), показали, что американские брокеры, направляющие лимитные ордера на площадки с самым высоким рибейтом, получали измеримо худшее исполнение — более низкие коэффициенты исполнения, худшее реализованное качество — потому что площадка с рибейтом — это место, где сидит ордер каждого другого охотника за рибейтом: самая длинная очередь, самые неблагоприятные исполнения. Крипто-аналог точен. Площадка, платящая лучший мейкер-рибейт, привлекает пассивные котировки каждого маркет-мейкера; ваш ордер присоединяется к глубокой очереди и исполняется преимущественно тогда, когда цена вот-вот пройдет через вас. Чистая мейкер-экономика с поправкой на маркаут по площадкам (следующий раздел) регулярно ранжирует площадки противоположно их сеткам комиссий.
Латентностный перекос — двусторонняя игра. Тот же межплощадочный информационный поток, который Ван Кервел задокументировал как защитные отмены, с другой стороны является наступательным сигналом: сделка на верху стакана Binance предсказывает сделки и отмены на соответствующем уровне OKX в течение миллисекунд. Роутер, учитывающий мейкер-ордера, поэтому должен (а) перекотировать свои резидентные ордера по событиям других площадок — привязываясь к межплощадочной микроцене, а не к локальной середине спреда — иначе он станет медленным контрагентом, которого выберут межплощадочные арбитражеры; и (б) может играть в эту игру намеренно: ставить на площадке, которая отстает, хеджировать на площадке, которая лидирует в момент исполнения. Это межплощадочный арбитраж очередей, и это та же структура задержек, что эксплуатируется в исполнении межбиржевого арбитража, просто встроенная внутрь мандата исполнения, а не стат-арб книги. Операционное требование идентично: событие исполнения на площадке A и хедж-ордер на площадку B должны жить в одном и том же однозначном по миллисекундам коде — иначе преимущество достанется кому-то другому.
Измерение качества роутинга: маркауты и турнирные таблицы
Роутеры акций дисциплинируются раскрытием по Правилу 605/606. Ваш роутер не дисциплинирует ничего, кроме вашего собственного TCA — фреймворк из implementation shortfall и TCA служит табло; здесь — специфичный для роутера срез этого фреймворка.
Атомарное измерение — это маркаут по площадке: для каждого исполнения фиксируется (консолидированная, скорректированная на задержку) середина спреда на момент для , со знаком так, что отрицательное значение означает, что рынок двинулся против вашего исполнения. Агрегируйте это в единую турнирную таблицу:
| Площадка | Доля тейкер-исполнений | Эфф. спред (б.п.) | Комиссия (б.п.) | Маркаут 1с (б.п.) | Полная стоимость (б.п.) |
|---|---|---|---|---|---|
| A | 46% | 1.4 | 2.0 | −0.6 | 4.0 |
| B | 31% | 1.9 | 1.0 | −2.1 | 5.0 |
| C | 23% | 1.2 | 7.5 | −0.4 | 9.1 |
Колонка комиссии говорит, что B — дешевая площадка. Колонка полной стоимости говорит, что B — дорогая площадка: ее устаревшие котировки исполняют вас избирательно, когда рынок уже двигается сквозь них, и секундный маркаут собирает по счету. Эта инверсия — ранжирование по комиссии против ранжирования по эффективной стоимости — самая устойчивая находка, когда деск-столы впервые строят эту таблицу, и это именно то число, которое должно вернуться в роутер: штраф выпуклой программы — это и есть устойчивый дефицит маркаута по площадке, измеренный, сглаженный и обновляемый. Роутер и TCA образуют замкнутый цикл, или ни один из них не работает.
Одна методологическая ловушка: турнирные таблицы, построенные из живого роутера, загрязнены систематической ошибкой отбора. Если роутер уже направляет сложный, информированный поток на глубокую площадку, а легкий поток — на дешевую, маркауты глубокой площадки выглядят несправедливо плохими. Чистое решение — намеренная рандомизация: направляйте несколько процентов дочерних ордеров равномерно случайным образом (-жадный роутер, который кванты узнают как бандита с выпукло-оптимизационным приором) — так что появляется контрфактический сценарий. Это стоит базисных пунктов на рандомизированном срезе, и это единственный способ доказуемо подтвердить, что остальные 95% потока роутятся хорошо.
Итого стек: честный по задержке консолидированный стакан; выпуклый water-fill по чистым маржинальным издержкам с измеренными параметрами испарения и токсичности; ограниченный по балансу быстрый цикл, чьи теневые цены управляют учитывающим издержки трансфера медленным циклом; пассивное размещение, учитывающее очереди и межплощадочный информационный поток; и рандомизированный, основанный на маркаутах TCA, возвращающий каждый параметр обратно в систему. Ни один из этих компонентов по отдельности не сложен. Сложна система целиком — потому что в крипте, в отличие от акций, ни один регулятор не построил за вас ни один из этих слоев, а рынок берет 2 б.п. с каждого дочернего ордера, всегда, пока вы не построите его сами.
Авторы
Инженер торговых систем
Разработка торговых ботов с 2017 года: межбиржевой арбитраж (подключал до 30 бирж), парный арбитраж на коинтеграции между спотом и фьючерсами, скальпинг, фронтраннинг, торговля по новостям, сентиментный анализ, трендовые алгоритмы, а также алгоритмы управления и балансировки портфелей. Делает выставление ордеров до 1 мс, warehouse для big data, бэктестинг-движки, AI-агентов и интерфейсы для ботов (в т.ч. open-source profitmaker.cc). Стек: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, архитектура.