Vine-копулы в арбитраже: моделирование зависимостей в высоких размерностях
Часть 3 серии "Сложные цепочки арбитража между фьючерсами и спотом"
Представьте себе бальный зал, где танцуют десятки пар. Обычная корреляция скажет вам, что два танцора движутся в одном направлении. Но она не расскажет, синхронизируются ли они только в медленных вальсах или ещё и в быстрых танго, расходятся ли они в моменты кульминации или, наоборот, сближаются именно тогда, когда музыка становится драматичной. Корреляция -- это плоская фотография. А копула -- это полная хореографическая партитура, описывающая структуру совместного движения. Теперь представьте, что вместо двух танцоров у вас четыре, пять, десять криптоактивов, и вам нужно понять, как они все связаны друг с другом, чтобы ловить арбитражные возможности. Именно здесь на сцену выходят vine-копулы -- элегантный способ разложить эту сложную многомерную хореографию на простые парные па.
В этой статье мы разберём, как vine-копулы работают, почему они превосходят классические методы моделирования зависимостей и как их использовать для построения арбитражных стратегий в криптовалютных рынках. Мы пройдём путь от интуитивных аналогий до конкретного кода на Rust.

Что такое копулы и почему они важны
Проблема линейной корреляции
Классическая корреляция Пирсона -- это рабочая лошадка финансового анализа. Но у неё есть фундаментальная проблема: она измеряет только линейную связь между переменными. На криптовалютных рынках, где распределения доходностей имеют тяжёлые хвосты, асимметрию и нелинейные зависимости, корреляция может быть опасно обманчивой.
Вот конкретный пример: корреляция между BTC и ETH может быть 0.7 в обычных условиях. Но что происходит во время краха рынка? Корреляция взлетает до 0.95 -- оба актива падают вместе. А во время бурного роста? Корреляция может упасть до 0.5, потому что альткоины растут непропорционально. Обычная корреляция не способна описать эту асимметрию поведения в хвостах распределения.
Слева: линейная корреляция показывает одно число. Справа: копула раскрывает полную структуру зависимости, включая поведение в экстремальных ситуациях
Копула: отделяем структуру зависимости от маргиналов
Копула (от латинского copulare -- "связывать") -- это многомерная функция распределения, маргинальные распределения которой равномерны на отрезке [0, 1]. Звучит абстрактно? Давайте разберём на пальцах.
Представьте, что у вас есть два актива -- BTC и ETH. Каждый из них имеет свои особенности: BTC может иметь распределение доходностей со скошенностью влево и тяжёлыми хвостами, ETH -- с ещё более тяжёлыми хвостами и другой формой. Это их маргинальные распределения -- индивидуальные характеристики каждого актива.
Но как они связаны между собой? Эта связь -- отдельная сущность, независимая от формы маргинальных распределений. Вот эту связь и описывает копула. Гениальность подхода в том, что мы можем моделировать каждый актив по отдельности (выбрав для каждого наиболее подходящее распределение) и отдельно моделировать структуру их совместного поведения.
Теорема Склара: фундамент копульного подхода
Формальная формулировка
Теорема Склара (Sklar, 1959) -- это краеугольный камень всей теории копул. Она утверждает:
Для любой d-мерной функции распределения F с непрерывными маргиналами F_1, F_2, ..., F_d существует единственная копула C такая, что:
F(x_1, x_2, ..., x_d) = C(F_1(x_1), F_2(x_2), ..., F_d(x_d))
И наоборот: если C -- копула, а F_1, ..., F_d -- одномерные функции распределения, то F, определённая формулой выше, является допустимой совместной функцией распределения.
Почему это революционно для арбитража
Теорема Склара даёт нам три суперспособности:
-
Гибкость маргиналов. Для каждого актива мы можем использовать своё, наиболее подходящее распределение. BTC -- скошенное t-распределение Стьюдента с 4 степенями свободы. ETH -- обобщённое распределение с ещё более тяжёлыми хвостами. SOL -- что-то третье. Каждый актив моделируется отдельно и точно.
-
Точность зависимостей. Нелинейные, асимметричные и хвостовые зависимости описываются именно так, как они есть в данных, а не загоняются в прокрустово ложе линейной корреляции.
-
Условные вероятности. Мы можем вычислить P(Актив_1 недооценён | Актив_2 на уровне x, Актив_3 на уровне y) -- именно то, что нужно для арбитражных сигналов.
Теорема Склара: совместное распределение = копула (структура зависимости) * маргиналы (индивидуальные распределения)
Плотность совместного распределения раскладывается в произведение:
f(x_1, ..., x_d) = c(F_1(x_1), ..., F_d(x_d)) * f_1(x_1) * f_2(x_2) * ... * f_d(x_d)
где c -- плотность копулы, а f_i -- маргинальные плотности. Первый множитель описывает зависимость, остальные -- индивидуальные характеристики.
Семейства копул: какую выбрать и когда
Не все зависимости одинаковы. Разные семейства копул описывают разные типы связей. Рассмотрим основные.
Гауссова копула
C_Gauss(u_1, u_2; rho) = Phi_2(Phi^{-1}(u_1), Phi^{-1}(u_2); rho)
Самая простая и интуитивно понятная. Параметр -- обычная корреляция rho. Но у неё есть критический недостаток: нулевая хвостовая зависимость (lambda_L = lambda_U = 0). Это означает, что модель не способна описать ситуацию, когда два актива одновременно переживают экстремальное падение. Именно этот недостаток стал одной из причин финансового кризиса 2008 года, когда гауссова копула использовалась для оценки CDO.
Для крипторынков, где экстремальные совместные движения -- повседневная реальность, гауссова копула категорически не подходит.
Копула Стьюдента (Student-t)
Два параметра: корреляция rho и степени свободы nu. Ключевое отличие от гауссовой: симметричная хвостовая зависимость (lambda_L = lambda_U > 0). Чем меньше nu, тем тяжелее хвосты. Для крипторынков с nu ~ 3-5 хорошо описывает реальность: криптоактивы падают вместе гораздо чаще, чем предсказывает гауссова модель.
Копула Клейтона (Clayton)
Нижняя хвостовая зависимость: lambda_L = 2^{-1/theta}, верхняя: lambda_U = 0. Идеальна для пар, где главный риск -- совместное падение. Два актива обрушиваются одновременно, но растут независимо -- это именно Клейтон.
Копула Гумбеля (Gumbel)
Зеркальная противоположность Клейтона: нижняя lambda_L = 0, верхняя lambda_U = 2 - 2^{1/theta}. Описывает совместный экстремальный рост. Полезна для коротких позиций в арбитраже.
Сводная таблица свойств
| Копула | Параметры | lambda_L | lambda_U | Симметрия | tau(theta) |
|---|---|---|---|---|---|
| Гауссова | rho in [-1,1] | 0 | 0 | Да | (2/pi)*arcsin(rho) |
| Стьюдента | nu>0, rho | >0 | >0 | Да | (2/pi)*arcsin(rho) |
| Клейтона | theta>0 | 2^{-1/theta} | 0 | Нет | theta/(theta+2) |
| Гумбеля | theta>=1 | 0 | 2-2^{1/theta} | Нет | 1-1/theta |
| Франка | theta!=0 | 0 | 0 | Да | 1+4[D_1(theta)-1]/theta |
Визуализация различных семейств копул: гауссова (симметричная, без хвостов), Клейтона (нижний хвост), Гумбеля (верхний хвост), Стьюдента (оба хвоста)
Хвостовая зависимость: почему это критически важно
Хвостовая зависимость измеряет вероятность совместных экстремальных событий. Нижняя lambda_L -- вероятность, что второй актив обвалится при условии краха первого. Если lambda_L = 0.5, когда один актив падает в нижний 1%, с вероятностью 50% второй тоже окажется в своём нижнем 1%.
Для арбитража это означает: если мы открыли позицию, предполагая расхождение активов, но lambda_L высокая -- они могут обвалиться вместе и хедж не спасёт. Игнорирование хвостовой зависимости -- одна из самых опасных ошибок в арбитраже.

Vine-копулы: декомпозиция на двумерные блоки
Проблема проклятия размерности
Стандартные многомерные копулы (гауссова, Стьюдента) масштабируются на произвольные размерности, но навязывают жёсткую структуру зависимостей. Все пары связаны одинаковым образом -- это редко соответствует реальности. Архимедовы копулы (Клейтон, Гумбель) гибки в двух измерениях, но в многомерном случае один параметр управляет всеми парными зависимостями.
Представьте задачу арбитража с 4 активами: BTC, ETH, SOL и стейблкоин-деривативом. Нам нужно описать C(4,2) = 6 парных зависимостей, причём:
- BTC-ETH могут иметь сильную нижнюю хвостовую зависимость (Клейтон)
- ETH-SOL -- симметричную зависимость (Стьюдент)
- BTC-SOL -- верхнюю хвостовую зависимость (Гумбель)
- Зависимость BTC-SOL может меняться в зависимости от текущего состояния ETH
Ни одна стандартная многомерная копула не может описать такую гетерогенность. Vine-копулы решают эту проблему.
Ключевая идея: дерево парных копул
Vine-копула (виноградная копула, названная так за визуальное сходство графовой структуры с виноградной лозой) раскладывает d-мерную плотность на:
- d маргинальных плотностей
- d(d-1)/2 двумерных (условных) копульных плотностей
Каждая двумерная копула может быть выбрана из любого семейства независимо. Это даёт невероятную гибкость.
Для трёх переменных разложение выглядит так:
f(x_1, x_2, x_3) = f_1(x_1) * f_2(x_2) * f_3(x_3) [маргиналы]
* c_{1,2}(F_1(x_1), F_2(x_2)) [безусловная копула]
* c_{1,3}(F_1(x_1), F_3(x_3)) [безусловная копула]
* c_{2,3|1}(F_{2|1}(x_2|x_1), F_{3|1}(x_3|x_1)) [условная копула]
Первые три множителя -- маргиналы. Следующие два -- безусловные парные копулы. Последний -- условная копула: зависимость между X_2 и X_3 с учётом X_1.
Для четырёх активов (типичная арбитражная когорта)
f(x_1, x_2, x_3, x_4) = [4 маргинала]
* c_{1,2} * c_{2,3} * c_{3,4} [Дерево 1: 3 безусловные пары]
* c_{1,3|2} * c_{2,4|3} [Дерево 2: 2 условные пары]
* c_{1,4|2,3} [Дерево 3: 1 дважды условная пара]
Итого: d(d-1)/2 = 6 двумерных копул для d=4, организованных в d-1 = 3 дерева.
Vine-структура для 4 активов: каждое дерево добавляет новый уровень условных зависимостей, как матрёшка из парных копул
h-функция: сердце vine-копулы
h-функция -- это условная функция распределения, вычисляемая через копулу: h(u_1 | u_2; theta) = dC(u_1, u_2; theta) / du_2. Для каждого семейства копул h-функция имеет свою замкнутую формулу. h-функция рекурсивно применяется через vine-дерево: значения F_{1|3}, F_{2|3} служат входами для копул следующего уровня, позволяя вычислять условные распределения произвольного порядка.
C-Vine, D-Vine, R-Vine: типы vine-структур
C-Vine (каноническая vine)
Структура: звёздообразный граф на каждом уровне. Один "корневой" узел связан со всеми остальными.
Дерево 1: 2 --- 1 --- 3
|
4
Дерево 2: 2,3|1 --- 2,4|1
Дерево 3: 3,4|1,2
Когда использовать: когда один актив доминирует в структуре зависимостей. На крипторынке BTC часто выступает именно таким доминирующим фактором -- все альткоины условно зависимы через свою связь с BTC. C-vine с BTC в качестве корня естественно описывает эту рыночную структуру.
D-Vine (рисуемая vine)
Структура: цепочечный граф. Каждый узел связан максимум с двумя соседями.
Дерево 1: 1 --- 2 --- 3 --- 4
Дерево 2: 1,3|2 --- 2,4|3
Дерево 3: 1,4|2,3
Когда использовать: когда нет одного доминирующего актива, но есть естественная цепочка (например, BTC-ETH-SOL-AVAX, упорядоченные по рыночной капитализации).
R-Vine (регулярная vine)
Наиболее общая структура, включающая C-vine и D-vine как частные случаи. Количество возможных R-vine структур растёт экспоненциально: 24 для d=4, 480 для d=5, ~3.5 * 10^18 для d=10. Этот комбинаторный взрыв мотивирует использование алгоритма Диссманна.
Три типа vine-структур: C-Vine (звезда), D-Vine (цепочка), R-Vine (произвольная). Выбор зависит от характера зависимостей в данных
Алгоритм Диссманна: автоматический выбор структуры
Общий принцип
Алгоритм Диссманна (Dissmann et al., 2013) -- это стандартный метод выбора оптимальной R-vine структуры. Его идея элегантно проста: на каждом уровне дерева мы строим максимальное остовное дерево, используя абсолютные значения тау Кендалла в качестве весов рёбер. Сильнейшие зависимости попадают в нижние деревья, где они моделируются безусловно и точно.
Пошаговый алгоритм
На каждом уровне дерева строим максимальное остовное дерево с весами |tau Кендалла|. Для каждого ребра подбираем оптимальное семейство копулы (минимизация AIC), оцениваем параметры через MLE и вычисляем h-функции для следующего уровня. Узлы дерева j+1 -- это рёбра дерева j, причём применяется условие близости.
Сложность: O(d^2 * T). Для однопараметрических семейств оценка может обойтись без оптимизации -- через формулы связи tau-theta:
Клейтон: theta = 2*tau / (1 - tau)
Гумбель: theta = 1 / (1 - tau)
Гауссова: rho = sin(pi * tau / 2)
Усечение vine-копулы
В высокоразмерных vine-копулах зависимости на верхних деревьях обычно слабые. Усечение заменяет все копулы выше определённого уровня на копулу независимости. Типичный порог: max|tau_e| < 0.05--0.10. На практике основная часть зависимости описывается первыми 2--3 деревьями.
Применение к арбитражу: торговые сигналы
Стратегия C-Vine: один против всех
Стратегия C-vine копулы, разработанная Stübinger et al. (2018) и реализованная в библиотеке ArbitrageLab (Hudson & Thames), -- наиболее широко применяемый vine-копульный подход к статистическому арбитражу.
Концепция: торгуем один "целевой" актив против когорты референсных активов. C-vine естественно представляет зависимость "один против остальных", с целевым активом в качестве корня.
Пайплайн:
Выбор вселенной -> Формирование когорты -> Подгонка vine -> Генерация сигнала -> Исполнение
Формирование когорты
Для d активов в когорте (обычно d = 3 или 4):
-
Преобразуем дневные доходности в псевдо-наблюдения через эмпирическую CDF:
u_{t,i} = rank(r_{t,i}) / (T + 1) -
Выбираем когорту, максимизируя агрегированную зависимость:
Score(когорта) = sum_{пары} |tau_{i,j}|
Условная вероятность как торговый сигнал
Ядро стратегии -- условная вероятность доходности целевого актива при заданных значениях остальных:
h(u_1 | u_2, u_3, u_4) = P(U_1 <= u_1 | U_2 = u_2, U_3 = u_3, U_4 = u_4)
Интерпретация:
- h > 0.5: целевой актив переоценён относительно когорты (шорт)
- h < 0.5: целевой актив недооценён относительно когорты (лонг)
Индекс ошибочной оценки (MPI и CMPI)
MPI (Mispricing Index) -- необработанная условная вероятность h на каждом шаге.
CMPI (Cumulative Mispricing Index) -- демеанированная кумулятивная сумма h:
CMPI_t = sum_{s=1}^{t} (h_s - h_bar)
где h_bar -- скользящее среднее h.
CMPI ведёт себя как mean-reverting спред, аналогично z-score в парном трейдинге. Мы используем его с полосами Боллинджера для генерации сигналов:
mu_hat(t) = среднее CMPI за окно W
sigma_hat(t) = стд. отклонение CMPI за окно W
ШОРТ: CMPI_t > mu_hat(t) + k * sigma_hat(t)
ЛОНГ: CMPI_t < mu_hat(t) - k * sigma_hat(t)
ВЫХОД: CMPI_t пересекает mu_hat(t)
где k -- ширина полосы (обычно k = 1.5--2.0).
Кумулятивный индекс ошибочной оценки (CMPI) с полосами Боллинджера: зелёные стрелки -- вход в лонг, красные -- вход в шорт, серые -- выход
Эмпирические результаты
Stübinger et al. (2018) на данных S&P 500 за 1992--2015 годы получили:
- Годовая доходность: 9.25% после транзакционных издержек
- Коэффициент Шарпа: 1.12
- Максимальная просадка: 6.57%
Для криптовалютных рынков, где волатильность выше, а неэффективности более выражены, потенциал стратегии может быть ещё больше.
Многоногий арбитраж с vine-копулами
Vine-копулы открывают путь к сложным стратегиям: кросс-биржевой арбитраж (BTC/USDT на Binance, OKX, Bybit -- C-vine с самой ликвидной биржей в качестве корня) и базисный трейдинг (спот + фьючерсы разных сроков + ставка финансирования). Vine-копула описывает совместную динамику всей кривой термической структуры и сигнализирует о моментах конвергенции базиса.
Коинтеграция + копулы: сильнее вместе
Зачем объединять оба подхода
| Аспект | Коинтеграция | Копулы |
|---|---|---|
| Тип связи | Линейное долгосрочное равновесие | Общая нелинейная зависимость |
| Распределения | Гауссовы остатки (обычно) | Любые маргиналы |
| Хвосты | Нет моделирования | Явная хвостовая зависимость |
| Многоактивность | Векторная ECM (ограниченная) | Vine-копулы (гибкие) |
| Сигнал | Z-score спреда | Условная вероятность |
Комбинация использует сильные стороны обоих подходов:
- Коинтеграция выявляет пары, которые действительно возвращаются к среднему
- Копулы моделируют нелинейную зависимость точнее
- Совместные сигналы более робастны, чем каждый по отдельности
Пайплайн: коинтеграция для отбора, копулы для торговли
Шаг 1: отбор пар через двухшаговый метод Энгла-Грэнджера и тест KSS (для нелинейной коинтеграции в крипто).
Шаг 2: для пар, прошедших тесты, подбираем копулу по AIC и вычисляем условные вероятности h_{1|2} и h_{2|1}. Правила входа:
ЛОНГ актив 1, ШОРТ актив 2: h_{1|2} < 0.05 И h_{2|1} > 0.95
ШОРТ актив 1, ЛОНГ актив 2: h_{1|2} > 0.95 И h_{2|1} < 0.05
ВЫХОД: h_{1|2} или h_{2|1} пересекают 0.5
Для многоактивных стратегий тест Йохансена выявляет коинтеграционные вектора, которые формируют стационарные спреды, а vine-копула моделирует их совместное распределение.
GARCH-EVT-Copula: количественная оценка экстремальных рисков
Для строгого моделирования рисков применяем трёхступенчатый фреймворк GARCH-EVT-Copula:
Шаг 1: GARCH фильтрует волатильность каждого актива. Для криптовалют с асимметричной волатильностью используем eGARCH, где параметр gamma захватывает "эффект рычага" -- отрицательные шоки увеличивают волатильность сильнее положительных.
Шаг 2: EVT (теория экстремальных значений) подгоняет обобщённое распределение Парето (GPD) к хвостам стандартизированных остатков. Центральную часть оцениваем ядерной оценкой плотности. Это даёт точные маргиналы с корректными хвостами.
Шаг 3: Vine-копула моделирует зависимости между отфильтрованными остатками:
u_{i,t} = F_i(z_{i,t}) [используя GARCH-EVT маргинал]
Подгоняем vine-копулу к {u_{1,t}, ..., u_{d,t}}
Имея подогнанную модель, вычисляем VaR и CVaR через Монте-Карло: генерируем N сценариев из vine-копулы (обратное преобразование Розенблатта), вычисляем P&L портфеля и берём alpha-квантиль. CVaR = среднее потерь за порогом VaR -- когерентная мера риска, более подходящая для арбитража.
Динамические копулы: зависимости, меняющиеся во времени
Финансовые зависимости не статичны -- в периоды паники корреляции взлетают, при бычьем рынке альткоины движутся более независимо. Для описания этой динамики используются три подхода.
Скользящее окно -- простейший метод: переоценка параметров каждые W периодов. Прост, но может давать резкие скачки.
DCC-тип эволюции (Patton, 2006) -- параметр эволюционирует как авторегрессионный процесс:
rho_t = Lambda(omega + beta * rho_{t-1} + alpha * Phi^{-1}(u_{t-1,1}) * Phi^{-1}(u_{t-1,2}))
Марковское переключение режимов -- копула переключается между "нормальным" (низкая зависимость, спред возвращается к среднему) и "кризисным" (высокая зависимость, уменьшаем позиции) режимами.
Практические рекомендации для крипто: окно 90--180 дней, переоценка параметров ежедневно, пересмотр семейств копул еженедельно, мониторинг тау Кендалла на структурные разрывы.
Реализация на Rust: ключевые структуры данных
Трейт BivariateCopula
Центральный элемент архитектуры -- трейт, определяющий интерфейс двумерной копулы:
pub trait BivariateCopula: Send + Sync {
/// CDF копулы: C(u1, u2)
fn cdf(&self, u1: f64, u2: f64) -> f64;
/// Плотность копулы: c(u1, u2)
fn pdf(&self, u1: f64, u2: f64) -> f64;
/// h-функция: h(u1 | u2) = dC(u1, u2)/du2
fn h_function(&self, u1: f64, u2: f64) -> f64;
/// Обратная h-функция: h^{-1}(u1 | u2)
fn h_inverse(&self, u1: f64, u2: f64) -> f64;
/// Логарифм правдоподобия для данных
fn log_likelihood(&self, u1: &[f64], u2: &[f64]) -> f64 {
u1.iter().zip(u2.iter())
.map(|(&a, &b)| self.pdf(a, b).ln())
.sum()
}
/// Тау Кендалла
fn kendall_tau(&self) -> f64;
/// Коэффициенты хвостовой зависимости (нижний, верхний)
fn tail_dependence(&self) -> (f64, f64);
/// Количество параметров
fn n_params(&self) -> usize;
/// AIC
fn aic(&self, u1: &[f64], u2: &[f64]) -> f64 {
-2.0 * self.log_likelihood(u1, u2) + 2.0 * self.n_params() as f64
}
}
Трейт отмечен Send + Sync, что позволяет безопасно использовать копулы в многопоточном контексте -- критически важно для параллельного подбора семейств через rayon.
Реализация копулы Клейтона
Рассмотрим конкретную реализацию для копулы Клейтона -- она наиболее наглядна благодаря замкнутым формулам для h-функции и её обратной:
pub struct ClaytonCopula {
theta: f64, // theta > 0
}
impl BivariateCopula for ClaytonCopula {
fn cdf(&self, u1: f64, u2: f64) -> f64 {
(u1.powf(-self.theta) + u2.powf(-self.theta) - 1.0)
.max(0.0) // числовая безопасность
.powf(-1.0 / self.theta)
}
fn pdf(&self, u1: f64, u2: f64) -> f64 {
let t = self.theta;
(t + 1.0) * (u1 * u2).powf(-(t + 1.0))
* (u1.powf(-t) + u2.powf(-t) - 1.0)
.powf(-(2.0 + 1.0 / t))
}
fn h_function(&self, u1: f64, u2: f64) -> f64 {
let t = self.theta;
u2.powf(-(t + 1.0))
* (u1.powf(-t) + u2.powf(-t) - 1.0)
.powf(-(1.0 + t) / t)
}
fn h_inverse(&self, u1: f64, u2: f64) -> f64 {
let t = self.theta;
let a = u2.powf(-t);
let b = u1.powf(-t / (t + 1.0));
((a * (b - 1.0) + 1.0).max(1e-300)).powf(-1.0 / t)
}
fn kendall_tau(&self) -> f64 { self.theta / (self.theta + 2.0) }
fn tail_dependence(&self) -> (f64, f64) {
(2.0_f64.powf(-1.0 / self.theta), 0.0)
}
fn n_params(&self) -> usize { 1 }
}
Обратите внимание на .max(0.0) и .max(1e-300) -- числовая безопасность критически важна. Возведение в отрицательные степени легко приводит к NaN без таких предохранителей.
Перечисление семейств и vine-модель
/// Семейства двумерных копул
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CopulaFamily {
Gaussian { rho: f64 },
StudentT { rho: f64, nu: f64 },
Clayton { theta: f64 },
Gumbel { theta: f64 },
Frank { theta: f64 },
Joe { theta: f64 },
BB1 { theta: f64, delta: f64 },
Independence,
}
/// Полная vine-копульная модель
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VineCopulaModel {
pub d: usize,
pub structure: RVineStructure,
/// Двумерные копулы: copulas[дерево][ребро]
pub copulas: Vec<Vec<CopulaFamily>>,
pub log_likelihood: f64,
pub aic: f64,
pub bic: f64,
pub truncation_level: Option<usize>,
}
/// Торговый сигнал
#[derive(Debug, Clone)]
pub struct CopulaSignal {
pub timestamp: i64,
/// Условная вероятность (значение h-функции)
pub conditional_prob: f64,
/// Индекс ошибочной оценки
pub mpi: f64,
/// Кумулятивный индекс ошибочной оценки
pub cmpi: f64,
/// Направление сигнала
pub signal: SignalDirection,
/// Уверенность (расстояние от порога в стд. отклонениях)
pub confidence: f64,
}
Оптимизация производительности
Ключевое разделение -- batch vs real-time:
| Операция | Сложность | Время |
|---|---|---|
| Выбор vine-структуры | O(d^2 * T) | ~5 сек |
| Параметры (Sequential MLE) | O(d^2 * T * iter) | ~10-20 сек |
| Условная вероятность | O(d^2) на наблюдение | ~0.1 мс |
| Монте-Карло (10K сценариев) | O(N * d^2) | ~50 мс |
Параллельный подбор семейств через rayon:
families.par_iter()
.map(|f| fit_and_score(u1, u2, f))
.min_by(|a, b| a.aic.partial_cmp(&b.aic).unwrap())
Vine-подгонка (5--30 секунд) выполняется в фоновом потоке, а торговый движок использует последнюю подогнанную модель для мгновенного вычисления условных вероятностей (~0.1 мс). Дополнительно используем кэширование h-функций, SIMD через std::simd для плотностей и инкрементальные обновления параметров вместо полной переоценки.

Полный пайплайн арбитражной стратегии
Соединим все элементы в единый алгоритм:
АЛГОРИТМ: Копульно-коинтеграционный арбитраж криптовалют
ФАЗА ОТБОРА ПАР:
1. Тесты Энгла-Грэнджера и KSS на коинтеграцию
2. Ранжировать по |tau Кендалла|, выбрать top-N пар
ФАЗА ПОДГОНКИ:
3. GARCH -> стандартизированные остатки -> псевдо-наблюдения
4. Выбор копулы по AIC, оценка параметров через MLE
ФАЗА ТОРГОВЛИ:
5. h_{1|2} < 0.05 И h_{2|1} > 0.95 -> ЛОНГ 1, ШОРТ 2
6. h_{1|2} или h_{2|1} пересекают 0.5 -> ВЫХОД
РИСК-МЕНЕДЖМЕНТ:
7. 10K сценариев -> VaR/CVaR -> контроль позиций
Vine-копулы также позволяют проводить реалистичные стресс-тесты: фиксируем U_BTC = 0.01 (крах BTC до 1-го процентиля) и симулируем остальные активы условно на этот стресс. Если копула Клейтона для пары BTC-ETH имеет lambda_L = 0.65, модель предскажет, что при крахе BTC ETH с вероятностью ~65% окажется в таком же экстремальном состоянии.
Заключение: от теории к практике
Vine-копулы -- это мощный и гибкий инструмент для моделирования сложных многомерных зависимостей в криптовалютном арбитраже. Они позволяют нам:
- Разделить индивидуальное поведение активов от структуры их связей (теорема Склара)
- Описать асимметричные и хвостовые зависимости, которые корреляция не видит
- Разложить сложные многомерные зависимости на простые двумерные блоки
- Генерировать торговые сигналы через условные вероятности (MPI/CMPI)
- Количественно оценивать экстремальные риски через GARCH-EVT-Copula фреймворк
При этом реализация на Rust обеспечивает производительность, достаточную для real-time торговли: вычисление условной вероятности занимает ~0.1 мс, а batch-переоценка модели -- 5-30 секунд в фоновом потоке.
В следующей части серии мы рассмотрим, как объединить vine-копулы с deep learning для адаптивного выбора структуры и параметров в режиме реального времени.
Полезные ссылки
- Stübinger, J., Mangold, B., & Krauss, C. (2018). "Statistical arbitrage with vine copulas." Quantitative Finance, 18(11), 1831-1849.
- Aas, K., Czado, C., Frigessi, A., & Bakken, H. (2009). "Pair-copula constructions of multiple dependence." Insurance: Mathematics and Economics, 44(2), 182-198.
- Dissmann, J. F., Brechmann, E. C., Czado, C., & Kurowicka, D. (2013). "Selecting and estimating regular vine copulae." Computational Statistics & Data Analysis, 59(1), 52-69.
- Tadi, M., & Witzany, J. (2025). "Copula-based trading of cointegrated cryptocurrency pairs." Financial Innovation, 11(1).
- Patton, A. J. (2006). "Modelling asymmetric exchange rate dependence." International Economic Review, 47(2), 527-556.
- Czado, C. (2019). "Analyzing Dependent Data with Vine Copulas." Lecture Notes in Statistics, Springer.
- Nelsen, R. B. (2006). "An Introduction to Copulas." Springer Series in Statistics, 2nd edition.
- Sklar, A. (1959). "Fonctions de repartition a n dimensions et leurs marges." Publ. Inst. Statist. Univ. Paris, 8, 229-231.
- vinecopulib -- C++ library for vine copula models (GitHub)
- Hudson & Thames. "Copula for Statistical Arbitrage: C-Vine Copula Trading."
- Macrosynergy. "Copulas and trading strategies."
Цитирование
@article{soloviov2026vinecopulas,
author = {Soloviov, Eugen},
title = {Vine-копулы в арбитраже: моделирование зависимостей в высоких размерностях},
year = {2026},
url = {https://marketmaker.cc/ru/blog/post/complex-arbitrage-vine-copulas},
version = {0.1.0},
description = {Как vine-копулы позволяют разложить сложную многомерную структуру зависимостей между криптоактивами на простые двумерные блоки и построить арбитражную стратегию}
}
MarketMaker.cc Team
Количественные исследования и стратегии