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

Глава 235: VQ-VAE для трейдинга

1. Введение

Векторно-квантованные вариационные автоэнкодеры (VQ-VAE) представляют собой мощный подход к обучению дискретных представлений сложных данных. Изначально предложенные van den Oord и соавторами (2017) для генерации изображений и звука, VQ-VAE предлагают привлекательную модель для финансовых рынков: способность сжимать непрерывные, зашумлённые рыночные данные в конечный набор дискретных “рыночных токенов”.

Ключевая идея заключается в том, что финансовые рынки, несмотря на их кажущуюся сложность, часто демонстрируют повторяющиеся паттерны — фазы консолидации, пробои, возврат к среднему, импульсные движения и панические распродажи. VQ-VAE автоматически учится выявлять эти паттерны, создавая кодовую книгу прототипических рыночных состояний. Каждый торговый день (или окно) отображается на ближайшую запись кодовой книги, фактически создавая дискретный “язык” рыночного поведения.

Такая дискретизация имеет глубокие последствия. После токенизации рыночных данных мы можем применить весь арсенал моделирования дискретных последовательностей — языковые модели, скрытые марковские модели, статистику n-грамм — для предсказания будущих рыночных состояний. Мы можем обнаруживать аномалии как дни, далёкие от всех записей кодовой книги. Мы можем строить интерпретируемые библиотеки паттернов, где каждая запись кодовой книги имеет ясный рыночный смысл.

В этой главе мы разрабатываем полную систему VQ-VAE для трейдинга на Rust с интеграцией данных биржи Bybit для токенизации поведения криптовалютного рынка.

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

2.1 Архитектура VQ-VAE

VQ-VAE состоит из трёх компонентов:

Энкодер $z_e(x) = f_\theta(x)$: Преобразует входные данные $x \in \mathbb{R}^D$ в непрерывное вложение $z_e \in \mathbb{R}^d$.

Кодовая книга $\mathcal{E} = {e_1, e_2, \ldots, e_K} \subset \mathbb{R}^d$: Набор из $K$ обучаемых векторов вложений (записей кодовой книги).

Декодер $\hat{x} = g_\phi(z_q)$: Восстанавливает входные данные из квантованного вложения $z_q$.

2.2 Квантование методом ближайшего соседа

Шаг квантования отображает выход энкодера на ближайшую запись кодовой книги:

$$z_q = e_k, \quad \text{где} \quad k = \arg\min_j |z_e(x) - e_j|_2$$

Это жёсткое присваивание — каждый вход отображается ровно на одну запись кодовой книги. Индекс $k$ служит дискретным представлением (токеном) входных данных.

2.3 Straight-Through оценка градиента

Операция argmin недифференцируема. VQ-VAE использует straight-through estimator для распространения градиентов: при прямом проходе $z_q = e_k$ (ближайшая запись кодовой книги); при обратном проходе градиенты передаются напрямую от входа декодера к выходу энкодера, минуя квантование:

$$\nabla_{z_e} \mathcal{L} \approx \nabla_{z_q} \mathcal{L}$$

Это работает, потому что если энкодер и кодовая книга хорошо обучены, $z_e \approx z_q$, и градиенты приблизительно корректны.

2.4 Функция потерь

Потери VQ-VAE состоят из трёх компонентов:

$$\mathcal{L} = \underbrace{|x - \hat{x}|2^2}{\text{реконструкция}} + \underbrace{|\text{sg}[z_e(x)] - e_k|2^2}{\text{кодовая книга}} + \underbrace{\beta |z_e(x) - \text{sg}[e_k]|2^2}{\text{приверженность}}$$

где $\text{sg}[\cdot]$ обозначает оператор остановки градиента:

  • Потери реконструкции: Обучают энкодер и декодер точно восстанавливать входные данные.
  • Потери кодовой книги: Перемещают записи кодовой книги к выходам энкодера (обновляют только кодовую книгу).
  • Потери приверженности: Побуждают выходы энкодера оставаться близко к записям кодовой книги (обновляют только энкодер). $\beta$ обычно устанавливается равным 0.25.

2.5 Обновления экспоненциальным скользящим средним (EMA)

Вместо оптимизации потерь кодовой книги градиентным спуском, EMA-обновления более стабильны:

$$N_k^{(t)} = \gamma N_k^{(t-1)} + (1 - \gamma) n_k^{(t)}$$

$$m_k^{(t)} = \gamma m_k^{(t-1)} + (1 - \gamma) \sum_{i \in S_k} z_e(x_i)$$

$$e_k^{(t)} = \frac{m_k^{(t)}}{N_k^{(t)}}$$

где $n_k^{(t)}$ — количество выходов энкодера, назначенных записи кодовой книги $k$ в момент $t$, $S_k$ — множество этих входов, а $\gamma$ — коэффициент затухания (обычно 0.99).

2.6 Метрика перплексии

Для измерения использования кодовой книги вычисляем перплексию распределения использования:

$$\text{Перплексия} = \exp\left(-\sum_{k=1}^{K} p_k \log p_k\right)$$

где $p_k$ — доля входов, назначенных записи кодовой книги $k$. Перплексия, равная $K$, означает равномерное использование всех кодов; низкая перплексия указывает на коллапс кодовой книги.

3. VQ-VAE против стандартного VAE

3.1 Дискретные и непрерывные латентные переменные

Стандартные VAE обучают непрерывное латентное пространство $z \sim \mathcal{N}(\mu, \sigma^2)$. VQ-VAE обучает дискретное латентное пространство $z \in {e_1, \ldots, e_K}$. Это различие имеет важные последствия:

СвойствоVAEVQ-VAE
Латентное пространствоНепрерывноеДискретное
РегуляризацияKL-дивергенцияПотери приверженности
АпостериорноеГауссовоКатегориальное (детерм.)
ГенерацияСэмплирование из приораАвторегрессия по кодам
ИнтерпретируемостьНизкаяВысокая (каждый код = паттерн)

3.2 Избежание коллапса апостериорного распределения

Известная проблема VAE — коллапс апостериорного распределения: декодер становится настолько мощным, что игнорирует латентный код, и апостериорное распределение энкодера коллапсирует к приору. Это означает, что латентное пространство не несёт информации.

VQ-VAE избегает этого по конструкции. Декодер получает дискретный код из конечной кодовой книги — если декодер игнорирует этот вход, он может производить только средний выход, что приводит к высоким потерям реконструкции. Дискретное узкое место заставляет значимую информацию проходить через латентное пространство.

3.3 Использование информации

В стандартных VAE аргумент “bits back” показывает, что латентный код несёт не более $\text{KL}(q(z|x) | p(z))$ натов информации. Латентный код VQ-VAE несёт ровно $\log_2 K$ бит на код (при равномерном использовании всех кодов). При $K = 512$ записях кодовой книги это 9 бит на код — достаточно для различения 512 различных рыночных паттернов.

4. Применение в трейдинге

4.1 Токенизация рыночных данных

Наиболее прямое применение VQ-VAE в трейдинге — преобразование непрерывных рыночных данных в дискретные токены. Для заданного окна OHLCV данных (например, 5 последовательных дней) VQ-VAE отображает его в один индекс кодовой книги. Это создаёт последовательность токенов:

$$\text{рыночные данные} \rightarrow [t_{23}, t_{7}, t_{45}, t_{12}, t_{7}, t_{31}, \ldots]$$

где каждый $t_i$ — индекс в обученной кодовой книге. Эту последовательность можно затем анализировать с помощью моделей дискретных последовательностей.

4.2 Построение “рыночных языковых моделей”

Получив последовательности токенов, мы можем обучить авторегрессионные модели предсказывать следующий токен:

$$P(t_{n+1} | t_1, t_2, \ldots, t_n)$$

Это аналогично языковому моделированию, где мы предсказываем следующее слово. “Словарь” — это наша кодовая книга, а “предложения” — последовательности рыночных состояний. Можно применять модели n-грамм, LSTM или Трансформеры.

Если кодовая книга выучила осмысленные паттерны (например, запись 23 = “сильный бычий пробой”), то предсказание “следующее состояние рынка — запись 23 с вероятностью 40%” предоставляет непосредственно применимую информацию.

4.3 Построение библиотеки паттернов

Каждую запись кодовой книги можно визуализировать и интерпретировать, исследуя:

  • Выход декодера $g_\phi(e_k)$: какой “идеальный” паттерн представляет эта запись?
  • Множество реальных рыночных дней, назначенных записи $k$: как выглядят реальные данные?
  • Статистику каждой записи: средний доход, волатильность, характеристики объёма.

Это создаёт автоматическую, основанную на данных библиотеку паттернов. В отличие от ручных технических паттернов (голова-и-плечи, чашка-с-ручкой), VQ-VAE обнаруживает паттерны, которые статистически обоснованы и оптимизированы для качества реконструкции.

4.4 Обнаружение аномалий через расстояние до кодовой книги

Мощное применение — обнаружение аномалий. Для каждого входа $x$ расстояние до ближайшей записи кодовой книги измеряет, насколько хорошо $x$ представлен:

$$d(x) = \min_k |z_e(x) - e_k|_2$$

Если $d(x)$ велико, вход не похож ни на что в кодовой книге — он представляет действительно новое рыночное условие. Это может служить системой раннего предупреждения: когда рынок входит на неисследованную территорию, расстояние до кодовой книги резко возрастает.

Мы можем установить пороги аномалий на основе исторических распределений расстояний. Дни, превышающие 95-й или 99-й перцентиль расстояний до кодовой книги, помечаются как аномальные, вызывая снижение риска или особое внимание.

5. Приор в стиле PixelCNN над дискретными кодами

5.1 Авторегрессионный приор

VQ-VAE обучает энкодер-декодер без приора над латентными кодами. Для генерации новых данных или вычисления правдоподобия нам нужна отдельная модель приора $p(z_1, z_2, \ldots, z_T)$ над последовательностями дискретных кодов.

PixelCNN (van den Oord и соавт., 2016) обеспечивает естественную авторегрессионную факторизацию:

$$p(z_1, \ldots, z_T) = \prod_{t=1}^{T} p(z_t | z_1, \ldots, z_{t-1})$$

Каждый множитель $p(z_t | z_{<t})$ моделируется как категориальное распределение над $K$ записями кодовой книги, параметризованное каузальной нейронной сетью (маскированные свёртки или Трансформер).

5.2 Применение в трейдинге

В контексте трейдинга этот приор захватывает временную динамику рыночных состояний. Обучение на исторических последовательностях токенов позволяет:

  1. Прогнозировать: Вычислить $P(z_{T+1} = k | z_1, \ldots, z_T)$ для каждой записи кодовой книги $k$, давая вероятностный прогноз будущих рыночных состояний.
  2. Симулировать: Сэмплировать целые траектории $z_1, \ldots, z_T$ из приора, декодировать их и получить реалистичные синтетические рыночные сценарии для анализа рисков.
  3. Оценивать: Вычислить логарифм правдоподобия $\log p(z_1, \ldots, z_T)$ наблюдаемых последовательностей для обнаружения смен режимов (резкие падения правдоподобия).

5.3 Заметки по реализации

Для практической торговой системы хорошо работает простой n-граммный или небольшой Трансформер-приор:

  • Биграмм: $p(z_t | z_{t-1})$ — матрица переходов $K \times K$
  • Триграмм: $p(z_t | z_{t-2}, z_{t-1})$ — тензор $K \times K \times K$
  • Трансформер: Полное контекстное окно, обучаемые позиционные кодировки

Биграммный приор особенно интерпретируем: каждый элемент матрицы переходов показывает вероятность перехода из одного рыночного состояния в другое.

6. Обзор реализации

Наша реализация на Rust предоставляет полную систему VQ-VAE, оптимизированную для торговых данных. Рассмотрим ключевые компоненты.

6.1 Энкодер

Энкодер — это простая сеть прямого распространения, отображающая входные признаки (данные OHLCV) в непрерывное вложение:

pub struct Encoder {
pub weights1: Array2<f64>, // input_dim x hidden_dim
pub biases1: Array1<f64>,
pub weights2: Array2<f64>, // hidden_dim x embedding_dim
pub biases2: Array1<f64>,
}

Мы используем активации ReLU. Энкодер сжимает, например, 5-дневное окно OHLCV (25 признаков) в вектор вложения размерности $d$ (например, 16).

6.2 Кодовая книга и квантование

Кодовая книга хранит $K$ векторов вложений. Квантование находит ближайший:

pub fn quantize(&self, z_e: &Array1<f64>) -> (Array1<f64>, usize) {
let mut min_dist = f64::MAX;
let mut min_idx = 0;
for (i, entry) in self.embeddings.iter().enumerate() {
let dist = (z_e - entry).mapv(|x| x * x).sum();
if dist < min_dist {
min_dist = dist;
min_idx = i;
}
}
(self.embeddings[min_idx].clone(), min_idx)
}

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

6.3 Вычисление потерь

Комбинированные потери управляют обучением:

pub fn compute_loss(
&self, x: &Array1<f64>, x_hat: &Array1<f64>,
z_e: &Array1<f64>, z_q: &Array1<f64>, beta: f64,
) -> (f64, f64, f64) {
let recon_loss = (x - x_hat).mapv(|v| v * v).sum();
let codebook_loss = (z_e - z_q).mapv(|v| v * v).sum();
let commitment_loss = (z_e - z_q).mapv(|v| v * v).sum();
(recon_loss, codebook_loss, beta * commitment_loss)
}

Оператор остановки градиента применяется при обратном распространении (не показан в вычислении потерь).

6.4 Обнаружение аномалий

После обучения обнаружение аномалий просто — вычисляем минимальное расстояние до кодовой книги для каждой новой точки данных и сравниваем с историческими порогами:

pub fn anomaly_score(&self, x: &Array1<f64>) -> f64 {
let z_e = self.encoder.forward(x);
let (_, _, min_dist) = self.codebook.quantize_with_distance(&z_e);
min_dist
}

7. Интеграция данных Bybit

Наша реализация получает реальные рыночные данные через публичный API Bybit. Эндпоинт https://api.bybit.com/v5/market/kline предоставляет исторические данные OHLCV для криптовалютных пар.

7.1 Получение данных

Мы запрашиваем дневные свечи для BTCUSDT и нормализуем данные:

  • Open, High, Low, Close: Процентные изменения от предыдущего закрытия
  • Volume: Логарифмическое преобразование и z-нормализация

Эта нормализация гарантирует, что VQ-VAE обучается паттернам формы, а не абсолютным уровням цен.

7.2 Формирование окон

Мы создаём скользящие окна последовательных дней (например, 5 дней), разворачивая каждое окно в один вектор признаков. Каждое окно становится одной точкой данных для VQ-VAE:

$$x = [\Delta o_1, \Delta h_1, \Delta l_1, \Delta c_1, v_1, \ldots, \Delta o_5, \Delta h_5, \Delta l_5, \Delta c_5, v_5]$$

7.3 Конвейер анализа

После обучения конвейер:

  1. Назначает каждое окно записи кодовой книги
  2. Вычисляет статистику использования кодовой книги и перплексию
  3. Выявляет аномальные окна с высокими расстояниями до кодовой книги
  4. Выводит последовательность токенов для последующего моделирования

8. Дискретные факторные модели и обнаружение рыночных режимов

8.1 VQ-VAE как факторная модель

Традиционные факторные модели в финансах опираются на непрерывные латентные представления. VQ-VAE предлагает привлекательную альтернативу, обучая дискретное латентное пространство через векторное квантование. В этой интерпретации каждая запись кодовой книги представляет прототипическое рыночное условие — режим роста, кризисный режим, режим низкой волатильности и кэрри и так далее. Вместо того чтобы требовать от трейдера заранее определять эти режимы (как в скрытых марковских моделях), VQ-VAE обучает их непосредственно из данных.

При $K$ записях кодовой книги VQ-VAE передаёт ровно $\log_2 K$ бит информации через узкое место. Для $K = 8$ это 3 бита на наблюдение — экстремальное сжатие, заставляющее модель захватывать только самые значимые особенности рыночного поведения. Это сжатие действует как мощный регуляризатор, предотвращая переобучение на шуме.

8.2 Кластеризация рыночных состояний

В отличие от кластеризации k-means, применённой непосредственно к признакам, VQ-VAE обучает нелинейное кодирование перед кластеризацией. Энкодер отображает сырые рыночные признаки (доходности, волатильность, объём, корреляции) в пространство представлений, где евклидово расстояние осмыслено. Это позволяет VQ-VAE обнаруживать режимы, невидимые для линейных методов.

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

8.3 Генерация режимно-специфичных сценариев

После обучения VQ-VAE позволяет генерировать сценарии, обусловленные режимом:

  1. Выбрать целевой режим $k$
  2. Подать соответствующую запись кодовой книги $e_k$ на декодер
  3. Добавить малые возмущения для генерации разнообразных сценариев внутри этого режима
  4. Использовать сгенерированные сценарии для стресс-тестирования или симуляции Монте-Карло

Это особенно ценно для управления рисками: “Как выглядит мой портфель, если мы войдём в Режим 1 (кризис)?” Декодер производит реалистичные рыночные сценарии, согласованные с историческими кризисными периодами, без необходимости вручную создавать стресс-сценарии.

8.4 Построение портфеля, обусловленного режимом

Назначения режимов позволяют строить условные портфельные стратегии:

  • Оценивать ожидаемые доходности и ковариационные матрицы для каждого режима отдельно
  • Использовать текущее назначение режима для выбора подходящих оценок
  • Строить оптимальные по mean-variance портфели, обусловленные обнаруженным режимом
  • Вероятности перехода между режимами информируют размер позиций и хеджирование

9. Иерархический VQ-VAE

9.1 Многомасштабные рыночные представления

Рынки функционируют на нескольких временных масштабах одновременно. Иерархический VQ-VAE использует несколько уровней квантования для их захвата:

  • Уровень 1 (грубый): Широкий рыночный режим (бычий/медвежий/боковой) — меняется в течение недель/месяцев
  • Уровень 2 (тонкий): Состояние микроструктуры (трендовый/возвратный/волатильный) — меняется в течение дней
  • Уровень 3 (тончайший): Внутридневной паттерн (моментум/реверс/пробой) — меняется в течение часов

Каждый уровень имеет собственную кодовую книгу. Грубый уровень захватывает медленно меняющиеся макро-факторы, а тонкие уровни — быстро меняющиеся тактические сигналы.

9.2 Иерархическая архитектура

В иерархическом VQ-VAE энкодер создаёт представления на нескольких разрешениях. Верхний уровень кодирует глобальную структуру; каждый последующий уровень кодирует остаточные детали, не захваченные более грубыми уровнями. Такая декомпозиция естественно отделяет сигнал от шума.

9.3 Трейдинг с иерархическими кодами

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

  • Стратегическая аллокация на основе кодов Уровня 1 (ежемесячная ребалансировка)
  • Тактические наклоны на основе кодов Уровня 2 (еженедельные корректировки)
  • Выбор времени исполнения на основе кодов Уровня 3 (внутридневные решения)

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

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

  1. VQ-VAE дискретизирует рыночные данные в конечный набор выученных паттернов (записей кодовой книги), создавая “словарь” рыночных состояний.

  2. Дискретные представления избегают коллапса апостериорного распределения — распространённой проблемы стандартных VAE, при которой латентное пространство игнорируется.

  3. EMA-обновления кодовой книги более стабильны, чем градиентная оптимизация, и не требуют отдельной скорости обучения.

  4. Перплексия кодовой книги измеряет, сколько кодов активно используется. Низкая перплексия указывает на коллапс кодовой книги; стремитесь к перплексии, близкой к $K$.

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

  6. Последовательности токенов позволяют языковое моделирование — после токенизации рыночных данных авторегрессионные модели могут предсказывать будущие рыночные состояния.

  7. Библиотека паттернов интерпретируема — каждую запись кодовой книги можно декодировать и проанализировать, чтобы понять, какой рыночный паттерн она представляет.

  8. Вес потерь приверженности $\beta$ контролирует баланс между качеством реконструкции и использованием кодовой книги. Типичные значения от 0.1 до 1.0.

  9. Размер кодовой книги $K$ определяет гранулярность дискретизации. Слишком мало записей теряет детали; слишком много приводит к недоиспользованию. Начните с 32-128 для дневных рыночных данных.

  10. VQ-VAE — это фундамент для более продвинутых моделей. Дискретные коды могут питать Трансформеры, HMM или агентов обучения с подкреплением в качестве компактных представлений состояний.

Литература

  • van den Oord, A., Vinyals, O., & Kavukcuoglu, K. (2017). Neural Discrete Representation Learning. NeurIPS.
  • van den Oord, A., et al. (2016). Conditional Image Generation with PixelCNN Decoders. NeurIPS.
  • Razavi, A., van den Oord, A., & Vinyals, O. (2019). Generating Diverse High-Fidelity Images with VQ-VAE-2. NeurIPS.
  • Roy, A., et al. (2018). Theory and Experiments on Vector Quantized Autoencoders. arXiv:1805.11063.