GNN, трансформеры и RL для арбитража: когда нейросети учатся торговать

MarketMaker.cc Team
Количественные исследования и стратегии

MarketMaker.cc Team
Количественные исследования и стратегии
Представьте шахматного гроссмейстера, который вместо доски видит десять бирж с сотнями торговых пар, а вместо 32 фигур — тысячи ордеров, обновляющихся каждую миллисекунду. Фигуры постоянно появляются и исчезают, правила меняются на ходу, а за неверный ход вы платите не проигрышем партии, а реальными деньгами. Классические алгоритмы вроде Bellman-Ford честно обходят граф, но к моменту, когда они находят прибыльный цикл, окно возможности уже закрылось. Нужен другой подход — не алгоритмический, а обучаемый.
В этой статье — пятой части серии «Сложные цепочки арбитража между фьючерсами и спотом» — мы разбираем, как современные методы ML превращают хаотичный мультибиржевой рынок в структурированную задачу. Графовые нейросети находят арбитражные возможности с F1=0.90. Трансформеры сливают данные с десятков бирж через механизм внимания. RL-агенты обгоняют rule-based ботов в 12 раз. И всё это можно запустить на Rust с inference менее 8 мс.
Ландшафт ML-подходов для обнаружения и исполнения арбитражных стратегий: от графовых нейросетей до эволюционных алгоритмов.
Мультибиржевой крипторынок — это граф по своей природе. Узлы — активы (BTC, ETH, SOL) или пары «актив-биржа». Рёбра — торговые связи, взвешенные спредами, объёмами, комиссиями и задержками. Арбитражные возможности — прибыльные циклы в этом графе.
Классический Bellman-Ford решает задачу за O(V*E). Graph Neural Networks (GNN) подходят иначе: вместо перебора циклов они учатся распознавать паттерны, предшествующие арбитражным возможностям. Это как разница между перебором всех маршрутов на карте и «чутьём» таксиста, который знает, где сейчас будет пробка.
Главный результат — масштабируемый фреймворк на основе GraphSAGE с кастомным модулем edge fusion, протестированный на реальных данных с KuCoin, Gate.io, Huobi, Bitget и MEXC по шести активам. Цифры:
GraphSAGE с edge fusion: узлы агрегируют информацию от соседей, модуль слияния рёбер классифицирует каждое ребро как потенциальную арбитражную возможность.
GraphSAGE проходит по графу в несколько слоёв. На каждом слое узел агрегирует информацию от соседей и обновляет своё представление. Модуль edge fusion берёт представления двух узлов, конкатенирует с признаками ребра и через MLP выдаёт вероятность арбитража:
use burn::prelude::*;
use burn::nn::{Linear, LinearConfig, Relu};
#[derive(Module, Debug)]
pub struct EdgeFusionModule<B: Backend> {
fc1: Linear<B>,
fc2: Linear<B>,
fc_out: Linear<B>,
relu: Relu,
}
impl<B: Backend> EdgeFusionModule<B> {
/// Предсказывает вероятность арбитража для ребра (u, v)
pub fn forward(
&self,
h_u: Tensor<B, 2>, // Эмбеддинг узла u
h_v: Tensor<B, 2>, // Эмбеддинг узла v
e_uv: Tensor<B, 2>, // Признаки ребра
) -> Tensor<B, 2> {
let fused = Tensor::cat(vec![h_u, h_v, e_uv], 1);
let x = self.relu.forward(self.fc1.forward(fused));
let x = self.relu.forward(self.fc2.forward(x));
self.fc_out.forward(x).sigmoid()
}
}
Ключевое преимущество — индуктивное обучение. Классические GNN привязаны к конкретному графу: добавился новый токен — переобучай. GraphSAGE учится генерировать эмбеддинги через агрегацию соседей, поэтому новый узел получит осмысленное представление без переобучения. Для криптомира, где каждую неделю появляются новые токены, это критично.
Статический граф — упрощение. Рынок постоянно меняется: корреляции дрейфуют, ликвидность мигрирует, пары появляются и исчезают. Temporal Graph Networks (TGN) моделируют эту динамику.
Каждый узел имеет память — вектор, обновляемый при каждом событии через GRU. По обновлённой памяти строятся временные эмбеддинги через graph attention с учётом давности взаимодействий. Узел, торговавшийся минуту назад, влияет сильнее, чем тот, чья последняя сделка была час назад.
Temporal Graph Network отслеживает эволюцию рыночного графа: память узлов обновляется при каждом событии, а временное внимание взвешивает соседей по давности.
Практическая ценность для арбитража — обнаружение смены режима. Когда ранее стабильный спред BTC между Binance и Coinbase вдруг начинает вести себя иначе, TGN замечает это через изменение паттернов обновления памяти — раннее предупреждение о новой возможности или опасности старой стратегии.
Элегантный бонус: GNN-автокодировщик, обученный реконструировать «нормальные» веса рёбер, автоматически находит ценовые дислокации — потенциальные арбитражи — как аномалии с высокой ошибкой реконструкции.
Если GNN работает с структурой рынка, то трансформеры работают с потоками данных. Multi-head self-attention захватывает зависимости между активами и биржами без необходимости явно указывать, кто на кого влияет.
Архитектура для кросс-биржевого арбитража: у каждой биржи свой энкодер (стакан, сделки, funding rate → вектор). Затем кросс-биржевое внимание позволяет одной бирже «смотреть» на все остальные:
Q = W_Q * x_target_exchange
K = W_K * concat(x_binance, x_coinbase, x_kraken, ...)
V = W_V * concat(x_binance, x_coinbase, x_kraken, ...)
fused = softmax(Q * K^T / sqrt(d_k)) * V
Веса внимания показывают, какие биржи наиболее информативны для предсказания цены на целевой бирже. Резкий рост attention_weight между KuCoin и Gate.io — сигнал о возможном арбитраже.
Механизм кросс-биржевого внимания: каждая биржа «смотрит» на все остальные. Веса внимания визуализируют информационные потоки между площадками.
Temporal Fusion Transformer (TFT) с GNN — гибрид TFT-GNN — показал лучшие результаты в прогнозировании цен, превзойдя standalone TFT в 11 из 12 оценённых периодов.
TFT разделяет входные данные на три категории: статические ковариаты (идентификаторы бирж, комиссии), известные будущие (время суток, обновления funding rate) и наблюдаемые прошлые (стакан, спреды, объёмы). Каждая проходит через Variable Selection Network, автоматически определяющую важность признаков.
Выходной слой предсказывает квантили спреда — не точечный прогноз, а 10-й, 50-й и 90-й перцентили. «Медианный спред — 0.3%, но с вероятностью 10% он будет ниже 0.05%» — для управления рисками бесценно.
Для базисного арбитража — архитектура с перекрёстным вниманием. Спотовый энкодер обрабатывает стакан + сделки + on-chain данные, фьючерсный — стакан + funding rate + open interest. Перекрёстное внимание учится ловить моменты рассинхронизации — окна для базисного арбитража.
/// Конфигурация cross-attention модуля спот-фьючерсы
pub struct SpotFuturesCrossAttention {
spot_encoder: TransformerEncoder, // стакан + on-chain
futures_encoder: TransformerEncoder, // стакан + funding + OI
spot_to_futures_attn: MultiHeadAttention,
futures_to_spot_attn: MultiHeadAttention,
basis_head: BasisPredictionHead, // траектория базиса + CI
}
LSTM-модели для спот-фьючерсного арбитража на индексах уже достигают MAPE 0.70% и доходности 58.18%. Трансформеры с cross-attention обещают улучшение за счёт захвата нелинейных зависимостей.
Reinforcement Learning естественно ложится на задачу арбитража. Состояние — стаканы, позиции, балансы. Действие — что торговать, на какой бирже, объём. Награда — прибыль/убыток.
Deep Q-Network подходит для дискретных действий: купить/продать/ждать. DQN-фреймворк для Bitcoin, переключающийся между пятью стратегиями (RSI, SMA Crossover, Bollinger Bands, Momentum, VWAP Reversion), пережил ноябрьский крах 2025 с +4.7% доходности против -11% у рынка.
Важные улучшения: Prioritized Experience Replay (фокус на удивительных переходах), Dueling DQN (разделение value/advantage), Double DQN (снижение переоценки Q-значений в шумной среде).
Когда нужны точные размеры ордеров и оптимальный тайминг, Soft Actor-Critic (SAC) — непрерывные действия плюс регуляризация энтропией для исследования. SAC с LSTM демонстрирует превосходную риск-скорректированную доходность и превосходит бенчмарки Modern Portfolio Theory.
Но самый впечатляющий результат — мультиагентное RL для конкурентного арбитража на DEX. Три специализированных агента:
Агенты работают в общей среде и обмениваются наблюдениями через канал коммуникации. Результат: 142% годовых против 12% у rule-based ботов. Прочитайте ещё раз. Это не баг в бэктесте — это координация специализированных агентов, находящих возможности, которые человеческий эксперт даже не рассмотрит.
Мультиагентное RL: специализированные агенты, работающие вместе, достигают доходности, невозможной для одностратегийных систем.
Стандартная награда «прибыль/убыток» ведёт к риск-ищущему поведению. Решение — Differential Sharpe Ratio как функция награды: мгновенная оценка вклада сделки в Sharpe ratio портфеля. Агент учится зарабатывать стабильно.
Ещё лучше — мульти-наградный подход: три агента с разными наградами (логарифмические доходности, Differential Sharpe, максимальная просадка) объединяются в единую политику. Оптимист, пессимист и прагматик в одном лице.
Гауссовские процессы (GP) моделируют кривую базиса (разница спот-фьючерс) как функцию от времени до экспирации, funding rate и объёмов — с калиброванными интервалами неопределённости. Ядро комбинирует SE-компоненту (гладкие тренды), периодическую (цикличность funding rate) и шумовую.
GP моделирует кривую базиса с доверительными интервалами. Выход за пределы — сигнал для арбитража.
Торговое правило: когда наблюдаемый базис выходит за доверительный интервал GP — арбитражная возможность. GP posterior variance автоматически увеличивается для out-of-distribution входов — встроенная мера риска.
Bayesian Online Changepoint Detection обнаруживает смену режима в реальном времени. На каждом шаге поддерживает распределение run length — времени с последней точки разрыва. Применение к NASDAQ order flow показало значительно более высокую точность в предсказании ценовых шоков.
/// Детектор смены режима на основе BOCPD
pub struct BocpdDetector {
lambda: f64, // P(changepoint) = 1/lambda
run_length_probs: Vec<f64>, // Распределение run length
sufficient_stats: Vec<SufficientStats>,
}
impl BocpdDetector {
/// Возвращает true при обнаружении смены режима
pub fn update(&mut self, spread: f64) -> bool {
let hazard = 1.0 / self.lambda;
let predictive: Vec<f64> = self.sufficient_stats.iter()
.map(|s| s.predictive_probability(spread))
.collect();
let changepoint_mass: f64 = self.run_length_probs.iter()
.zip(predictive.iter())
.map(|(p, pred)| p * pred * hazard)
.sum();
let growth: Vec<f64> = self.run_length_probs.iter()
.zip(predictive.iter())
.map(|(p, pred)| p * pred * (1.0 - hazard))
.collect();
let total = changepoint_mass + growth.iter().sum::<f64>();
changepoint_mass / total > 0.5
}
}
Для арбитража: обнаружил смену режима → приостанови стратегию → обнови параметры → продолжай.
Когда есть несколько арбитражных маршрутов, Thompson Sampling балансирует эксплуатацию и исследование: для каждого маршрута сэмплирует из Beta(alpha, beta) и выбирает наибольший. Прибыльный маршрут → alpha += 1, убыточный → beta += 1. Неопределённые маршруты дают высокую дисперсию (обеспечивая исследование), проверенные — стабильные сэмплы (обеспечивая эксплуатацию). Никакого ручного epsilon-greedy.
Автокодировщик, обученный на «нормальных» состояниях рынка (без арбитража), выдаёт высокую ошибку реконструкции при аномалии = потенциальной возможности. Вариационный автокодировщик (VAE) ещё мощнее: генерирует синтетические «нормальные» состояния — когда реальное поведение выходит за границы, аномалия обнаружена. Комбинация автокодировщика с Isolation Forest достигает 0.98 accuracy.
Conditional VAE учит поведение пары в контексте режима: спред, нормальный для выходных, может быть аномальным в лондонскую сессию.
Методы статистического контроля процессов идеально подходят для мониторинга спредов. CUSUM накапливает кумулятивную сумму отклонений — лучше для устойчивых арбитражных возможностей. EWMA экспоненциально взвешивает недавние наблюдения — лучше для градуального дрейфа.
Мы запускаем оба параллельно: CUSUM сработал — устойчивая возможность. EWMA сработал — режим меняется, обнови параметры. Оба — сигнал высокой уверенности.
Параллельный мониторинг: CUSUM ловит устойчивые сдвиги, EWMA — градуальный дрейф. Совместное срабатывание = высокая уверенность.
10 бирж, 50 маршрутов — какой выбрать сейчас? Multi-Armed Bandits дают теоретически обоснованный ответ. UCB выбирает маршрут с наивысшим оптимистичным скором. Contextual Bandits (LinUCB) учитывают контекст — волатильность, время суток, ликвидность:
/// LinUCB для выбора маршрута с учётом контекста
pub struct LinUcbRouteSelector {
routes: Vec<LinUcbArm>,
alpha: f64,
}
impl LinUcbRouteSelector {
pub fn select(&self, context: &[f64]) -> usize {
self.routes.iter()
.enumerate()
.map(|(i, arm)| {
let theta = arm.a_inv.dot(&arm.b);
let x = ndarray::Array1::from_vec(context.to_vec());
let mean = theta.dot(&x);
let uncertainty = self.alpha
* (x.dot(&arm.a_inv.dot(&x))).sqrt();
(i, mean + uncertainty)
})
.max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
.unwrap().0
}
}
Алгоритм экспоненциальных весов (Hedge) смешивает стратегии: каждая — «эксперт» (треугольный арбитраж, кросс-биржевой, базисный). Веса обновляются: w_i *= exp(-epsilon * cost_i). Гарантия: регрет O(sqrt(T * ln(N))). Fixed-Share вариант восстанавливается при смене режима.
FTRL — стабильнее: вместо следования за лидером добавляет регуляризатор. Optimistic FTRL использует подсказки от ML-моделей для пре-адаптации.
MAML учит не конкретный режим, а инициализацию, быстро адаптирующуюся к любому новому:
theta* = argmin_theta sum_task L(theta - alpha * grad L(theta, D_train), D_test)
Каждый «таск» — рыночный режим. Результат: модель, которая за 5-10 градиентных шагов адаптируется к новому режиму вместо полного переобучения.
Генетическое программирование (GP) эволюционирует саму структуру правила. Индивидуум — дерево из операторов и рыночных переменных:
IF (spread > 0.002 * volatility AND volume > SMA(volume, 20))
THEN BUY_SIZE = min(spread * 1000, max_position)
ELSE HOLD
Financial GP на внутридневных тиковых данных показал 3-кратное улучшение прибыльности над наивными правилами. Инициализируем 500-2000 случайных правил, оцениваем фитнес (Sharpe ratio), скрещиваем, мутируем, отбираем элиту. Через 100 поколений — правила, которые ни один человек не придумал бы.
Grammatical Evolution улучшает GP, разделяя пространство поиска и решения через формальную грамматику. Исследования подтверждают: GE генерирует более прибыльные, робастные и простые стратегии.
Арбитраж — всегда компромисс. NSGA-II находит Парето-оптимальное множество по нескольким целям: максимизация прибыли, минимизация просадки, минимизация latency, минимизация заблокированного капитала.
NSGA-II: каждая точка — стратегия, не уступающая другим по всем целям одновременно. Трейдер выбирает точку по профилю риска.
Результат — не одна «лучшая» стратегия, а фронт от агрессивных до консервативных. Эмпирические данные подтверждают: NSGA-II генерирует портфели с превосходными характеристиками по сравнению с традиционными моделями.
Реальная мощь — в интеграции. Полный pipeline:
Биржевые данные (WebSocket, REST)
│
▼
┌─────────────────────────┐
│ Feature Engineering │
│ Признаки стакана, │
│ спреды, граф, │
│ CUSUM/EWMA мониторинг │
└─────────────────────────┘
│ │
▼ ▼
┌────────────┐ ┌────────────┐
│ Аномалии │ │ GNN-детекция│
│ Autoencoder│ │ GraphSAGE + │
│ + IForest │ │ Temporal GNN│
└────────────┘ └────────────┘
│ │
▼ ▼
┌─────────────────────────┐
│ Signal Fusion │
│ Transformer / TFT │
│ Cross-exchange + │
│ spot-futures attention │
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ Выбор стратегии │
│ Thompson Sampling + │
│ Exp. Weights + BOCPD │
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ Исполнение: RL (SAC/PPO)│
│ Размер, тайминг │
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ Риск: байесовский │
│ сайзинг + GP-границы │
└─────────────────────────┘
Бюджет задержки для всего пайплайна:
| Компонент | Задержка | Подход |
|---|---|---|
| Приём данных | < 0.1 мс | Zero-copy буферы |
| Feature engineering | < 0.5 мс | Инкрементальные обновления |
| Детекция аномалий | < 1.0 мс | ONNX Runtime |
| GNN inference | < 2.0 мс | ONNX Runtime GPU |
| Transformer fusion | < 2.0 мс | ONNX Runtime GPU (INT8) |
| Выбор стратегии | < 0.1 мс | Pure Rust |
| RL-решение | < 1.0 мс | ONNX Runtime |
| Отправка ордера | < 0.5 мс | Pre-established connections |
| ИТОГО | < 7.5 мс |
Менее 8 миллисекунд от данных до ордера с полным ML-pipeline. На Rust + ONNX Runtime это реалистично.
Burn (рекомендация для продакшена) — чистый Rust, поддерживает обучение и inference, работает на CPU/CUDA/Vulkan/WebGPU/WASM:
use burn::prelude::*;
#[derive(Module, Debug)]
pub struct ArbitrageModel<B: Backend> {
lstm: Lstm<B>,
attention: MultiHeadAttention<B>,
fc1: Linear<B>,
fc2: Linear<B>,
}
ONNX Runtime (ort) — основная рекомендация для inference. Train in Python, deploy in Rust: обучаем в PyTorch, экспортируем в ONNX, загружаем через ort. Inference в 5-10x быстрее Python, sub-millisecond реалистичен, поддержка INT8 квантизации.
Candle (HuggingFace) — минималистичный, хорош для inference трансформеров. tch-rs — привязки к libtorch, полный доступ к PyTorch, но внешняя зависимость.
linfa (scikit-learn на Rust), ndarray (NumPy), statrs (распределения), nalgebra (линейная алгебра), petgraph (графы), argmin (оптимизация).
Сейчас: CUSUM/EWMA (чистый Rust), Isolation Forest (linfa), Thompson Sampling (Beta-Bernoulli).
Среднесрочно: GraphSAGE (Python → ONNX → Rust), BOCPD (чистый Rust + statrs), Autoencoder (ONNX).
Долгосрочно: Transformer fusion, RL execution agent (SAC/PPO), NSGA-II, Temporal Graph Network.
Начните с мониторинга. CUSUM + EWMA на спредах можно запустить за день. Когда система стабильно мониторит 100+ спредов — добавляйте ML.
Train in Python, deploy in Rust. Не обучайте GNN на Rust (пока). PyTorch → ONNX → ort. Лучшее из двух миров.
Квантизация — бесплатный обед. INT8 снижает latency в 2-4x с минимальной потерей точности. Для арбитражных моделей достаточно правильного знака и порядка.
Не забывайте про нестационарность. Модель из января к марту может работать хуже Z-Score. BOCPD + MAML + скользящее переобучение — обязательный минимум.
Логируйте всё. Каждое предсказание, каждое решение, каждый changepoint. Через месяц поймёте, какие модели реально вносят вклад.
Мы рассмотрели арсенал ML-методов: GNN видит структуру рынка, трансформер сливает данные, RL исполняет, байесовские методы управляют неопределённостью, эволюционные алгоритмы открывают стратегии. Каждый решает свою подзадачу, но настоящая мощь — в комбинации.
ML в арбитраже — не серебряная пуля. Это арсенал инструментов, каждый из которых требует понимания, настройки и обслуживания. Но для тех, кто готов инвестировать, разница между 12% и 142% годовых говорит сама за себя.
@software{soloviov2026complexarbitrageml, author = {Soloviov, Eugen}, title = {GNN, трансформеры и RL для арбитража: когда нейросети учатся торговать}, year = {2026}, url = {https://marketmaker.cc/ru/blog/post/complex-arbitrage-ml-approaches}, version = {0.1.0}, description = {Как графовые нейросети, трансформеры, reinforcement learning и байесовские методы создают интегрированную систему для обнаружения и исполнения сложных арбитражных цепочек между фьючерсами и спотом.} }