Перейти к содержимому

Глава 273: LIT Трансформер для моделирования книги заявок

1. Введение

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

Традиционные подходы к моделированию LOB представляют книгу в виде плоского вектора признаков: складывают топ-N уровней бид и аск, возможно добавляют признаки недавних сделок и подают всё в LSTM или полносвязную сеть. Такое сглаживание уничтожает богатую реляционную структуру, существующую внутри каждой стороны книги и между книгой и потоком сделок.

Архитектура LIT (Limit-order-book Informed Transformer) устраняет эти ограничения, вводя три специализированных компонента:

  1. LOB-энкодер — модуль самовнимания, работающий по ценовым уровням и обучающийся определять, какие уровни несут наибольшую прогностическую информацию.
  2. Энкодер потока сделок — модуль темпорального внимания, обрабатывающий поток недавних сделок, захватывающий моментум, паттерны агрессора и эффекты кластеризации.
  3. Трансформер слияния — механизм перекрёстного внимания, позволяющий представлениям LOB и потока сделок взаимодействовать, создавая совместное вложение, из которого голова предсказания прогнозирует направление средней цены.

Данная глава разрабатывает математические основы LIT, реализует полный прототип на Rust с реальными рыночными данными Bybit и демонстрирует, как архитектура обрабатывает живые книги заявок и потоки сделок BTCUSDT.

2. Математические основы

2.1 Обозначения

Пусть снимок LOB в момент времени $t$ состоит из $L$ ценовых уровней на каждой стороне. Для уровня $i$ на стороне бид имеем $(p_i^b, q_i^b)$ (цена, объём) и аналогично $(p_i^a, q_i^a)$ на стороне аск. Мы складываем их в матрицу:

$$\mathbf{X}^{\text{LOB}} \in \mathbb{R}^{2L \times d_{\text{lob}}}$$

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

Для потока сделок пусть $K$ последних сделок представлены как:

$$\mathbf{X}^{\text{trade}} \in \mathbb{R}^{K \times d_{\text{trade}}}$$

где каждая строка кодирует цену сделки, размер, сторону агрессора и время между сделками.

2.2 LOB-информированное самовнимание

Стандартное многоголовое самовнимание вычисляет:

$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V$$

Для LOB-энкодера запросы, ключи и значения получаются из вложений уровней:

$$Q = \mathbf{X}^{\text{LOB}} W_Q, \quad K = \mathbf{X}^{\text{LOB}} W_K, \quad V = \mathbf{X}^{\text{LOB}} W_V$$

Мы дополняем оценки внимания позиционным смещением, кодирующим относительное расстояние между ценовыми уровнями:

$$A_{ij} = \frac{(Q_i)(K_j)^\top}{\sqrt{d_k}} + b(|i - j|)$$

где $b(\cdot)$ — обучаемое относительное позиционное смещение. Это смещение позволяет модели понимать, что соседние ценовые уровни имеют более сильную структурную связь, чем удалённые. Дополнительно мы добавляем индикатор стороны для различения уровней бид и аск, позволяя модели обучаться асимметричным паттернам, таким как абсорбция на стороне бид или айсберг-заявки на стороне аск.

2.3 Темпоральное внимание потока сделок

Энкодер потока сделок применяет каузальное самовнимание по последовательности недавних сделок:

$$Q^t = \mathbf{X}^{\text{trade}} W_Q^t, \quad K^t = \mathbf{X}^{\text{trade}} W_K^t, \quad V^t = \mathbf{X}^{\text{trade}} W_V^t$$

Каузальная маска гарантирует, что каждая сделка может обращать внимание только на себя и более ранние сделки:

$$M_{ij} = \begin{cases} 0 & \text{если } i \geq j \ -\infty & \text{если } i < j \end{cases}$$

Темпоральное кодирование использует синусоидальные функции от времени между сделками вместо фиксированных позиционных индексов, отражая нерегулярный характер поступления сделок:

$$\text{TE}(t_k) = \left[\sin(\omega_1 \Delta t_k), \cos(\omega_1 \Delta t_k), \ldots, \sin(\omega_{d/2} \Delta t_k), \cos(\omega_{d/2} \Delta t_k)\right]$$

где $\Delta t_k = t_k - t_{k-1}$ — время между сделками, а $\omega_j$ — обучаемые частоты.

2.4 Перекрёстное внимание слияния

Трансформер слияния позволяет представлениям LOB и сделок обмениваться информацией через перекрёстное внимание. Пусть $\mathbf{H}^{\text{LOB}}$ и $\mathbf{H}^{\text{trade}}$ обозначают выходы соответствующих энкодеров. Мы вычисляем две операции перекрёстного внимания:

Внимание сделки-к-LOB (поток сделок запрашивает LOB):

$$\text{CrossAttn}_1 = \text{softmax}\left(\frac{(\mathbf{H}^{\text{trade}} W_Q^c)(\mathbf{H}^{\text{LOB}} W_K^c)^\top}{\sqrt{d_k}}\right) \mathbf{H}^{\text{LOB}} W_V^c$$

Внимание LOB-к-сделкам (LOB запрашивает поток сделок):

$$\text{CrossAttn}_2 = \text{softmax}\left(\frac{(\mathbf{H}^{\text{LOB}} \hat{W}_Q^c)(\mathbf{H}^{\text{trade}} \hat{W}_K^c)^\top}{\sqrt{d_k}}\right) \mathbf{H}^{\text{trade}} \hat{W}_V^c$$

Объединённое представление формируется путём конкатенации и проекции:

$$\mathbf{H}^{\text{fused}} = W_{\text{proj}} \cdot [\text{pool}(\text{CrossAttn}_1) | \text{pool}(\text{CrossAttn}_2)]$$

где $\text{pool}(\cdot)$ обозначает усреднение по измерению последовательности.

2.5 Голова предсказания

Голова предсказания отображает объединённое представление в распределение вероятностей по трём классам: цена вверх, цена вниз и цена стационарна.

$$\hat{y} = \text{softmax}(W_2 \cdot \text{ReLU}(W_1 \cdot \mathbf{H}^{\text{fused}} + b_1) + b_2)$$

Модель обучается с функцией потерь перекрёстной энтропии:

$$\mathcal{L} = -\sum_{c \in {\text{up}, \text{down}, \text{stay}}} y_c \log(\hat{y}_c)$$

3. Обзор архитектуры

┌─────────────────────┐
│ Голова предсказания│
│ (3 класса) │
└──────────┬──────────┘
┌──────────┴──────────┐
│ Трансформер слияния │
│ (Перекрёстное вним.)│
└──┬───────────────┬──┘
│ │
┌──────────┴──┐ ┌──────┴──────────┐
│ LOB-энкодер │ │ Энкодер потока │
│ (Самовним.) │ │ сделок (Кауз.) │
└──────┬──────┘ └──────┬───────────┘
│ │
┌─────────┴───────┐ ┌───────┴────────┐
│ LOB-вложение │ │ Вложение сделок│
│ + Поз. кодир. │ │ + Темп. кодир. │
└─────────┬───────┘ └───────┬────────┘
│ │
┌─────────┴───────┐ ┌───────┴────────┐
│ Книга заявок │ │ Недавние сделки│
│ Bybit │ │ Bybit │
└─────────────────┘ └────────────────┘

3.1 LOB-энкодер

LOB-энкодер обрабатывает $2L$ вложений уровней (L уровней бид + L уровней аск). Каждый уровень представлен признаками: расстояние от средней цены, объём, количество заявок и кумулятивный объём. Добавляется обучаемое позиционное вложение уровня вместе с индикатором стороны (бид=0, аск=1). Энкодер применяет $N_{\text{LOB}}$ слоёв многоголового самовнимания с относительным позиционным смещением, описанным в разделе 2.2.

3.2 Энкодер потока сделок

Энкодер потока сделок обрабатывает $K$ недавних сделок. Каждая сделка кодируется признаками: цена относительно средней, размер, сторона агрессора и логарифм времени между сделками. Темпоральное позиционное кодирование на основе времени между сделками заменяет стандартное позиционное кодирование. Энкодер применяет $N_{\text{trade}}$ слоёв каузального многоголового самовнимания.

3.3 Трансформер слияния

Трансформер слияния принимает закодированные представления LOB и сделок, выполняет двунаправленное перекрёстное внимание и создаёт единый объединённый вектор через усреднение и проекцию. Этот вектор захватывает совместное состояние микроструктуры книги заявок и недавней торговой активности.

4. Реализация на Rust

Реализация в rust/src/lib.rs предоставляет:

  • LobEncoder: Самовнимание по уровням книги заявок с относительным позиционным смещением.
  • TradeFlowEncoder: Каузальное самовнимание по недавним торговым событиям.
  • FusionTransformer: Перекрёстное внимание между кодировками LOB и сделок.
  • PredictionHead: Двухслойная полносвязная сеть для предсказания направления цены (3 класса).
  • LitModel: Сквозная обёртка, объединяющая все компоненты.
  • BybitClient: HTTP-клиент для получения снимков книги заявок и недавних сделок с публичного API Bybit.

Ключевые проектные решения в реализации на Rust:

  1. ndarray для тензорных операций: Мы используем ndarray для матричных операций, обеспечивающих эффективные вычисления с поддержкой BLAS без накладных расходов полноценного фреймворка глубокого обучения.
  2. Явное вычисление внимания: Все механизмы внимания реализованы с нуля, делая архитектуру прозрачной и легко модифицируемой.
  3. Блокирующий HTTP для простоты: Библиотека использует reqwest::blocking для API-вызовов, с асинхронным примером, демонстрирующим интеграцию с tokio.

5. Интеграция с данными Bybit

Реализация подключается к публичному REST API Bybit для получения:

  1. Снимков книги заявок: GET /v5/market/orderbook?category=linear&symbol=BTCUSDT&limit=50 возвращает до 50 уровней на каждой стороне.
  2. Недавних сделок: GET /v5/market/recent-trade?category=linear&symbol=BTCUSDT&limit=100 возвращает до 1000 недавних сделок.

Этапы предобработки данных:

  • Нормализация цен: Все цены выражаются относительно средней цены, масштабированные по размеру тика.
  • Нормализация объёмов: Объёмы логарифмически преобразуются и стандартизируются.
  • Кодирование времени: Временные метки сделок преобразуются во время между сделками в миллисекундах, затем кодируются обучаемыми синусоидальными функциями.
  • Упорядочивание уровней: Уровни бид упорядочиваются от лучшего к худшему (по убыванию цены), уровни аск — от лучшего к худшему (по возрастанию цены), затем конкатенируются.

6. Ключевые выводы

  1. Структуросохраняющее кодирование важно. Представление LOB как последовательности ценовых уровней с позиционным кодированием сохраняет присущую структуру, которую уничтожают плоские векторы признаков. Относительное позиционное смещение позволяет модели обучаться тому, что соседние уровни взаимодействуют сильнее.

  2. Раздельные энкодеры для гетерогенных данных. LOB и поток сделок имеют принципиально разные структуры: LOB — это пространственный снимок, а сделки — временная последовательность. Использование специализированных энкодеров с соответствующими паттернами внимания (полное внимание для LOB, каузальное — для сделок) учитывает эти различия.

  3. Перекрёстное внимание обеспечивает слияние информации. Трансформер слияния позволяет модели обнаруживать взаимодействия между состоянием книги и потоком сделок, такие как крупные сделки, поглощающие определённые ценовые уровни, или сигналы дисбаланса, предсказывающие агрессивный поток заявок.

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

  5. Вывод в реальном времени осуществим на Rust. Реализация на Rust достигает задержки вывода на уровне микросекунд для отдельных снимков, что делает её пригодной для живых торговых систем, где каждая микросекунда задержки может влиять на прибыльность.

  6. Архитектура модульна. Каждый компонент (LOB-энкодер, энкодер сделок, слияние, голова предсказания) может быть независимо улучшен или заменён. Например, можно заменить LOB-энкодер на подход на основе CNN или добавить третий энкодер для данных о ставке финансирования.

  7. Дисбаланс классов в предсказании цены. Класс «стационарный» обычно доминирует на коротких горизонтах. Производственные системы должны использовать взвешенную перекрёстную энтропию или фокальную функцию потерь и оценивать качество с помощью сбалансированной точности или коэффициента корреляции Мэтьюза, а не простой точности.