Асимметричные GARCH с тяжелыми хвостами: EGARCH, GJR и Student-t
В первой части этой серии мы построили GARCH(1,1) с нуля: интуицию кластеризации волатильности, рекурсию условной дисперсии, оценивание методом максимального правдоподобия, прогнозирование и стандартную диагностику остатков с помощью библиотеки arch. Если вы ее не читали, начните оттуда — этот пост предполагает, что вы уже умеете оценивать и интерпретировать обычный GARCH(1,1), и не будет заново выводить основы.
Обычный GARCH(1,1) — хороший базовый вариант, но плохой финальный ответ. У него есть два структурных дефекта, которые дешево игнорировать в бэктесте и дорого игнорировать с реальным капиталом. Во-первых, он симметричен: модель реагирует на день с точно так же, как на день с , потому что шок входит в рекурсию дисперсии только через свой квадрат, . Возведение в квадрат уничтожает знак. Во-вторых, он предполагает гауссовские инновации: даже после того как GARCH впитал кластеризацию волатильности, стандартизованные остатки BTC и ETH заметно тяжелохвостые, и гауссовское правдоподобие систематически недооценивает хвост. 99%-й VaR по модели GARCH(1,1)-Normal будет нарушаться намного чаще, чем в 1% случаев.
Этот пост устраняет оба дефекта. Мы добавляем асимметрию с помощью GJR-GARCH и EGARCH и тяжелые хвосты с помощью инноваций Student- и скошенного распределения Хансена (skew-). Затем мы делаем то, что реально окупается: превращаем оцененное условное распределение в однодневный прогноз Value-at-Risk и Expected Shortfall и честно бэктестируем этот прогноз с помощью тестов Купика и Кристоффersена. Модель волатильности, которую вы никогда не тестируете на риск, — это декорация.
Эффект финансового рычага и почему в крипте все сложнее
В акциях у этой асимметрии есть название и история. Эффект финансового рычага (leverage effect, Black, 1976): когда акции компании падают, отношение долга к капиталу растет, капитал механически становится более рискованным, и волатильность повышается. Плохие новости повышают будущую волатильность сильнее, чем равные по размеру хорошие новости. Эмпирически это один из самых устойчивых стилизованных фактов в литературе по волатильности акций.
У крипты нет ни акционерного капитала, ни балансового рычага в корпоративном смысле, но асимметрия, похожая на эффект финансового рычага, все равно проявляется большую часть времени — движимая вынужденным делевериджем, а не бухгалтерией. Когда BTC резко падает, ликвидируются переколлатерализованные займы, принудительно закрываются лонги по бессрочным фьючерсам, funding переворачивается, и каскад подпитывает волатильность. Так что механизм отличается, но знак часто совпадает с акциями: движения вниз резче поднимают волатильность.
Важная оговорка: крипта грязнее, и асимметрию стоит рассматривать как эмпирический вопрос, а не как закон. Резкие движения вверх — шорт-сквизы, разгон на рычаге, гэп на одобрении ETF — тоже могут резко поднять реализованную волатильность. В зависимости от актива и окна выборки оцененная асимметрия может быть сильной, слабой или иногда "неправильного" знака. Дисциплина, на которой настаивает этот пост: оцените асимметричную модель, посмотрите, статистически значим ли параметр асимметрии и в ожидаемом ли он направлении, и сохраняйте дополнительный параметр, только если он оправдывает свое место. Не предполагайте, что история из акций переносится напрямую — проверяйте это.
Проверка на асимметрию до моделирования
Тезис выше гласит "рассматривайте асимметрию как эмпирический факт" — поэтому перед оценкой асимметричной модели стоит запустить дешевый формальный тест на само наличие асимметрии. Именно это делают тесты Engle-Ng на sign-bias (1993). Сначала оцените симметричный GARCH(1,1), возьмите его квадраты стандартизованных остатков и регрессируйте их на индикаторы знака и величины предыдущего шока:
где и . Логика такая: если симметричная модель уже учла все, знак и величина вчерашнего шока не должны предсказывать сегодняшний квадрат остатка, то есть . Индивидуальные -тесты — это тесты на sign-bias (), negative-size-bias () и positive-size-bias (); совместный -тест по всем трем — это omnibus-тест. Значимый или говорит о том, что отрицательные шоки систематически неверно оцениваются симметричной моделью — это сигнал к тому, что GJR или EGARCH помогут.
import statsmodels.api as sm
def sign_bias_test(symmetric_res):
"""Engle-Ng sign-bias tests on a fitted symmetric GARCH result."""
z = symmetric_res.std_resid.dropna()
z2 = (z ** 2).values[1:]
eps_lag = z.values[:-1] # standardized shock proxy
neg = (eps_lag < 0).astype(float)
X = np.column_stack([
np.ones_like(eps_lag), # intercept
neg, # sign bias
neg * eps_lag, # negative size bias
(1 - neg) * eps_lag, # positive size bias
])
ols = sm.OLS(z2, X).fit()
names = ["const", "sign_bias", "neg_size_bias", "pos_size_bias"]
for nm, coef, t, p in zip(names, ols.params, ols.tvalues, ols.pvalues):
print(f"{nm:16s} coef={coef:+.4f} t={t:+.2f} p={p:.3f}")
print(f"Joint F p-value: {ols.f_pvalue:.4f}")
return ols
sign_bias_test(models["GARCH-N"])
Если совместный -тест незначим, у вас есть эмпирическое основание остаться на симметричной модели и сэкономить два параметра. Если он значим — обычный исход для BTC/ETH — переходите к GJR/EGARCH со спокойной совестью, зная, что моделируете реальную особенность, а не гонитесь за шумом. Это и есть эмпирическая дисциплина, которую требует тезис выше: не предполагать историю про эффект рычага из акций, а проверять ее.
GJR-GARCH: асимметрия через пороговый член
Модель Glosten-Jagannathan-Runkle (1993) — иногда называемая TGARCH или threshold GARCH — это наименьшая возможная правка GARCH(1,1), позволяющая плохим и хорошим новостям влиять по-разному. Вспомним симметричную рекурсию условной дисперсии из первой части:
GJR добавляет один пороговый член: дополнительную дозу дисперсии, которая включается только после отрицательного шока.
где — индикатор
Прочитайте рекурсию по случаям. После положительного шока () индикатор равен нулю, и влияние квадрата шока на дисперсию следующего периода — просто . После отрицательного шока индикатор равен единице, и влияние составляет . Параметр — вся история асимметрии в одном числе:
- : отрицательные шоки поднимают волатильность сильнее, чем положительные шоки той же величины. Это эффект финансового рычага, и это то, что вы обычно ожидаете найти в BTC/ETH.
- : модель схлопывается обратно к симметричному GARCH(1,1). Тест отношения правдоподобий или -тест на — это прямая проверка того, существует ли асимметрия вообще.
- : положительные шоки поднимают волатильность сильнее — редкий режим криптовалютного разгона вверх. Редко, но не исключайте это a priori.
Положительность и стационарность
Поскольку по-прежнему строится аддитивно, нужно, чтобы каждый член оставался неотрицательным. Достаточные условия положительности:
Заметьте, что сам может быть отрицательным, пока , так что влияние после плохих новостей никогда не становится отрицательным.
Для стационарности по ковариации предположим, что инновации стандартизованы и имеют симметричное распределение вокруг нуля, так что , и индикатор в среднем вносит вклад . Условие стационарности принимает вид
Безусловная (долгосрочная) дисперсия тогда равна
Это аналог для GJR результата из первой части , с дополнительным членом , учитывающим средний вклад периода полураспада эффекта рычага. Если распределение ваших инноваций скошено (скошенное распределение Хансена, см. ниже), заменяется на фактическую вероятность того, что , но — стандартный ориентир, используемый для отчетной персистентности.
EGARCH: моделирование логарифма дисперсии без ограничений положительности
GJR удерживает вас внутри смирительной рубашки положительности дисперсии: каждую комбинацию параметров нужно проверять на неравенства-ограничения, что раздражает при оптимизации и еще хуже при скользящей переоценке, когда окно иногда забредает в недопустимую область. Экспоненциальный GARCH Нельсона (1991) полностью обходит эту проблему, моделируя логарифм условной дисперсии. Поскольку может быть любым действительным числом, автоматически положительна независимо от значений параметров. Никаких ограничений вводить не нужно.
Запишем рекурсию через стандартизованную инновацию :
Шок несут два члена, и разделение их — вся идея:
- Член величины реагирует на размер шока, знак убран. Вычитание центрирует его так, что шок средней величины не вносит вклада. Для стандартного нормального распределения ; для стандартизованного Student- ожидаемое абсолютное значение меньше и зависит от , но
archобрабатывает это внутренне. - Член знака — это асимметрия. Он линеен по знаковой инновации, так что отрицательный толкает в противоположном направлении от положительного.
Соглашение о знаке важно, и на нем часто спотыкаются. В этой параметризации эффект финансового рычага (плохие новости поднимают волатильность) соответствует : отрицательный шок тогда дает , увеличивая логарифм дисперсии. Это противоположный знак по сравнению с в GJR. Всегда сверяйтесь с документацией конкретной модели по поводу соглашения, а не полагайтесь на память; arch сообщает EGARCH со своим знаком, и мы проверяем это ниже по кривой news impact, а не доверяем памяти.
Поскольку все аддитивно в логарифмах, персистентность EGARCH(1,1) определяется единственным авторегрессионным коэффициентом при ; стационарность требует только . Это намного более чистое условие, чем неравенство GJR, и это реальное практическое преимущество при переоценке на скользящих окнах.
Стоит отметить одну тонкость: реакция EGARCH на шоки экспоненциальна по инновации (экспонирование происходит в конце), тогда как у GJR она квадратичная. Поэтому EGARCH реагирует более резко на большие шоки — полезная особенность в крипте, где важны именно хвостовые события, но также и причина, по которой EGARCH иногда может выдавать неправдоподобно большие прогнозы дисперсии после дня-выброса. Ни одна из моделей не лучше универсально; выбор делается по качеству вневыборочного прогноза и бэктестам риска — в этом смысл всей серии.
Кривая news impact
Самый чистый способ увидеть разницу между симметричным GARCH, GJR и EGARCH — это кривая news impact (Engle and Ng, 1993): зафиксировать на ее долгосрочном уровне и построить график условной дисперсии следующего периода как функцию последнего шока . Она отвечает на вопрос "при шоке такого размера и знака насколько модель поднимает завтрашнюю волатильность?"
- Симметричный GARCH дает симметричную параболу, отцентрированную на нуле. Шоки и попадают на одинаковую высоту. Это как раз тот дефект, который мы устраняем.
- GJR дает параболу с изломом в нуле — круче слева (отрицательные шоки), чем справа, при . Две половины имеют кривизну и соответственно.
- EGARCH дает асимметричную экспоненциальную V-образную форму: два плеча имеют разный наклон из-за члена , и вся кривая изгибается вверх быстрее параболы из-за финального экспонирования.
Мы построим все три кривые по оцененным параметрам позже, в разделе с реализацией — это самый полезный диагностический инструмент для наглядной демонстрации того, что дает асимметрия.
Тяжелые хвосты: инновации Student-t и skew-t
Асимметрия исправляет реакцию модели на знак шоков. Она никак не влияет на распределение самих шоков. Обычный GARCH предполагает , и это предположение почти всегда неверно для крипты. Даже после того как GARCH убирает кластеризацию волатильности, стандартизованные остатки сохраняют избыточный эксцесс — они тяжелохвостые. Гауссовское правдоподобие, подгоняющее плечи распределения, недооценивает, насколько часто в реальности случается день с отклонением в , или сигм.
Последствие для риска прямое. Гауссовский 99%-й VaR использует квантиль , то есть предсказывает . Если истинное стандартизованное распределение — Student- с, скажем, степенями свободы, истинный 1%-й квантиль близок к — гауссовский VaR оптимистичен примерно на при этом уровне доверия. Вы будете нарушать его гораздо чаще, чем в 1% случаев, и систематически удивляться "невозможным" дням. Это не особенность крипты; Боллерслев (1987) ввел -GARCH именно потому, что остатки акций и валютных пар показывали те же тяжелые хвосты. Крипта — просто более экстремальная версия той же проблемы.
Стандартизованное распределение Student-t
Плотность Student- имеет параметр числа степеней свободы , контролирующий толщину хвостов: малое означает тяжелые хвосты, а при распределение сходится к гауссовскому. Загвоздка в том, что необработанное распределение имеет дисперсию , поэтому его необходимо стандартизовать к единичной дисперсии перед использованием в качестве инновации — иначе "" в рекурсии GARCH не была бы фактически условным стандартным отклонением.
Стандартизованная инновация Student- с единичной дисперсией имеет плотность
Обратите внимание на внутри — это и есть стандартизация, обеспечивающая . Вклад в логарифм правдоподобия одного наблюдения при заданной условной дисперсии GARCH и равен
Член — это якобиан преобразования от к — тот же член, что вы видели в гауссовском правдоподобии GARCH в первой части. Меняется только форма. Максимизация совместно по параметрам GARCH и — это именно то, что делает arch при передаче dist='t'.
Оцененное само по себе информативно. Для дневных доходностей BTC/ETH обычно получается диапазон — тяжелые хвосты, но с конечной дисперсией (для чего нужно ) и обычно конечным эксцессом (для чего нужно ). Если оцененное падает ниже 4, учтите, что выборочный эксцесс технически бесконечен в модели, а некоторые оценщики становятся неустойчивыми; это сигнал внимательно присмотреться к выбросам и качеству данных.
Скошенное распределение Хансена (skew-t)
Student- тяжелохвостое, но по-прежнему симметричное — левый и правый хвосты равны по тяжести. Остатки доходностей крипты часто также скошены: левый хвост (обвалы) тяжелее правого. Скошенное распределение Хансена (1994) обобщает стандартизованное параметром скошенности наряду с :
где константы , и подобраны так, чтобы имело нулевое среднее и единичную дисперсию при любых допустимых . Распределение разбивается в точке , используя разное масштабирование в каждой части, чтобы сместить больше массы в один хвост.
Интерпретация: дает левоскошенное распределение (более тяжелый нижний хвост), что является обычной находкой для крипты и тем, что вы бы ожидали в паре с эффектом финансового рычага. восстанавливает симметричное распределение Student-, так что тест показывает, дает ли член скошенности какую-то пользу. В arch это dist='skewt', который оценивает и , и . Результат — VaR, чей левый хвостовой квантиль честно тяжелее правого хвостового квантиля — именно то, что нужно, когда убытки, которые вы пытаетесь пережить, асимметричны. Это напрямую связано с асимметрией убытка и прибыли в исходах позиций: просадка на требует больше для восстановления, так что неправильное моделирование левого хвоста обходится дороже, чем правого.
Реализация на Python
Теперь оценим все это с помощью библиотеки arch. Настройка повторяет первую часть: получаем дневные доходности, масштабируем на 100 для численной кондиционированности (оптимизаторы GARCH плохо себя ведут, когда доходности имеют порядок ), и оцениваем с постоянным средним. Если вам нужны внутридневные данные или другая модель среднего, механика идентична.
Настройка и данные
import numpy as np
import pandas as pd
from arch import arch_model
from arch.univariate import GARCH, EGARCH, ConstantMean, StudentsT, SkewStudent
from scipy import stats
def fetch_returns(symbol="BTC-USD", start="2019-01-01", end="2025-12-31"):
"""Daily log returns, in percent (scaled x100 for the optimizer)."""
import yfinance as yf
px = yf.download(symbol, start=start, end=end)["Close"].dropna()
ret = 100.0 * np.log(px / px.shift(1)).dropna()
ret.name = symbol
return ret
r = fetch_returns("BTC-USD")
print(f"{len(r)} daily observations, "
f"annualized vol ~ {r.std() * np.sqrt(365):.0f}%")
Крипта торгуется 24/7, поэтому мы аннуализируем через 365, а не 252 — небольшой, но постоянно возникающий источник путаницы, когда вы сравниваете криптовалютный Sharpe или волатильность с цифрами фондового деска.
Оценка четырех моделей
Паттерн в arch: vol='Garch' с p=1, q=1 — это симметричный GARCH; добавление o=1 включает пороговый член GJR; vol='EGARCH' переключает на модель логарифма дисперсии. Распределение инноваций задается через dist: 'normal', 't', 'skewt'.
def fit(returns, vol="Garch", p=1, o=0, q=1, dist="normal"):
am = arch_model(returns, mean="Constant",
vol=vol, p=p, o=o, q=q, dist=dist)
res = am.fit(disp="off")
return res
models = {
"GARCH-N": fit(r, vol="Garch", o=0, dist="normal"), # Part 1 baseline
"GJR-t": fit(r, vol="Garch", o=1, dist="t"), # asymmetry + fat tails
"EGARCH-t": fit(r, vol="EGARCH", o=1, dist="t"), # log-variance asymmetry
"GJR-skewt": fit(r, vol="Garch", o=1, dist="skewt"), # + skew
}
for name, res in models.items():
print(f"\n===== {name} =====")
print(res.summary().tables[1]) # parameter table
Для vol='EGARCH' аргумент o контролирует асимметричный член (), а p/q контролируют члены величины и лага; o=1, p=1, q=1 — это стандартный EGARCH(1,1). Один подвох: имена параметров EGARCH в arch те же буквы, но соглашение о знаке члена асимметрии — нельсоновское, так что отрицательная оценка означает эффект финансового рычага. Мы проверяем это по кривой news impact, а не по памяти.
Чтение результата GJR
Таблица параметров GJR- выглядит примерно так (иллюстративные значения, не результат реального эксперимента — переоцените на своих данных):
coef std err t P>|t|
omega 0.0480 0.017 2.82 0.005
alpha[1] 0.0620 0.018 3.44 0.001
gamma[1] 0.0910 0.028 3.25 0.001
beta[1] 0.8850 0.021 42.1 0.000
nu 4.30 0.55 7.82 0.000
Как это читать:
gamma[1] = 0.091с -статистикой выше 3 — статистически значимый эффект финансового рычага. После отрицательного шока влияние квадрата шока составляет ; после положительного — просто . Плохие новости двигают волатильность этой модели примерно в раза сильнее, чем хорошие новости той же величины.nu = 4.3подтверждает тяжелые хвосты — далеко от гауссовского () и достаточно низкое, чтобы четвертый момент был на грани конечности. Гауссовский VaR на этом ряду был бы сильно оптимистичным.- Персистентность составляет — очень высокая, как обычно для дневной крипты: шоки затухают медленно, и волатильность сильно кластеризована.
Самая важная строка для проверки — строка . Если ее -значение велико, асимметричный член не оправдывает свое место на этом активе и окне, и стоит предпочесть более простую симметричную модель. Это дисциплина отбора моделей, а не декорация — подробнее об этом ниже.
Сравнение моделей по информационным критериям
Логарифм правдоподобия всегда улучшается при добавлении параметров, поэтому нельзя выбирать модель только по нему. Используйте AIC/BIC, которые штрафуют за число параметров (BIC агрессивнее):
def compare(models: dict) -> pd.DataFrame:
rows = []
for name, res in models.items():
rows.append({
"model": name,
"n_params": len(res.params),
"loglik": res.loglikelihood,
"AIC": res.aic,
"BIC": res.bic,
})
df = pd.DataFrame(rows).set_index("model")
return df.sort_values("BIC")
print(compare(models))
Практическое правило интерпретации: улучшение BIC более чем примерно на 6 по сравнению с базовой моделью — сильное свидетельство того, что дополнительная структура реальна; разница в 1–2 — это шум. Если GJR-t превосходит GARCH-N на 30+ пунктов BIC, а GJR-skewt превосходит GJR-t только на 1, сохраните и откажитесь от скошенности — параметр скошенности не окупает себя на этих данных. Не читайте AIC/BIC как замену вневыборочной валидации; они вознаграждают внутривыборочное качество с поправкой на сложность, что необходимо, но недостаточно. Настоящий тест — это бэктест VaR и, в конечном счете, пошаговая (walk-forward) оценка.
Построение кривой news impact
Это самый показательный график — он делает асимметрию видимой и проверяет соглашение о знаке EGARCH.
import matplotlib.pyplot as plt
def news_impact_curve(res, shock_grid):
"""
Next-period conditional variance as a function of the last shock,
holding sigma_{t-1} at the model's unconditional level.
Works for symmetric GARCH, GJR (o=1), and EGARCH.
"""
p = res.params
vol_name = res.model.volatility.__class__.__name__
sigma2_bar = np.mean(res.conditional_volatility ** 2)
omega = p["omega"]
alpha = p.get("alpha[1]", 0.0)
gamma = p.get("gamma[1]", 0.0)
beta = p.get("beta[1]", 0.0)
if vol_name == "EGARCH":
sig_prev = np.sqrt(sigma2_bar)
z = shock_grid / sig_prev
E_abs = np.sqrt(2 / np.pi) # approx; arch uses the fitted dist's E|z|
log_s2 = (omega + beta * np.log(sigma2_bar)
+ alpha * (np.abs(z) - E_abs) + gamma * z)
return np.exp(log_s2)
else:
ind = (shock_grid < 0).astype(float)
return omega + (alpha + gamma * ind) * shock_grid**2 + beta * sigma2_bar
shocks = np.linspace(-8, 8, 401) # daily % shocks
plt.figure(figsize=(8, 5))
for name in ["GARCH-N", "GJR-t", "EGARCH-t"]:
nic = news_impact_curve(models[name], shocks)
plt.plot(shocks, nic, label=name, lw=2)
plt.axvline(0, color="gray", lw=0.8, ls="--")
plt.xlabel("Last shock $\\varepsilon_{t-1}$ (daily %)")
plt.ylabel("Next-period conditional variance $\\sigma_t^2$")
plt.title("News impact curve: symmetric vs GJR vs EGARCH (BTC)")
plt.legend()
plt.tight_layout()
Когда вы запустите это, симметричная кривая GARCH-N окажется чистой параболой, отцентрированной на нуле, — шоки и дают одинаковую дисперсию. GJR-t — парабола с изломом в начале координат, выше на левом плече. EGARCH-t — экспоненциальная V-образная кривая, и если ее левое плечо расположено выше правого, вы одним взглядом подтвердили и эффект финансового рычага, и соглашение о знаке. Если левое плечо EGARCH расположено ниже правого, либо оценилась положительной (режим повышенной волатильности вверх), либо у вас перепутан знак — график подскажет, что именно, без всяких догадок.
Сравнение четырех моделей бок о бок
Прежде чем перейти к риску, полезно поставить четыре модели рядом. Каждая строка — это дизайн-решение, а столбцы показывают, во что оно обходится и что дает.
| Свойство | GARCH-N | GJR-t | EGARCH-t | GJR-skewt |
|---|---|---|---|---|
| Асимметрия (знак шока) | нет | пороговая | знаковая | пороговая |
| Форма хвоста инновации | гауссовская | Student- | Student- | скошенная- |
| Скошенность инновации | нет | нет | нет | да () |
| Ограничения положительности | да | да () | нет (лог-форма) | да |
| Условие стационарности | ||||
| Дополнительные параметры к базовой | 0 | |||
| Типичный вердикт для крипты | не проходит бэктест VaR | сильный, устойчивый | сильный, устойчивый | маргинальное улучшение над GJR-t |
Паттерн, который стоит запомнить: скачок от первого столбца ко второму — добавление одновременно асимметрии и тяжелых хвостов — это то место, где живет почти все улучшение калибровки риска. Последующие уточнения (функциональная форма EGARCH, член скошенности) реальны, но второго порядка, и на многих криптовалютных рядах они находятся внутри шума. Тратьте бюджет моделирования на первый скачок и относитесь скептически ко всему остальному.
Применение к риску: VaR и Expected Shortfall
Оценка более сложной модели волатильности имеет смысл только если она улучшает решение. Самое понятное решение для улучшения — это однодневный прогноз хвостового риска: насколько плохим может быть завтра? Мы получаем однодневный Value-at-Risk и Expected Shortfall (он же Conditional VaR, который использует в качестве целевой функции конвейер портфеля HRP/CVaR) напрямую из оцененного прогноза GARCH-/skew-.
От условного распределения к VaR
Механика GARCH дает однодневный прогноз условного среднего и условного стандартного отклонения . Доходность моделируется как с , взятым из оцененного стандартизованного распределения (гауссовского, или skew-). Так что -квантиль доходности — это просто аффинное преобразование -квантиля стандартизованного распределения:
где — квантиль (обратная функция распределения) стандартизованной инновации, а ведущий знак минус следует соглашению, что VaR — это положительное число убытка. Для 99%-го VaR , и вы подставляете . Вся выгода от /skew- проявляется именно здесь: более отрицательно, чем гауссовское , так что VaR честно больше.
Expected Shortfall
VaR сообщает порог; он ничего не говорит о том, насколько плохим будет нарушение, когда оно случится. Expected Shortfall — средний убыток при условии превышения VaR — сообщает, и он когерентен (субаддитивен), поэтому именно он лежит в основе оптимизации CVaR и почему Базель перешел на него. Для модели типа "положение-масштаб",
Член условного хвостового математического ожидания имеет замкнутые формы для стандартных распределений. Для гауссовского, с ,
где — плотность стандартного нормального распределения. Для стандартизованного Student- с степенями свободы и (на стандартизованной шкале) хвостовое математическое ожидание равно
где — стандартизованная плотность . Expected Shortfall для -распределения превышает гауссовский не только на ту же величину, что и VaR, потому что хвост -распределения не просто дальше — он толще, так что средний убыток за порогом непропорционально велик. Этот дополнительный разрыв — число, которое гауссовская модель от вас скрывает.
Вычисление VaR и ES по оцененной модели arch
Распределения в arch предоставляют метод ppf (квантиль), так что можно получить стандартизованный квантиль напрямую и не выводить его заново. Для ES мы интегрируем численно, что устойчиво и работает единообразно для normal/t/skewt.
from scipy import integrate
def var_es_forecast(res, alpha=0.99):
"""
One-step-ahead VaR and ES at level alpha, on the same (x100) scale
as the returns fed to the model. Divide by 100 for fractional units.
"""
fc = res.forecast(horizon=1, reindex=False)
mu = fc.mean.iloc[-1, 0]
sigma = np.sqrt(fc.variance.iloc[-1, 0])
dist = res.model.distribution # StudentsT / SkewStudent / Normal
dp = [res.params[k] for k in res.params.index
if k in ("nu", "eta", "lambda", "lam")]
z_q = dist.ppf(1 - alpha, dp) if dp else dist.ppf(1 - alpha)
z_q = float(np.atleast_1d(z_q)[0])
def pdf(z):
arr = np.atleast_1d(z).astype(float)
lp = dist.loglikelihood(dp, arr, np.ones_like(arr), individual=True) \
if dp else dist.loglikelihood([], arr, np.ones_like(arr),
individual=True)
return np.exp(lp)
num, _ = integrate.quad(lambda z: z * pdf(z), -30, z_q, limit=200)
es_z = num / (1 - alpha) # E[z | z <= z_q]
var = -(mu + sigma * z_q)
es = -(mu + sigma * es_z)
return {"mu": mu, "sigma": sigma, "z_q": z_q,
"VaR": var, "ES": es}
for name in ["GARCH-N", "GJR-t", "GJR-skewt"]:
out = var_es_forecast(models[name], alpha=0.99)
print(f"{name:11s} sigma={out['sigma']:.2f}% "
f"z_q={out['z_q']:+.2f} "
f"VaR99={out['VaR']:.2f}% ES99={out['ES']:.2f}%")
Столбец z_q — вся история в одном числе. Гауссовская модель использует ; модель с использует что-то около ; skew- отодвигает левый квантиль еще дальше, одновременно подтягивая правый. При том же — заметно больший VaR. Если вы запускали гауссовский VaR на крипте, это тот разрыв, который вы молча поглощали.
Один шаг против многих шагов: оговорка
Все вышеизложенное — это прогноз на один день вперед, и именно там VaR по GARCH самый чистый. Две вещи усложняют более длинные горизонты, и вам стоит их знать перед экстраполяцией.
Во-первых, прогнозы дисперсии возвращаются к среднему. Условная дисперсия на шагов вперед из стационарного GARCH сходится к безусловному уровню по мере роста , а кумулятивная дисперсия за дней — это сумма поshaговых прогнозов — это не , если только волатильность не находится на своем долгосрочном среднем. Наивное масштабирование "корень из времени" игнорирует этот возврат к среднему и оказывается неверным именно после шока, когда это число нужнее всего. Используйте собственную многошаговую траекторию дисперсии модели.
Во-вторых, распределение многодневной доходности не той же формы, что однодневная инновация. Суммирование нескольких дневных шоков с распределением (через нелинейную рекурсию GARCH) не дает распределения на горизонте дней; чистой замкнутой формы не существует. Для многодневного VaR честный путь — симуляция: сгенерировать траектории инноваций из оцененного стандартизованного распределения, прогнать их через рекурсию GARCH, чтобы получить симулированные траектории доходности, агрегировать в -дневные доходности и прочитать эмпирический квантиль. Это также естественным образом обрабатывает случай skew-, для которого вообще не существует аналитического многогоризонтного квантиля. Однодневные аналитические формулы в этом посте точны; относитесь к любому многошаговому упрощению как к приближению, которое нужно проверять.
Бэктестинг VaR: Купик и Кристоффersен
Прогноз VaR — это вероятностное утверждение: "убыток превысит этот порог лишь в доле дней". Вы проверяете его, подсчитывая нарушения (дни, когда реализованный убыток превысил прогнозный VaR) на пошаговой (walk-forward) оценке и проверяя две вещи. Во-первых, верна ли частота нарушений? Во-вторых, независимы ли нарушения, или они кластеризуются (что означает, что модель отказывает именно тогда, когда это важнее всего, — во время скачков волатильности)?
Пусть — последовательность нарушений, — число нарушений за дней, а — наблюдаемая частота. Целевая частота .
Тест безусловного покрытия Купика (1995) проверяет через отношение правдоподобий:
Тест независимости Кристоффersена (1998) проверяет, что сегодняшнее нарушение не предсказывается вчерашним нарушением. Пусть считает переходы из состояния в состояние в последовательности нарушений, , и . Тогда
Оба теста объединяются в тест условного покрытия , который одновременно проверяет и правильную частоту, и независимость. Модель может пройти тест Купика (верное число нарушений), но провалить тест Кристоффersена (все они сгрудились в одну неделю обвала) — именно этот режим отказа важнее всего отловить, потому что кластеризованные нарушения — это те, что взрывают счет.
from scipy.stats import chi2
def var_backtest(losses, var, p):
"""
losses, var: 1D arrays, same length; loss>0 is a loss, var>0 threshold.
p = 1 - alpha (target violation rate, e.g. 0.01 for 99% VaR).
Returns Kupiec, Christoffersen-independence, and conditional-coverage LR.
"""
losses = np.asarray(losses)
var = np.asarray(var)
I = (losses > var).astype(int) # violation indicators
T = len(I)
N = int(I.sum())
pi_hat = N / T
eps = 1e-12
ll_null = N * np.log(p + eps) + (T - N) * np.log(1 - p + eps)
ll_alt = N * np.log(pi_hat + eps) + (T - N) * np.log(1 - pi_hat + eps)
LR_uc = -2 * (ll_null - ll_alt)
p_uc = 1 - chi2.cdf(LR_uc, df=1)
n00 = np.sum((I[:-1] == 0) & (I[1:] == 0))
n01 = np.sum((I[:-1] == 0) & (I[1:] == 1))
n10 = np.sum((I[:-1] == 1) & (I[1:] == 0))
n11 = np.sum((I[:-1] == 1) & (I[1:] == 1))
pi01 = n01 / (n00 + n01) if (n00 + n01) else 0.0
pi11 = n11 / (n10 + n11) if (n10 + n11) else 0.0
pi = (n01 + n11) / (n00 + n01 + n10 + n11)
def _ll(pi01, pi11, pi_pooled, use_pooled):
if use_pooled:
a = (n00 + n10) * np.log(1 - pi_pooled + eps)
b = (n01 + n11) * np.log(pi_pooled + eps)
return a + b
return (n00 * np.log(1 - pi01 + eps) + n01 * np.log(pi01 + eps)
+ n10 * np.log(1 - pi11 + eps) + n11 * np.log(pi11 + eps))
LR_ind = -2 * (_ll(pi01, pi11, pi, True) - _ll(pi01, pi11, pi, False))
p_ind = 1 - chi2.cdf(LR_ind, df=1)
LR_cc = LR_uc + LR_ind
p_cc = 1 - chi2.cdf(LR_cc, df=2)
return {
"T": T, "violations": N,
"obs_rate": pi_hat, "target_rate": p,
"LR_uc": LR_uc, "p_uc": p_uc,
"LR_ind": LR_ind, "p_ind": p_ind,
"LR_cc": LR_cc, "p_cc": p_cc,
}
Чтобы честно получить данные losses/var, переоценивайте модель (или хотя бы перепрогнозируйте) на расширяющемся или скользящем окне и записывайте однодневный прогноз VaR для каждого дня вне выборки, а затем сравнивайте его с реализованным убытком за тот же день. Никогда не бэктестируйте VaR внутри выборки — модель, оцененная на том же обвале, который ее просят предсказать, будет выглядеть намного лучше, чем есть на самом деле. Это та же дисциплина, что и паритет бэктеста и живой торговли: оценка должна использовать только информацию, доступную на момент принятия решения.
def walk_forward_var(returns, alpha=0.99, start=750, refit_every=25,
vol="Garch", o=1, dist="t"):
"""
Expanding-window one-step VaR. Refit every `refit_every` days
(refitting daily is correct but slow; every ~25 days is a common
compromise -- validate the shortcut on your data).
"""
losses, vars_ = [], []
res = None
for t in range(start, len(returns)):
if res is None or (t - start) % refit_every == 0:
am = arch_model(returns.iloc[:t], mean="Constant",
vol=vol, p=1, o=o, q=1, dist=dist)
res = am.fit(disp="off")
fc = res.forecast(horizon=1, reindex=False)
mu = fc.mean.iloc[-1, 0]
sig = np.sqrt(fc.variance.iloc[-1, 0])
dp = [res.params[k] for k in res.params.index
if k in ("nu", "eta", "lambda", "lam")]
z_q = float(np.atleast_1d(
res.model.distribution.ppf(1 - alpha, dp) if dp
else res.model.distribution.ppf(1 - alpha))[0])
var_t = -(mu + sig * z_q)
vars_.append(var_t)
losses.append(-returns.iloc[t]) # realized loss for that day
return np.array(losses), np.array(vars_)
losses, vars_ = walk_forward_var(r, alpha=0.99, dist="t")
print(var_backtest(losses, vars_, p=0.01))
Как читать результат: хорошо откалиброванный 99%-й VaR показывает наблюдаемую частоту около 1%, незначимый тест Купика (большое p_uc) и незначимый тест Кристоффersена (большое p_ind) — без кластеризации. На практике честный результат для крипты в том, что GARCH-Normal проваливает тест Купика (слишком много нарушений, p_uc крошечное), в то время как GJR- или EGARCH- проходят или почти проходят. Этот контраст — весь аргумент этого поста, выраженный в виде статистической проверки гипотезы. Если даже модель показывает кластеризованные нарушения (малое p_ind), ваша динамика волатильности все еще неверно специфицирована — часто это признак того, что нужна более длинная память (component/FIGARCH) или слой режимов, что связано с определением режимов через HMM.
Ранжирование моделей по хвостовому убытку, а не только по прохождению теста
Тесты Купика и Кристоффersена дают бинарный вердикт — модель отвергнута или нет. Это необходимо, но грубо: две модели могут обе "пройти", в то время как одна заметно точнее. Чтобы ранжировать конкурирующие прогнозы VaR, оцените их строго согласованной функцией потерь для квантиля — pinball (квантильной) потерей:
где — (знаковый) квантиль VaR, а — реализованная доходность. Усредненное по дням вне выборки, меньшее среднее значение pinball-потери означает лучше откалиброванный и более точный квантиль; поскольку потеря согласована для -квантиля, ее минимизация не вознаграждает модель за то, что она попросту "широка". Чтобы формально сравнить две модели, подайте разности их подневных потерь в тест Diebold-Mariano.
def pinball_loss(returns, var, alpha=0.99):
tau = 1 - alpha
q = -np.asarray(var) # VaR is a positive loss; quantile is negative
r = np.asarray(returns)
hit = (r < q).astype(float)
return np.mean((tau - hit) * (r - q))
Что касается Expected Shortfall, отметим, что ES сам по себе не элиситабелен (не существует функции потерь, минимизатор которой был бы только ES) — это подлинная теоретическая тонкость: вы оцениваете ES совместно с VaR, используя правила оценки Fissler-Ziggel, либо прибегаете к более простой практике — проверке того, что средняя величина нарушения соответствует предсказанному моделью ES. Грубая, но полезная проверка ES: среди дней с нарушением VaR сравните средний реализованный убыток со средним прогнозным ES в эти дни — они должны быть близки.
Регуляторный подход — это подход светофора Базеля: за 250 торговых дней 0-4 нарушения 99%-го VaR — "зеленый" (приемлемо), 5-9 — "желтый" (усиленный контроль), 10+ — "красный" (модель отвергается, и мультипликаторы капитала растут). Это более грубый родственник теста Купика, но именно на этом языке действительно говорят риск-комитеты, и его стоит указывать наряду со статистиками LR.
Практические соображения
Когда дополнительные параметры не окупаются
Честный подход по умолчанию — скепсис к сложности. Каждый добавленный параметр — это ручка, которую оптимизатор может переподогнать, а у асимметричного тяжелохвостого GARCH их несколько. Конкретные рекомендации:
- Неликвидные или короткие выборки. При нескольких сотнях дневных наблюдений стандартная ошибка и будет большой, и вы будете "обнаруживать" асимметрии, которые на самом деле являются шумом выборки. На новом или тонком альткоине симметричный GARCH- часто является самой сложной моделью, которую могут поддержать данные. Подгонка skew- EGARCH на 200 днях — это самообман.
- Член скошенности часто не окупает свою стоимость. На практике переход от Normal к — крупное и надежное улучшение (тяжелые хвосты реальны и сильны). Переход от к skew- часто маргинален — прирост BIC в 1-2 пункта, иногда отрицательный. Добавляйте скошенность только тогда, когда данные явно ее требуют.
- EGARCH против GJR на дневных данных — обычно паритет. Они кодируют одну и ту же качественную историю разными функциональными формами. Выбирайте по вневыборочному бэктесту VaR, а не по тому, у какой лучше внутривыборочное правдоподобие.
- Более высокая частота меняет ответ. На часовых или минутных барах доминируют внутридневная сезонность и микроструктура, и обычный дневной GARCH неверно специфицирован независимо от асимметрии. Другая задача, другой инструментарий.
Это тот же урок, что и честная оценка без устойчивого преимущества: более сложная модель, которая не выживает вневыборочное тестирование, хуже простой, которую она заменила, потому что несет иллюзию точности. Сообщайте об отрицательном результате — "скошенность не помогла на ETH" — как о реальной находке, и используйте пошаговую оптимизацию как арбитра, а не внутривыборочный AIC.
Это те самые маргинальные распределения, на которых строится все остальное
Модели из этого поста — не конечная точка; это одномерный строительный блок для совместной риск-машинерии. Пост про копула-модели совместного крипто-риска использует именно EGARCH/GJR- в качестве маргинальных распределений GARCH-EVT перед подгонкой вайн-копулы — вы оцениваете асимметричный тяжелохвостый GARCH для каждого актива, извлекаете стандартизованные остатки и только затем моделируете межактивную зависимость. Если ваше маргинальное распределение — симметричный гауссовский GARCH, копула унаследует его ошибки в хвостах независимо от того, насколько хороша модель зависимости. Мусорные маргиналы — мусорный совместный VaR.
Для многомерной задачи волатильности — изменяющихся во времени корреляций, а не подневных дисперсий — см. третью часть, DCC-GARCH, которая надстраивает модель динамической корреляции поверх этих одномерных оценок. А для превращения прогноза волатильности в размер позиции и торговый бэктест четвертая часть о таргетировании волатильности использует прогнозы из этих же моделей, чтобы масштабировать экспозицию обратно пропорционально прогнозируемому риску.
Альтернатива без предположений о распределении
Весь раздел про риск опирается на параметрическое предположение: что стандартизованные остатки следуют распределению или skew-. Это предположение проверяемо и обычно разумно, но оно может не выполняться. Если вы не хотите вообще привязываться к форме хвоста, конформное предсказание дает интервалы прогноза без предположений о распределении с гарантиями покрытия для конечной выборки — подлинно другая философия, не делающая никаких утверждений о распределении инноваций. Два подхода дополняют друг друга: параметрический GARCH- дает полную условную плотность (а значит, и ES, который конформные интервалы напрямую не предоставляют), в то время как конформный подход дает покрытие, которое выполняется даже когда ваша плотность неверна. В продакшене использование обоих в качестве перекрестной проверки — дешевая страховка.
Численная и рабочая гигиена
- Масштабируйте доходности на 100. Оптимизаторы GARCH сходятся гораздо надежнее на процентных доходностях, чем на сырых дробных. Не забудьте пересчитать масштаб VaR/ES обратно, если отчитываетесь в дробных единицах.
- Следите за персистентностью. Если оценка выше ~0.999, модель близка к интегрированной (в духе IGARCH); прогнозы возвращаются к среднему крайне медленно, и долгосрочные прогнозы дисперсии становятся ненадежными. Не обязательно неверно, но стоит пометить.
- Сбои сходимости на скользящих окнах. Логарифмическая форма EGARCH избегает ограничений положительности, но все равно может не сойтись на патологическом окне. Оберните
fit()в try/except и откатывайтесь на параметры предыдущего окна вместо того, чтобы обрушивать живой бэктест. - Модель среднего. Мы всюду использовали постоянное среднее. Для большей части дневной крипты условное среднее близко к нулю и подавляется волатильностью; не тратьте сложность модели на его прогнозирование без реальной причины.
Резюме
- У обычного GARCH(1,1) два структурных дефекта: он симметричен (реагирует на и одинаково, потому что шоки входят как ) и предполагает гауссовские инновации (недооценивая тяжелые хвосты крипты). Оба обходятся реальными деньгами через чрезмерно оптимистичный VaR.
- GJR-GARCH добавляет пороговый член . Значимый — это эффект финансового рычага: плохие новости поднимают волатильность сильнее. Положительность требует ; персистентность — .
- EGARCH моделирует , поэтому нет ограничений положительности, а стационарность — это просто . Асимметрия входит через знаковый член (эффект рычага — это в этом соглашении), отделенный от члена величины .
- Кривая news impact — дисперсия следующего периода в зависимости от последнего шока — делает асимметрию видимой и проверяет соглашение о знаке EGARCH одним взглядом.
- Инновации Student- (
dist='t') исправляют хвосты через число степеней свободы (обычно 3–6 для крипты); скошенное распределение Хансена (dist='skewt') добавляет скошенность для более тяжелого левого хвоста. Переход от Normal к — крупный надежный выигрыш; от к skew- часто маргинален. - VaR и ES следуют из оцененного условного распределения: , при этом тяжелохвостый квантиль делает риск честно больше гауссовского. ES (когерентный, CVaR) отражает средний убыток за пределами VaR.
- Бэктестируйте тестами Купика и Кристоффersена. Купик проверяет частоту нарушений; Кристоффersен проверяет, что нарушения не кластеризуются. Модель может пройти один тест и провалить другой — кластеризованные нарушения являются опасным режимом отказа. Бэктестируйте строго вне выборки.
- Дисциплина важнее сложности. Добавляйте асимметрию/скошенность только тогда, когда они выдерживают проверку BIC и вневыборочный бэктест VaR. На коротких или неликвидных рядах более простая модель обычно побеждает.
References:
- Nelson, D. B. (1991). Conditional heteroskedasticity in asset returns: A new approach. Econometrica, 59(2), 347-370. DOI
- Glosten, L. R., Jagannathan, R., & Runkle, D. E. (1993). On the relation between the expected value and the volatility of the nominal excess return on stocks. Journal of Finance, 48(5), 1779-1801. DOI
- Bollerslev, T. (1987). A conditionally heteroskedastic time series model for speculative prices and rates of return. Review of Economics and Statistics, 69(3), 542-547. DOI
- Hansen, B. E. (1994). Autoregressive conditional density estimation. International Economic Review, 35(3), 705-730. DOI
- Engle, R. F., & Ng, V. K. (1993). Measuring and testing the impact of news on volatility. Journal of Finance, 48(5), 1749-1778. DOI
- Christoffersen, P. F. (1998). Evaluating interval forecasts. International Economic Review, 39(4), 841-862. DOI
- Kupiec, P. H. (1995). Techniques for verifying the accuracy of risk measurement models. Journal of Derivatives, 3(2), 73-84. DOI
- Black, F. (1976). Studies of stock price volatility changes. Proceedings of the American Statistical Association, Business and Economic Statistics Section, 177-181.
- McNeil, A. J., Frey, R., & Embrechts, P. (2015). Quantitative Risk Management: Concepts, Techniques and Tools (2nd ed.). Princeton University Press.
- Sheppard, K. (2023). arch: Autoregressive conditional heteroskedasticity models in Python. GitHub.
MarketMaker.cc Team
Количественные исследования и стратегии