Модели ARCH и GARCH

  • ARCH, GARCH, EGARCH
  • Глубокое погружение в модели ARCH и GARCH
  • Волатильность S&P500: модели ARCH и GARCH
  • Почему GARCH-модели терпят неудачу вне выборки
  • Режим волатильности по GARCH(1,1)&Markov

ARCH, GARCH, EGARCH

Как измерить волатильность в движении цен на акции

Я по-прежнему уверен в понимании различных методов, используемых в количественных исследованиях, в частности, с акциями. Я углубился в байесовские методы, такие как BART и модели динамической регрессии с переключением Маркова. Я продолжу углубляться в байесовскую статистику и логические выводы, однако недавно я работал над проектом, который включал в себя понимание природы волатильности в ценах. В своих поисках я наткнулся на серию моделей с аббревиатурой ARCH. ARCH расшифровывается как autoregressive conditional heteroskedasticity (авторегрессионная условная гетероскедастичность). Вы можете думать о ARCH как о базовой модели, и есть другие модели, такие как GARCH и EGARCH, которые ответвляются от нее. Существует целый набор таких моделей, потенциально около 50 или около того, если предположить. Более полный список моделей можно найти в журнальной статье, цитируемой ниже, Bollerslev[1]. В этом посте мы поговорим о трех наиболее распространенных моделях ARCH: ARCH, GARCH и EGARCH

ARCH можно рассматривать как модель авторегрессии, которая использует запаздывающие значения в качестве предиктора или экзогенные переменные в регрессионной модели для прогнозирования будущих значений. В случае прогнозирования и оценки волатильности для прогнозирования будущих неизвестных значений используются предыдущие переменные волатильности и дисперсии. Гетероскедастичность является основным компонентом для понимания назначения моделей ARCH. Гетероскедастичность предполагает, что переменная временного ряда имеет дисперсию, которая изменяется со временем. Это относится и к доходности цены актива. Будут периоды, когда будет высокий и низкий спрос. Эти периоды высокого и низкого спроса будут сгруппированы вместе в течение определенного периода времени. Именно здесь на помощь приходят модели ARCH для моделирования присутствия этих кластеров. Все модели ARCH следуют этой общей функциональности с разными весами, чтобы представлять данные немного по-разному по сравнению друг с другом.

Модели

На рисунке ниже первая модель — это стандартная модель ARCH. Основа всех остальных моделей, связанных с ARCH. Второй — GARCH, а третий — EGARCH. Вы заметите, что вторая и третья формулы являются расширениями модели ARCH. Ниже приведено объяснение каждого из них.

ARCH(p)

Формула 1: ARCH(p)
  • В последовательности случайных переменных временных рядов мы ищем уловить дисперсию в момент времени t с учетом прошлых значений p. Это «условный» аспект модели и то, что означает буква C в аббревиатуре.
  • σ² – прогнозируемая условная дисперсия в момент времени t.
  • ⍺₀ — константа во всех моделях ARCH, которая является точкой пересечения уравнения авторегрессии.
  • yt здесь будет представлять значения в нашем временном ряду случайной величины. Поскольку модели, связанные с ARCH, широко используются в области количественных финансов, для единообразия мы определим их как логарифмическую доходность актива.
  • ⍺i — коэффициенты модели авторегрессии для каждого возвращаемого значения P в квадрате логарифма. Это также известно как термин ARCH.
  • Обратите внимание, что в приведенной выше модели ARCH(p) логарифмические доходы возведены в квадрат. Формула дисперсии: Var(X) = E[(X-μ)µ²]. Однако в приведенном выше примере мы возводим значения в квадрат без вычитания среднего значения. Это связано с тем, что модель предполагает, что моделируемая случайная величина имеет среднее значение 0. Если ваши значения не совпадают, убедитесь, что вы выполнили шаг центрирования переменных, вычитая среднее значение из каждого значения. Общее понимание логарифмических возвращаемых значений заключается в том, что они обычно сосредоточены вокруг 0. То же самое относится и к GARCH и EGARCH.

GARCH(p, q)

Формула 2: GARCH(p, q)
  • В GARCH модель ARCH расширяется за счет ее обобщения. Он обобщается путем сложения прошлых q значений прогнозируемой условной дисперсии.
  • βj — коэффициенты для каждого прогнозируемого значения условной дисперсии от 1 до qσ². Это также известно как термин GARCH.
  • ⍺i остается термином ARCH из исходной модели, а ⍺₀ является пересечением.
  • Опять же, как и модель ARCH, она предполагает среднее значение 0.

ЕГАРХ(p, q)

  • Приведенная выше формула для модели EGARCH используется в пакете python ARCH. Здесь et = yt / σt, где y остается в качестве логарифмического возврата в этом посте. et — стандартизированный логарифмический возврат в момент времени t.
  • В EGARCH вы можете увидеть ARCH и GARCH в основе модели с дополнительными расширениями. На этот раз вместо того, чтобы моделировать условную дисперсию, он моделирует логарифм условной дисперсии, ln(σ²).
  • Кроме того, вместо того, чтобы просто возвести логарифм в квадрат, он заменяется новым уравнением ⍺i(|et-i| — √2/π)). Уравнение служит модифицированным членом ARCH. ⍺i — коэффициент члена ARCH. et являются предыдущими стандартизированными логарифмическими возвратами. Модифицированный член ARCH учитывает предыдущие p абсолютных значений «шоков волатильности». Вы можете думать о шоках волатильности как о величине предыдущего p-логарифмического дохода.
  • Буква o обозначает порядок «асимметричных инноваций» в серии логарифмических возвратов. Это параметр, который передается в python-реализации EGARCH. В некоторой литературе этот параметр не передается, и в приведенном выше уравнении o будет заменено на p. «Асимметричные инновации» — это запаздывающие логарифмические доходы, которые указывают на наличие асимметрии в пределах предыдущих доходностей. Я столько раз говорил об асимметрии, не объясняя, что это вообще значит. В данном случае это означает, что положительная или отрицательная доходность приводит к повышенной волатильности. Не то и другое. Если повышенная положительная или отрицательная доходность приводит к повышенной волатильности, то говорят, что она симметрична.
  • γ — это дополнительный коэффициент, который может дать вам представление о том, имеет ли ваш временной ряд симметричное или асимметричное поведение волатильности. Когда значение γ = 0, волатильность называется симметричной. При γ < 0 отрицательная доходность увеличивает волатильность. Наконец, γ > 0 указывает на то, что положительная доходность приводит к повышенной волатильности. Значение, на которое следует обратить внимание при анализе модели [2].

Реализация

Примечание: Приведенный ниже код предназначен для отображения того, как вычисляются некоторые вычисления и как создаются графики. Приносим извинения за неполноту. Причина, по которой полный код не включен, заключается в том, что у нас есть набор классов, предназначенных для анализа, визуализации и вычислений метрик, которые команда часто использует. Чтобы отобразить полный набор кода, мне нужно отобразить полный репозиторий. Кроме того, РЕПО в настоящее время является частным, поскольку команда исследует количественные методы, которые мы могли бы использовать в качестве розничных трейдеров. Прогресс нашей работы на рынках будет обсуждаться в следующих статьях, так что следите за обновлениями, чтобы снова и снова извиниться!

Чтобы применить модели на практике на реальных данных, будет оценена и спрогнозирована волатильность двух акций. Это две акции: Devon Energy Corp (DVN) и UBER Technologies (UBER). Ниже приведен график скорректированной цены закрытия каждой акции с 10 мая 2019 года по 30 ноября 2023 года.

UBER и DVN Скорректированная цена закрытия

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

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

Марк Джеймисон

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

Возврат журнала UBER и DVN за 1 день

На графике выше видны признаки высокой волатильности в первые месяцы 2020 года. COVID-19 был периодом повышенной волатильности на всех рынках. После этого аномального периода времени наблюдаются небольшие сокращения и расширения логарифмической доходности UBER. С другой стороны, DVN, похоже, имеет довольно стабильную волатильность в своих логарифмических доходах. Несмотря на то, что временные ряды возвращаемых журналов не идеальны с точки зрения кластеров, мы посмотрим, можно ли их смоделировать для целей этой статьи.

Если вы помните из приведенного выше описания упомянутых моделей ARCH, есть 2 параметра, которые следует учитывать. Этими параметрами являются p и qP — переменная запаздывающей дисперсии, а q — запаздывающая условная дисперсия. Запаздывающая дисперсия представляет собой логарифмическую возвращаемость, возведенную в квадрат. Синяя линия на графиках, отображающая логарифмическую доходность с течением времени, указывает среднее значение ряда, которое составляет около 0. Чтобы проверить, обладает ли логарифмическая доходность какой-либо предсказательной силой на основе запаздывающих значений, для акций строятся графики ACF и PACF.

Функции ACF и PACF проверяют, существует ли значимая корреляция между запаздывающими переменными. В данном случае мы проверяем, есть ли какие-либо корреляции между возвращаемыми значениями log в момент времени t и — q. По оси x показаны запаздывающие дни, а по оси Y — коэффициент корреляции.

UBER и DVN ACF и PACF логов возвратов

Судя по приведенным выше графикам, у нас не так много предсказательной силы, на которую мы можем положиться из-за запаздывающих переменных. Для UBER отставание в 3 балла, основанное как на ACF, так и на PACF, показывает некоторую значимость, но корреляция близка к отсутствию. То же самое касается и лага в 7 для DVN. Поскольку мы моделируем дисперсию, приведенный выше анализ можно дополнительно усовершенствовать, возведя в квадрат логарифмические доходы, чтобы увидеть, есть ли связь между текущей дисперсией и запаздывающей дисперсией.

UBER и DVN ACF и PACF дисперсии

После возведения в квадрат логарифмических возвращаемых значений мы можем увидеть некоторые улучшения в отношении текущего и запаздывающего значений. Исходя из вышесказанного, как для UBER, так и для DVN, значение с запаздыванием в 1 день предлагает лучшее значение параметра для моделей ARCH.

Обратите внимание, что в приведенном ниже коде пакет ARCH предпочитает иметь значения от 1 до 1000. При передаче значений меньшего размера, ARCH напечатает предупреждающее сообщение и изменит масштаб значений, умножив их на 10. Чтобы предотвратить любую искусственную дисперсию и предупреждающее сообщение, параметру rescale было присвоено значение False.# scale the returns to prevent scale warnings
uber_returns = UBER[‘log_returns’].dropna()
dvn_returns = DVN[‘log_returns’].dropna()

UBER_ARCH = arch_model(uber_returns, vol=»ARCH», p=1, rescale=False)
UBER_GARCH = arch_model(uber_returns, vol=»GARCH», p=1, q=1, rescale=False)
UBER_EGARCH = arch_model(uber_returns, vol=»EGARCH», p=1, q=1, rescale=False)

DVN_ARCH = arch_model(dvn_returns, vol=»ARCH», p=1, rescale=False)
DVN_GARCH = arch_model(dvn_returns, vol=»GARCH», p=1, q=1, rescale=False)
DVN_EGARCH = arch_model(dvn_returns, vol=»EGARCH», p=1, q=1, rescale=False)

# fit the models
UBER_ARCH = UBER_ARCH.fit()
UBER_GARCH = UBER_GARCH.fit()
UBER_EGARCH = UBER_EGARCH.fit()

DVN_ARCH = DVN_ARCH.fit()
DVN_GARCH = DVN_GARCH.fit()
DVN_EGARCH = DVN_EGARCH.fit()

# get the predicted variance of each model
uber_arch_vol = UBER_ARCH.conditional_volatility
uber_garch_vol = UBER_GARCH.conditional_volatility
uber_egarch_vol = UBER_EGARCH.conditional_volatility

dvn_arch_vol = DVN_ARCH.conditional_volatility
dvn_garch_vol = DVN_GARCH.conditional_volatility
dvn_egarch_vol = DVN_EGARCH.conditional_volatility

# combine with the training data
UBER = UBER.dropna()
DVN = DVN.dropna()

UBER[‘Predicted ARCH’] = uber_arch_vol
UBER[‘Predicted GARCH’] = uber_garch_vol
UBER[‘Predicted EGARCH’] = uber_egarch_vol

DVN[‘Predicted ARCH’] = dvn_arch_vol
DVN[‘Predicted GARCH’] = dvn_garch_vol
DVN[‘Predicted EGARCH’] = dvn_egarch_vol

UBER[‘Actual VAR’] = ((UBER[‘log_returns’] ** 2) ** 0.5)
DVN[‘Actual VAR’] = ((DVN[‘log_returns’] ** 2) ** 0.5)

plot_uber = UBER[[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’]].reset_index()
plot_dvn = DVN[[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’]].reset_index()

# melt the data
plot_uber_melt = plot_uber.melt(id_vars=’Date’, value_vars=[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’])
plot_dvn_melt = plot_dvn.melt(id_vars=’Date’, value_vars=[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’])

palette = {‘Actual VAR’: ‘black’,
‘Predicted ARCH’: ‘#009CDE’,
‘Predicted GARCH’: ‘#FF671F’,
‘Predicted EGARCH’: ‘#802AB8’}

fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(15, 12))

sns.lineplot(data=plot_uber_melt,
x=’Date’,
y=»value»,
hue=»variable»,
palette=palette, ax=axes[0]).set_title(f»UBER Predicted vs Actual: Training Data»)

sns.lineplot(data=plot_dvn_melt,
x=’Date’,
y=»value»,
hue=»variable»,
palette=palette, ax=axes[1]).set_title(f»DVN Predicted vs Actual: Training Data»)

# plt.savefig(‘training_plot.png’, bbox_inches=’tight’)
plt.show()

Прогнозируемые и фактические значения обучающих данных (в выборке)

Теперь, когда модели были подогнаны к выборочным данным, мы можем использовать коэффициенты аппроксимированной модели, чтобы спрогнозировать, как потенциально будет выглядеть волатильность в будущем.# forecast 20 days out
UBER_test = test_data[test_data[‘ticker’] == ‘UBER’]
DVN_test = test_data[test_data[‘ticker’] == ‘DVN’]

UBER_test = UBER_test[UBER_test.index < ‘2024-01-01’]
DVN_test = DVN_test[DVN_test.index < ‘2024-01-01’]
print(UBER_test.shape)
print(DVN_test.shape)

uber_forecast_ARCH = UBER_ARCH.forecast(start=0, horizon=20)
uber_forecast_GARCH = UBER_GARCH.forecast(start=0, horizon=20)
uber_forecast_EGARCH = UBER_EGARCH.forecast(start=0, horizon=20, method=’simulation’)

uber_forecast_ARCH = uber_forecast_ARCH.variance.dropna().iloc[-1].values.flatten()
uber_forecast_GARCH = uber_forecast_GARCH.variance.dropna().iloc[-1].values.flatten()
uber_forecast_EGARCH = uber_forecast_EGARCH.variance.dropna().iloc[-1].values.flatten()
#
dvn_forecast_ARCH = DVN_ARCH.forecast(start=0, horizon=20)
dvn_forecast_GARCH = DVN_GARCH.forecast(start=0, horizon=20)
dvn_forecast_EGARCH = DVN_EGARCH.forecast(start=0, horizon=20, method=’simulation’)

dvn_forecast_ARCH = dvn_forecast_ARCH.variance.dropna().iloc[-1].values.flatten()
dvn_forecast_GARCH = dvn_forecast_GARCH.variance.dropna().iloc[-1].values.flatten()
dvn_forecast_EGARCH = dvn_forecast_EGARCH.variance.dropna().iloc[-1].values.flatten()
#
# # add to the dataframe
UBER_test[‘Predicted ARCH’] = uber_forecast_ARCH
UBER_test[‘Predicted GARCH’] = uber_forecast_GARCH
UBER_test[‘Predicted EGARCH’] = uber_forecast_EGARCH

DVN_test[‘Predicted ARCH’] = dvn_forecast_ARCH
DVN_test[‘Predicted GARCH’] = dvn_forecast_GARCH
DVN_test[‘Predicted EGARCH’] = dvn_forecast_EGARCH
#
UBER_test[‘Actual VAR’] = ((UBER_test[‘log_returns’] ** 2) ** 0.5)
DVN_test[‘Actual VAR’] = ((DVN_test[‘log_returns’] ** 2) ** 0.5)
#
plot_uber_test = UBER_test[[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’]].reset_index()
plot_dvn_test = DVN_test[[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’]].reset_index()
#
# # melt the data
plot_uber_melt_test = plot_uber_test.melt(id_vars=’Date’, value_vars=[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’])
plot_dvn_melt_test = plot_dvn_test.melt(id_vars=’Date’, value_vars=[‘Actual VAR’, ‘Predicted ARCH’, ‘Predicted GARCH’, ‘Predicted EGARCH’])

fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(15, 12))

sns.lineplot(data=plot_uber_melt_test,
x=’Date’,
y=»value»,
hue=»variable»,
palette=palette, ax=axes[0]).set_title(f»UBER Predicted vs Actual: Test Data»)

sns.lineplot(data=plot_dvn_melt_test,
x=’Date’,
y=»value»,
hue=»variable»,
palette=palette, ax=axes[1]).set_title(f»DVN Predicted vs Actual: Test Data»)

# plt.savefig(‘test_plot.png’, bbox_inches=’tight’)
plt.show()

Все три модели предсказывали будущие значения, близкие к 0. Исходя из масштаба оси Y, фактические значения также несколько близки к 0. Приведенный выше график увеличен только на тестовом наборе, когда мы уменьшаем масштаб и включаем некоторые обучающие данные, прогнозируемые значения по сравнению с фактическими выглядят …

Черный: фактическая переменная, зеленый: прогнозы в выборке, синий: прогнозы вне выборки

Включив некоторые результаты обучения в результаты теста, можно увидеть авторегрессионную природу модели. По сути, поскольку мы указали 1 в качестве значения для p и q , мы говорим, что значение дисперсии предыдущего дня, скорее всего, будет похоже на значение сегодняшнего. Небольшая разница между этими 2 будет заключаться в коэффициентах для членов ARCH, GARCH и асимметричного порядка. Пример коэффициентов и значимости модели ЕГАРХ можно найти ниже. Перечисленные коэффициенты были аппроксимированы с использованием результатов логарифмического журнала UBER в выборке.Constant Mean — EGARCH Model Results
==============================================================================
Dep. Variable: log_returns R-squared: 0.000
Mean Model: Constant Mean Adj. R-squared: 0.000
Vol Model: EGARCH Log-Likelihood: 2346.73
Distribution: Normal AIC: -4683.46
Method: Maximum Likelihood BIC: -4658.24
No. Observations: 1148
Date: Wed, Jan 17 2024 Df Residuals: 1147
Time: 13:43:11 Df Model: 1
Mean Model
=============================================================================
coef std err t P>|t| 95.0% Conf. Int.
——————————————————————————
mu 1.3562e-04 8.533e-04 0.159 0.874 [-1.537e-03,1.808e-03]
Volatility Model
===========================================================================
coef std err t P>|t| 95.0% Conf. Int.
—————————————————————————
omega -0.4047 0.194 -2.082 3.731e-02 [ -0.786,-2.379e-02]
alpha[1] 0.1951 5.647e-02 3.455 5.507e-04 [8.442e-02, 0.306]
gamma[1] -0.1100 3.488e-02 -3.154 1.610e-03 [ -0.178,-4.164e-02]
beta[1] 0.9407 2.814e-02 33.430 4.981e-245 [ 0.886, 0.996]
===========================================================================

Приведенный выше вывод представляет собой сводку модели EGARCH, подогнанную к логарифмическим возвратам данных временных рядов UBER. Омега, которая на самом деле выглядит как ω, является константой ⍺₀ в приведенных выше уравнениях. Альфа 1 — это коэффициент члена ARCH, ⍺i, где i = 1, учитывая, что мы смотрим только на 1 день назадГамма 1 – коэффициент для асимметричных нововведений, γn. Если вы заметили, значение равно < 0 , что указывает на то, что отрицательная логарифмическая доходность для UBER может привести к повышенной волатильности. Наконец, бета 1 — коэффициент для члена GARCH, βj. В качестве последней меры, прежде чем этот пост станет слишком длинным, мы можем построить график невязок наших прогнозов в выборке и вне выборки для каждой акции, чтобы оценить производительность.# Get the residuals of the training data
plot_uber[‘residuals_ARCH’] = plot_uber[«Predicted ARCH»] — plot_uber[«Actual VAR»]
plot_uber[‘residuals_GARCH’] = plot_uber[«Predicted GARCH»] — plot_uber[«Actual VAR»]
plot_uber[‘residuals_EGARCH’] = plot_uber[«Predicted EGARCH»] — plot_uber[«Actual VAR»]

plot_dvn[‘residuals_ARCH’] = plot_dvn[«Predicted ARCH»] — plot_dvn[«Actual VAR»]
plot_dvn[‘residuals_GARCH’] = plot_dvn[«Predicted GARCH»] — plot_dvn[«Actual VAR»]
plot_dvn[‘residuals_EGARCH’] = plot_dvn[«Predicted EGARCH»] — plot_dvn[«Actual VAR»]

# # Get the residuals of the testing data
plot_uber_test[‘residuals_ARCH’] = plot_uber_test[«Predicted ARCH»] — plot_uber_test[«Actual VAR»]
plot_uber_test[‘residuals_GARCH’] = plot_uber_test[«Predicted GARCH»] — plot_uber_test[«Actual VAR»]
plot_uber_test[‘residuals_EGARCH’] = plot_uber_test[«Predicted EGARCH»] — plot_uber_test[«Actual VAR»]

plot_dvn_test[‘residuals_ARCH’] = plot_dvn_test[«Predicted ARCH»] — plot_dvn_test[«Actual VAR»]
plot_dvn_test[‘residuals_GARCH’] = plot_dvn_test[«Predicted GARCH»] — plot_dvn_test[«Actual VAR»]
plot_dvn_test[‘residuals_EGARCH’] = plot_dvn_test[«Predicted EGARCH»] — plot_dvn_test[«Actual VAR»]

# melt the dataframes to plot each models’ residuals

plot_melt_uber = plot_uber[[‘Date’, ‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’]].melt(id_vars=[‘Date’],
value_vars=[‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’],
var_name=’model’,
value_name=’residuals’)

plot_melt_dvn = plot_dvn[[‘Date’, ‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’]].melt(id_vars=[‘Date’],
value_vars=[‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’],
var_name=’model’,
value_name=’residuals’)

plot_melt_uber_test = plot_uber_test[[‘Date’, ‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’]].melt(id_vars=[‘Date’],
value_vars=[‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’],
var_name=’model’,
value_name=’residuals’)

plot_melt_dvn_test = plot_dvn_test[[‘Date’, ‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’]].melt(id_vars=[‘Date’],
value_vars=[‘residuals_ARCH’, ‘residuals_GARCH’, ‘residuals_EGARCH’],
var_name=’model’,
value_name=’residuals’)
# plot the residuals
# set the palette
palette2 = {
‘residuals_ARCH’: ‘#009CDE’,
‘residuals_GARCH’: ‘#FF671F’,
‘residuals_EGARCH’: ‘#802AB8’}
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(15, 12))

sns.histplot(data=plot_melt_uber, x=’residuals’, hue=’model’, multiple=’dodge’, palette=palette2, ax=axes[0,0]).set_title(‘UBER Model Residuals: In-Sample’)
sns.histplot(data=plot_melt_uber_test, x=’residuals’, hue=’model’, multiple=’dodge’, palette=palette2, ax=axes[0,1]).set_title(‘UBER Model Residuals: Out-Sample’)
sns.histplot(data=plot_melt_dvn, x=’residuals’, hue=’model’, multiple=’dodge’, palette=palette2, ax=axes[1,0]).set_title(‘DVN Model Residuals: In-Sample’)
sns.histplot(data=plot_melt_dvn_test, x=’residuals’, hue=’model’, multiple=’dodge’, palette=palette2, ax=axes[1,1]).set_title(‘DVN Model Residuals: Out-Sample’)
# plt.savefig(«test_training_residual.png»)
plt.show()

Судя по графикам остатков, все три модели показали схожие результаты. По результатам значений MSE и RSME каждой модели, ARCH превзошел GARCH и EGARCH на обеих акциях. Метрики перечислены ниже. В идеале мы бы хотели, чтобы гистограмма была непосредственно центрирована вокруг 0 как для входящей, так и для исходящей выборки. Тем не менее, невязки в выборке, по-видимому, немного смещены влево, что благоприятствует положительным остаткам, а не предсказанию многих истинных значений. Для невязок из выборки мы недооцениваем волатильность, учитывая, что значения в основном отрицательные.********************* DVN Metrics *********************

Predicted ARCH: mse — 0.00018258658965947765 rmse — 0.013512460533133026
Predicted GARCH: mse — 0.00020081010478905026 rmse — 0.014170748208512149
Predicted EGARCH: mse — 0.00020475110392705913 rmse — 0.014309126595535421

********************* UBER Metrics *********************

Predicted ARCH: mse — 0.00020682898198136468 rmse — 0.01438155005489202
Predicted GARCH: mse — 0.00021730528452966247 rmse — 0.01474127825290814
Predicted EGARCH: mse — 0.000223535060993643 rmse — 0.014951088956783147

Заключение

3 модели ARCH, рассмотренные в этой статье, лишь поверхностно. Существует множество версий и реализаций ARCH. Понимание этих 3 поможет вам понять более сложные версии модели. По сути, модель ARCH обуславливает будущую прогнозируемую дисперсию или волатильность с предыдущей дисперсией. Он рассматривает природу волатильности как симметричную. Это означает, что как положительная, так и отрицательная доходность, если она экстремальна, скорее всего, увеличит волатильность. С другой стороны, EGARCH рассматривает волатильность с асимметричной точки зрения. Это означает, что положительный или отрицательный результат сам по себе приводит к повышенной волатильности. Будете ли вы использовать одну из моделей ARCH для прогнозирования волатильности? Если да, оставьте комментарий, я буду рад услышать об этом больше! Кроме того, если есть что-то, что стоит изучить, сделайте заметку, и я добавлю ее в свой растущий список тем для написания..

Ссылки

[1] Т. Боллерслев. 2009.Глоссарий к ARCH (GARCH). NBER и CREATES, (16 февраля 2009 г.)1-31. https://public.econ.duke.edu/~boller/Papers/glossary_arch.pdf

[2] К.Дальвид и.Гранберг.2017.Эффект кредитного плеча — раскрытие истинной природы асимметричной волатильности в США. Школа экономики и менеджмента Лундского университета.6–7.https://lup.lub.lu.se/luur/download?func=downloadFile&recordOId=8914682&fileOId=8914688

Глубокое погружение в модели ARCH и GARCH

Обзор

Если вы знакомы со статистическими моделями, вы, вероятно, работали с линейной регрессией, логистической регрессией и несколькими другими подходами к моделированию средних значений. Если нет, ничего страшного! Средняя модель — это просто модель, которая предсказывает среднее значение результата на основе одной или нескольких предикторных переменных. Эти средние модели широко используются в нескольких областях; Однако существует также ряд моделей для прогнозирования условной дисперсии, которые по-разному используются в финансовых данных.

Мы будем опираться на предыдущую публикацию Medium «Введение в модели ARMA с финансовыми данными», чтобы изучить модели ARCH (авторегрессионная условная гетероскедастичность) и GARCH (обобщенная авторегрессионная условная гетероскедастичность). Цель состоит в том, чтобы уйти с пониманием вводной экономической теории, концепции волатильности, мотивов и модельных утверждений ARCH и GARCH, признавая, когда эти модели уместны, реализацию модели и прогнозирование.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pmdarima as pm
import yfinance as yf

from arch import arch_model
from pmdarima.model_selection import train_test_split
from scipy.stats import chi2, jarque_bera
from sklearn.metrics import mean_absolute_percentage_error, mean_squared_error
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.stats.diagnostic import acorr_ljungbox
from statsmodels.tsa.stattools import acf, adfuller
from statsmodels.graphics.gofplots import qqplot
from statsmodels.tsa.arima.model import ARIMA

Импорт данных

Начнем с загрузки исторических данных S&P 500 ($SPY) из yfinance.

spy = yf.Ticker("SPY")
hist = spy.history(start = "2010-01-04", end = "2020-02-01")
df = pd.DataFrame(hist, columns=['Close'])
df.head
Date                                 
2010-01-04 00:00:00-05:00 88.117889
2010-01-05 00:00:00-05:00 88.351151
2010-01-06 00:00:00-05:00 88.413376
2010-01-07 00:00:00-05:00 88.786560
2010-01-08 00:00:00-05:00 89.082054
... ...
2020-01-27 00:00:00-05:00 307.216400
2020-01-28 00:00:00-05:00 310.435852
2020-01-29 00:00:00-05:00 310.179321
2020-01-30 00:00:00-05:00 311.185974
2020-01-31 00:00:00-05:00 305.535522

Фон

В предыдущем посте мы пришли к выводу, что цена закрытия S&P 500 может быть адекватно смоделирована с помощью модели случайного блуждания. Гипотеза эффективного рынка проиллюстрирует, почему модель случайного блуждания является подходящей, и приведет нас к рассмотрению методов учета риска и возможностей для получения прибыли в этих экономических рамках.

Гипотеза эффективного рынка:

Гипотеза эффективного рынка утверждает, что цена акции отражает эффективный рынок, то есть вся информация о компании отражается в текущей стоимости акций. Несмотря на споры, эта точка зрения лежит в основе многих экономических теорий. В соответствии с этой структурой не существует по существу безрисковой или минимально безрисковой фиксации прибыли, потому что нет рыночной неэффективности, которая приводит к разнице между текущей стоимостью акций и их фактической стоимостью, т. е. не может существовать арбитраж. Это означает, что последовательное обыгрывание рынка невозможно на основе информации о цене ценной бумаги до момента t, поскольку вся информация доступна публично через время t.

Математически это можно выразить следующим образом:

где Xt — текущая цена/доходность актива, и мы обусловливаем все предыдущие цены/доходность.

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

Летучесть

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

Мы можем связать эти два фактора — риск и волатильность — придерживаясь общей концепции, согласно которой чем выше волатильность, тем выше риск финансового актива. Мы можем визуализировать это различие следующим образом:

  • Цена акций компании А составляет 100 долларов, и мы уверены, что в следующем квартале она вырастет только на +/- 5%.
  • Цена акций компании B составляет 100 долларов, и мы уверены, что в следующем квартале она может колебаться в пределах +/- 50%.

Хотя это очень упрощенный пример, мы видим, что с дополнительной волатильностью компании B возникает дополнительное понятие риска с активом.

Кластеризация волатильности

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

Возвращает

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

Пусть Rt обозначает доходность актива в момент времени t, Pt обозначает цену актива в момент времени t, а Pt₋₁ обозначает цену актива в предыдущий период времени t-1. Мы можем сформулировать однопериодную доходность актива следующим образом:

Пусть rt обозначает логарифмический возврат, который чаще используется, потому что логарифмические возвраты имеют аддитивное свойство, которого нет у простых возвратов. Мы формулируем однопериодную логарифмическую доходность актива следующим образом:

# Convert prices to log returns 
df['Return'] = np.pad(np.diff(np.log(df['Close'])) * 100, (1, 0), 'constant', constant_values=np.nan)

Модель ARCH

Структура модели

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

Модель, которую мы будем использовать для этого, называется авторегрессивной условной гетероскедастической моделью порядка P, ARCH(P).

Напомним, что в различных случаях, таких как линейная регрессия и даже модель ARMA(p,q), нам нужна гомоскедастическая модель (постоянная дисперсия между наблюдениями). Однако в этом случае мы уточняем, что на самом деле существует гетероскедастичность (непостоянная дисперсия). Поскольку волатильность концептуально связана с дисперсией, нас интересует моделирование того, как дисперсия изменяется с течением времени.

Типовое заявление

где εt — IID(0,1), а b₀, b₁, … , bp > 0.

Xt может быть ценой, доходностью или логарифмической доходностью актива, смоделированной суммой его квадратов исторических значений X²t₋j. Для простоты мы определяем Xt как логарифмическую доходность актива.

В ожидании Xt² — это предельная дисперсия логарифмических возвратов. Почему это так? Вспомним зависимость между дисперсией и математическим ожиданием var(X) = E[X²] — E[X]². Мы знаем, что E[Xt] = 0, потому что ожидаемая доходность тривиально равна 0 из-за гипотезы эффективного рынка. Таким образом, E[Xt]² = 0, и мы остаемся с предельной дисперсией σ² = E[Xt²], которая постоянна и не зависит от t.

Мы опираемся на концепцию постоянной предельной дисперсии для включения гетероскедастичности путем моделирования волатильности во времени t (σt²), которая является условной дисперсией временного ряда и находится под непосредственным влиянием квадрата логарифмической доходности Xt².

Мы можем использовать все вышесказанное, чтобы интуитивно увидеть, что если Xt быстро колеблется (т. е. логарифмическая доходность быстро увеличивается или уменьшается), Xt² является высоким и, следовательно, волатильность σt² в момент времени t высока. Именно так модели ARCH фиксируют колебания цен и их влияние на волатильность базового актива.

Модель GARCH

Типовое заявление

где εt — IID(0,1) и b₀, b₁, … , bp,a₀, a₁, …, an ≠ 0.

Структура модели

GARCH является обобщенной авторегрессионной условной гетероскедастической моделью порядка (P,Q) и является расширением модели ARCH(P). Мы обратили внимание на дополнительный член, показанный выше при определении условной дисперсии (волатильности σt² в момент времени t), который позволяет моделировать условную дисперсию как зависимую от запаздывающих версий самой себя с использованием линейной комбинации a₀, a₁, … , an и условных дисперсий в предыдущие моменты времени. Это дополнение к заявлению модели делает модели GARCH более гибкими и способными фиксировать постоянство волатильности.

Таким образом, мы можем сократить оператор модели, разложив части модели на:

1) Эффекты ARCH: эффекты, приписываемые разрешению запаздывающих квадратов возврата логарифма Xt²

2) Эффекты GARCH: эффекты, приписываемые для учета запаздывающих условных дисперсий σt²

Исследовательский анализ данных

Мы начинаем фазу исследовательского анализа данных (EDA) с построения графика трассировки доходности с течением времени, чтобы визуализировать кластеризацию волатильности. Обратите внимание, что есть периоды с большей волатильностью, иллюстрируемые более высокими максимумами и более низкими минимумами, которые группируются вместе, и периоды, когда мы видим меньшую волатильность. Например, обратите внимание на неровный характер доходности S&P 500 в 2010-2012 годах (высокая волатильность) по сравнению с относительно стабильным периодом 2013-2015 годов (низкая волатильность).

# Add trace plot
plt.figure(figsize=(8,5))
plt.plot(df['Return'])
plt.ylabel("Return %")
plt.title('Returns of S&P 500');

Затем мы генерируем графики автокорреляции (ACF) и частичной автокорреляции (PACF), чтобы визуализировать, как предыдущие доходности с разными задержками коррелируют друг с другом. Напомним, что из-за свойств стационарности корреляция и ковариация в разные моменты времени должны быть одинаковыми для одного и того же промежутка, также известного как запаздывание h, независимо от точного момента времени t. То есть ACF и PACF должны быть постоянными на одном и том же запаздывании во времени и должны зависеть только от запаздывания h, а не непосредственно от t. Более подробное объяснение доступно в предыдущей статье.

# Plot ACF and PACF
diff_ts = df['Return'].iloc[1:]


fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
plot_acf(diff_ts, ax=ax1, lags=10)
ax1.set_ylim(-0.5, .5)
ax1.set_title("Autocorrelation in Returns")
plot_pacf(diff_ts, ax=ax2, lags=10)
ax2.set_ylim(-0.5, .5)
ax2.set_xlabel("Lag")
ax2.set_title("Partial Autocorrelation in Returns")

plt.show()

Приведенные выше графики ACF и PACF не указывают на наличие эффектов ARCH и GARCH. В частности, мы хотели бы, чтобы указание считало ряд ненезависимым, что визуально рассматривалось бы как запаздывания, для которых значения ACF и PACF находятся за пределами синей области. Это означало бы существенную разницу в ACF или PACF от 0 и позволило бы нам моделировать эффекты ARCH.

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

# Plot ACF and PACF of absolute returns
abs_returns = diff_ts.abs()

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
plot_acf(abs_returns, ax=ax1, lags=10)
ax1.set_ylim(-.5, .5)
ax1.set_title("Autocorrelation in Absolute Returns")
plot_pacf(abs_returns, ax=ax2, lags=10)
ax2.set_ylim(-.5, .5)
ax2.set_title("Partial Autocorrelation in Absolute Returns")
ax2.set_xlabel("Lag")

plt.show();

После описанного выше преобразования в абсолютную доходность теперь существует закономерность, указывающая на наличие эффектов ARCH и GARCH. В PACF нет большого падения примерно до запаздывания 4, что может указывать на то, что у нас должен быть порядок P,Q до 4. Для простоты и наглядности мы будем использовать модель GARCH(1,1) перед оценкой и тестированием различных спецификаций. Мы более формально проверим эти эффекты с помощью теста Маклеода-Ли для эффектов ARCH и GARCH. Нюансы и математические формулировки тестовой статистики ниже опущены, но концепция и гипотеза обобщены.

Тест Маклеода-Ли

Тест Маклеода-Ли предлагает следующие нулевые и альтернативные гипотезы для проверки поведения белого шума в остатках ряда:

H₀: во временном ряду отсутствуют эффекты ARCH

Hₐ: во временном ряду есть эффекты ARCH

Таким образом, мы сначала подгоняем модель GARCH(1,1), а затем применяем критерий Маклеода-Ли к остаткам. Результатом теста является p-значение < 0,001, и, таким образом, мы приходим к выводу, что во временном ряду существуют эффекты ARCH.

def mcleod_li_test(x, k):
"""
Calculates the McLeod-Li test statistic for a time series with k lags.
Returns the test statistic and its p-value.
"""
n = len(x)
x_sq = x ** 2
x_sum = np.sum(x_sq)
x_lag_sum = np.sum(x_sq[:-k])
test_stat = n * (n + 2) * x_lag_sum / (x_sum ** 2)
df = k
p_value = 1 - chi2.cdf(test_stat, df)
return test_stat, p_value
test_stat, p_value = mcleod_li_test(abs_returns, 50)
print("McLeod-Li test statistic: ", test_stat)
print("p-value: ", p_value)
McLeod-Li test statistic:  2929.754
p-value: 0.0

Подходит для модели GARCH (P, Q)

Ниже мы подогоняем модель GARCH(1,1) к данным. Мы реализуем этот процесс, используя разделение данных обучения и тестирования 80%/20%, при этом более свежие исторические данные служат тестовым набором.

Мы используем arch_model() из пакета arch и указываем, что данные имеют средний ноль и моделируются с помощью процесса GARCH. Мы указываем аргументы P,Q как 1,1 и предпочитаем не стандартизировать («перемасштабировать») данные.

# Fit GARCH (1,1)
y_train, y_test = train_test_split(abs_returns, train_size= 0.8)

garch_mod = arch_model(y_train, mean = "Zero", vol='Garch', p=1, q=1, rescale=False)
res_garch = garch_mod.fit()
Iteration:      1,   Func. Count:      5,   Neg. LLF: 4134.426614213216
Iteration: 2, Func. Count: 14, Neg. LLF: 3069.3112782531625
Iteration: 3, Func. Count: 20, Neg. LLF: 3281.6598598167393
Iteration: 4, Func. Count: 25, Neg. LLF: 2411.996065119879
Iteration: 5, Func. Count: 30, Neg. LLF: 2403.725012109664
Iteration: 6, Func. Count: 34, Neg. LLF: 2403.6940641153606
Iteration: 7, Func. Count: 38, Neg. LLF: 2403.691097819412
Iteration: 8, Func. Count: 42, Neg. LLF: 2403.6909625646995
Iteration: 9, Func. Count: 46, Neg. LLF: 2403.6908993457237
Iteration: 10, Func. Count: 49, Neg. LLF: 2403.6908993458132
Optimization terminated successfully (Exit mode 0)
Current function value: 2403.6908993457237
Iterations: 10
Function evaluations: 49
Gradient evaluations: 10

Мы вспоминаем приведенное выше утверждение модели GARCH(P,Q) и приводим оценки параметров в результате соответствия нашей модели GARCH:

где εt — IID(0,1) и b₀, b₁, … , bp,a₀, a₁, …, an ≠ 0.

Наша установленная модель выглядит следующим образом:

где σt² — условная дисперсия в момент времени t, X²t₋₁ — квадрат возврата в момент времени t-1, а σ²t₋₁ — условная дисперсия в момент времени t-1 .

Оценки параметров для модели GARCH(1,1): b₀= 0,0309, b₁= 0,14 и a₁= 0,82.

# Model summary 
print(res_garch.summary())
Zero Mean - GARCH Model Results                        
==============================================================================
Dep. Variable: Return R-squared: 0.000
Mean Model: Zero Mean Adj. R-squared: 0.000
Vol Model: GARCH Log-Likelihood: -2403.69
Distribution: Normal AIC: 4813.38
Method: Maximum Likelihood BIC: 4830.23
No. Observations: 2028
Date: Tue, May 16 2023 Df Residuals: 2028
Time: 13:10:35 Df Model: 0
Volatility Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
omega 0.0309 8.422e-03 3.667 2.450e-04 [1.438e-02,4.740e-02]
alpha[1] 0.1432 2.548e-02 5.621 1.900e-08 [9.329e-02, 0.193]
beta[1] 0.8196 2.771e-02 29.575 3.116e-192 [ 0.765, 0.874]
============================================================================

Covariance estimator: robust

Прогнозирование волатильности

Прогноз на N-шаг вперед

Используя модель GARCH сверху, мы можем прогнозировать волатильность σt² в момент времени t, которые являются нетривиальными предсказаниями. Модель делает эти прогнозы, получая доступ к данным из логарифмических возвратов Xt, из которых можно вычислить σt₊₁² (n-ступенчатый прогноз). Затем мы используем эти прогнозы, чтобы расширить прогноз волатильности до времен t+1, t+2, …, t+n. Мы не обновляем Xt постоянно по мере увеличения времени t, а скорее ограничиваем наши прогнозы на все будущие даты, которые будут сделаны исключительно на текущую дату.

На следующих графиках показана прогнозируемая волатильность с использованием этого метода.

# Forecast the test set 
yhat = res_garch.forecast(horizon = y_test.shape[0], reindex=True)
fig,ax = plt.subplots(figsize=(10,8))
ax.spines[['top','right']].set_visible(False)
# Plot test set returns
plt.plot(diff_ts[-y_test.shape[0]:])
# Plot volatility estimates for test set
plt.plot(y_test.index, np.sqrt(yhat.variance.values[-1,:]))
plt.title('S&P 500 Volatility Prediction')
plt.legend(['True Daily Log Returns', 'Predicted Volatility'])
# Conditional volatility by model fitting
res_garch.plot(annualize="D")

Скользящий прогноз на шаг вперед

Другим подходящим и более прагматичным подходом было бы делать прогнозы только на один шаг вперед на основе информации до времени t и обновлять информацию в модели в режиме реального времени по мере того, как время t становится временем t+1, t+2 и т.д. Проще говоря, с каждым днем мы обновляем Xt, Xt₊₁, Xt₊₂ с фактической, наблюдаемой отдачей от этого дня до модели на один шаг вперед.

Ниже мы видим, насколько хорошо этот скользящий прогноз волатильности способен отразить волатильность в наших невидимых тестовых данных.

rolling_preds = []

for i in range(y_test.shape[0]):
train = abs_returns[:-(y_test.shape[0]-i)]
model = arch_model(train, p=1, q=1, rescale = False)
model_fit = model.fit(disp='off')
# One step ahead predictor
pred = model_fit.forecast(horizon=1, reindex=True)
rolling_preds.append(np.sqrt(pred.variance.values[-1,:][0]))

rolling_preds = pd.Series(rolling_preds, index=y_test.index)
# Plot of predicted test data rolling volatility predictions
fig,ax = plt.subplots(figsize=(10,4))
ax.spines[['top','right']].set_visible(False)
plt.plot(rolling_preds)
plt.title('S&P 500 Rolling Volatility Prediction')
# Compare n-step-ahead and one-step-ahead rolling predictions
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
ax1.spines[['top','right']].set_visible(False)
ax1.plot(diff_ts[-y_test.shape[0]:])
ax1.plot(y_test.index, np.sqrt(yhat.variance.values[-1,:]))
ax1.set_title("S&P 500 Volatility N-Step Predictions")
ax1.legend(['True Daily Returns', 'Predicted Volatility'])

ax.spines[['top','right']].set_visible(False)
ax2.plot(diff_ts[-y_test.shape[0]:])
ax2.plot(y_test.index,rolling_preds)
ax2.set_title("S&P 500 Volatility Rolling Predictions")
ax2.legend(['True Daily Returns', 'Predicted Rolling Volatility'])
plt.show()

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

Диагностика модели

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

Тест Жарка-Бера

В модели GARCH(P,Q) мы делаем предположение о распределении наших ошибок: если модель указана правильно, то ошибки нормально распределяются со средним значением 0 и постоянной дисперсией. Тест Жарка-Бера проверяет, нормально ли распределены ошибки модели.

Формула тестовой статистики выглядит следующим образом:

где n — размер данных, S — асимметрия выборки (которая измеряет симметрию данных относительно среднего), а K — эксцесс выборки (который измеряет форму распределения, особенно хвостов).

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

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

H₀: данные имеют нормальное распределение.

Hₐ: данные не имеют нормального распределения.

# Calculate the standardized residuals on the test data
std_resid = res_garch.resid / res_garch.conditional_volatility

# Perform Jarque-Bera test using scipy.stats
jb_test = jarque_bera(std_resid)
print("Jarque-Bera test statistic:", jb_test[0])
print("p-value:", jb_test[1])
Jarque-Bera test statistic: 1950.9105880383472
p-value: 0.0

Тест Жарка-Бера показывает нам, что у нас нет стандартизированных остатков, которые следуют нормальному распределению. Несмотря на то, что это выходит за рамки этого поста, следующим шагом является указание различных распределений в модели GARCH, которые являются более тяжелыми для терминов ошибок, таких как t-распределение Стьюдента.

Заключение

Наш путь к моделям ARCH и GARCH увел нас от общей структуры моделирования средних значений к моделированию дисперсий. Это привело нас к экономике и гипотезе эффективного рынка и тщательно изучило математику, которая строит эти мощные модели. Это дало нам инструменты на этапе EDA для определения того, когда следует использовать модели ARCH и GARCH. Мы подогнали модели и построили прогнозы, которые можно было бы делать на скользящей основе, чтобы предсказать волатильность наиболее практичным способом. Наконец, мы закончили исследованием того, что мы можем сделать, чтобы улучшить нашу модель, тонко изменив наши предположения.

Наконец, мы можем изменить подходы ARCH и GARCH по-разному. Важно отметить, что мы можем объединить этот подход GARCH с моделью ARMA, чтобы создать модель ARMA + GARCH. Следите за обновлениями в следующем посте, чтобы прочитать об этом универсальном подходе!

Волатильность S&P500: модели ARCH и GARCH

Знакомство

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

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

Цель этой статьи — кратко рассмотреть, как можно использовать статистические методы для прогнозирования, понять, что такое финансовые данные временных рядов и как модели ARCH и GARCH можно использовать для прогнозирования волатильности.

Библиотеки, которые вам нужно будет установить в собственной среде Python для этого эксперимента, — это библиотека yfinance для получения финансовых данных и библиотека arch, которая используется для моделирования моделей ARCH и GARCH.

Чтобы увидеть этот полный проект на Kaggle, вы можете прочитать мой ??ноутбук S&P500 Volatility: ARCH vs GARCH Models.

Данные S&P 500

Библиотека yfinance используется для получения исторических данных для S&P 500, который является эталоном американского фондового рынка. Исторические данные охватывают весь период с 30 декабря 1927 года по 17 апреля 2023 года.

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

# Obtaining historic data on the SP500
sp = yf.download('^GSPC')
sp

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

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

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

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

Однако, прежде чем перейти к этому, мы можем провести статистический тест, чтобы подтвердить, является ли скорректированная цена закрытия S&P 500 случайным блужданием или нет, даже если график предполагает, что это так. Для этого мы будем использовать тест Дики-Фуллера.

Тест Дики-Фуллера

В статистике тест Дики-Фуллера проверяет нулевую гипотезу о том, что единичный корень присутствует в авторегрессионной модели временных рядов, что указывает на то, что ряд является случайным блужданием. Простая авторегрессионная (AR) модель задается следующим уравнением:

y= ρyt₋₁ + ut

Где yt — зависимая переменная в момент времени tρ — коэффициент, а ut — член ошибки. Если ρ = 1, в ряду есть единичный корень.

Используя библиотеку Statsmodels, мы можем легко выполнить этот тест. Функция adfuller даст нам p-значение, чтобы отвергнуть или не отвергнуть нулевую гипотезу. Если p-значение равно 1, то это подтверждает, что в скорректированной цене закрытия для S&P 500 есть единичный корень и, следовательно, это случайное блуждание, которое должно быть детрендом.

# Testing for stationary or non-stationary data 
adf_test = sm.tsa.stattools.adfuller(sp['Adj Close'])
print(f'p-value = {adf_test[1]}')
p-value = 1.0

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

Детренд серии S&P 500

Чтобы смоделировать S&P 500, нам нужно будет детрендить серию. Самый простой способ сделать это — рассчитать процентное изменение ежедневных цен закрытия и получить ежедневную доходность для S&P 500.

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

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

Моделирование волатильности: модели ARCH и GARCH

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

Прежде чем оценить, достаточно ли использовать модели ARCH для моделирования волатильности данных S&P 500, нам необходимо протестировать влияние ARCH на данные. В приведенном ниже коде мы подгоняем модель GARCH к данным, а затем получаем квадрат остатков модели, чтобы проверить, есть ли в данных гетероскедастичность. Если p-значение ниже 0,05, это означает, что в данных присутствует эффект ARCH, и мы можем использовать модели ARCH для прогнозирования волатильности.

# Testing for the ARCH effect
model = arch.arch_model(sp['returns'], vol = 'GARCH', p = 1, q = 1, rescale = False)
results = model.fit(disp='off',show_warning = False)
residuals = results.resid
squared_residuals = residuals**2
arch_test = sm.stats.diagnostic.het_arch(squared_residuals)
print(f'ARCH test results:\n')
print(f'LM Statistic: {arch_test[0]}')
print(f'p-value: {arch_test[1]}')
print(f'F Statistic: {arch_test[2]}')
print(f'p-value: {arch_test[3]}')
ARCH test results:

LM Statistic: 157.53089980719574
p-value: 1.0472830360159583e-28
F Statistic: 15.850206645654502
p-value: 8.359066280122928e-29

Оба теста LM и F имеют p-значения 1.0472830360159583e-28 и 8.359066280122928e-29 соответственно. Оба значения находятся в экспоненциальном представлении и представляют собой очень небольшие числа, которые намного ниже порога 0,05, что говорит о том, что в данных существует эффект ARCH, и мы можем использовать эти модели для прогнозирования волатильности.

ARCH(1)

Модель ARCH(1) предполагает, что дисперсия текущего члена определяется квадратом погрешности прошлого значения. Он также предполагает, что дисперсия ошибок не постоянна и что волатильность имеет тенденцию к кластеризации. Это определяется следующим уравнением:

σ²t=ω+αε²t ₋ ₁

Где σ²t представляет собой дисперсию члена ошибки в данный момент времени t, ω — константа, представляющая безусловную дисперсию, α₁ — коэффициент члена запаздывающего квадрата ошибки, а ε²t ₋ ₁ — член квадрата ошибки в момент времени t, который является прямым предыдущим значением.

В приведенном ниже коде мы подгоняем модель ARCH(1) к данным и получаем ее сводку, чтобы увидеть коэффициенты и то, насколько хорошо модель соответствует данным.

# Fitting ARCH(1) model
model = arch.arch_model(sp['returns'],
vol = 'ARCH',
p = 1, # One lag of the squared residuals
rescale = False)
results = model.fit(disp = 'off', show_warning = False)
print(results.summary()) # Plotting summary
Constant Mean - ARCH Model Results                      
==============================================================================
Dep. Variable: returns R-squared: 0.000
Mean Model: Constant Mean Adj. R-squared: 0.000
Vol Model: ARCH Log-Likelihood: 74390.0
Distribution: Normal AIC: -148774.
Method: Maximum Likelihood BIC: -148750.
No. Observations: 23936
Date: Mon, Apr 17 2023 Df Residuals: 23935
Time: 21:46:31 Df Model: 1
Mean Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
mu 5.6718e-04 8.473e-05 6.694 2.167e-11 [4.011e-04,7.332e-04]
Volatility Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
omega 7.9117e-05 2.066e-06 38.297 0.000 [7.507e-05,8.317e-05]
alpha[1] 0.4500 3.044e-02 14.785 1.831e-49 [ 0.390, 0.510]
============================================================================

Covariance estimator: robust

Приведенная выше сводка показывает нам результаты подгонки модели ARCH(1) к данным. Расчетный коэффициент для среднего значения составляет 5,6718e-04, и он считается статистически значимым при p-значении ниже 0,05.

Модель волатильности оценивает параметры модели ARCH(1), где омега постоянна на уровне 7,9117e-05, а альфа[1] — коэффициент для запаздывающих квадратов остатков на уровне 0,4500. Оба являются статистически значимыми с их p-значениями ниже порога 0,05.

Эти результаты дают нам статистические доказательства того, что модель ARCH(1) подходит для моделирования волатильности доходности для S&P 500

ARCH(2)

Модель ARCH(2) является расширением предыдущей модели и предполагает, что дисперсия текущего члена определяется суммой квадратов двух последних членов ошибки. Он также предполагает, что дисперсия ошибок не постоянна и что волатильность имеет тенденцию к кластеризации. Это определяется следующим уравнением:

σ²t=ω+α₁ε²t ₋ ₁ + αε²t ₋ ₂

Где σ²t представляет собой дисперсию члена ошибки в данный момент времени t, ω — константа, представляющая безусловную дисперсию, α₁ и α₂ — коэффициенты квадратов членов ошибки из двух предыдущих периодов времени, а ε²t ₋ ₁ и ε²t ₋ ₂ — квадрат погрешности в момент времени t — 1 и времени t — 2 .

Чтобы подогнать модель ARCH(2) к данным, мы можем использовать тот же подход, что и для модели ARCH(1), но теперь указав p=2, чтобы указать, что модель является моделью ARCH(2).

# Fitting ARCH(2) model
model = arch.arch_model(sp['returns'],
vol = 'ARCH',
p = 2, # Two lags of the squared residuals
rescale = False)
results = model.fit(disp = 'off', show_warning = False)
print(results.summary())
Constant Mean - ARCH Model Results                      
==============================================================================
Dep. Variable: returns R-squared: 0.000
Mean Model: Constant Mean Adj. R-squared: 0.000
Vol Model: ARCH Log-Likelihood: 75909.5
Distribution: Normal AIC: -151811.
Method: Maximum Likelihood BIC: -151779.
No. Observations: 23936
Date: Mon, Apr 17 2023 Df Residuals: 23935
Time: 21:46:31 Df Model: 1
Mean Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
mu 6.1953e-04 6.947e-05 8.918 4.767e-19 [4.834e-04,7.557e-04]
Volatility Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
omega 5.7544e-05 1.617e-06 35.583 2.568e-277 [5.437e-05,6.071e-05]
alpha[1] 0.3000 2.226e-02 13.475 2.206e-41 [ 0.256, 0.344]
alpha[2] 0.3000 2.010e-02 14.926 2.229e-50 [ 0.261, 0.339]
============================================================================

Covariance estimator: robust

Расчетный коэффициент для среднего значения составляет 6,1953e-04, и он считается статистически значимым при p-значении ниже 0,05.

Модель волатильности оценивает параметры модели ARCH(2), где омега постоянна на уровне 5,7544e-05, а альфа[1] и альфа[2] являются коэффициентами для запаздывающих квадратичных остатков на уровне 0,3000. Все параметры статистически значимы, их p-значения ниже порога 0,05.

Эти результаты дают нам статистические доказательства того, что модель ARCH(2) также подходит для моделирования волатильности доходности для S&P 500

GARCH(1,1)

Модель GARCH(1,1) является расширением модели ARCH, которая учитывает сохранение волатильности во времени. Он предполагает, что дисперсия члена ошибки в данный момент времени является функцией прошлых членов квадрата ошибки и прошлых условных дисперсий. Это определяется следующим уравнением:

σ²t=ω+α₁ε²t ₋ ₁+β₁ε²t ₋ ₂

Где σ²t представляет собой условную дисперсию члена ошибки в данный момент времени t, ω — константа, представляющая безусловную дисперсию, α₁ и β₁ — коэффициенты квадрата членов ошибки в момент времени t — 1 соответственно, а ε²t ₋ ₁ — квадрат члена ошибки в момент времени t — 1.

Мы также можем подогнать GARCH(1,1) с помощью библиотеки arch, передав GARCH в параметре vol и определив p=1 и q=1 .

# Fitting GARCH(1,1) model
model = arch.arch_model(sp['returns'],
vol = 'GARCH', # GARCH model
p = 1,
q = 1)
results = model.fit(disp = 'off', show_warning = False)
print(results.summary())
Constant Mean - GARCH Model Results                      
==============================================================================
Dep. Variable: returns R-squared: 0.000
Mean Model: Constant Mean Adj. R-squared: 0.000
Vol Model: GARCH Log-Likelihood: -31761.8
Distribution: Normal AIC: 63531.7
Method: Maximum Likelihood BIC: 63564.0
No. Observations: 23936
Date: Mon, Apr 17 2023 Df Residuals: 23935
Time: 21:46:32 Df Model: 1
Mean Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
mu 0.0528 5.693e-03 9.267 1.911e-20 [4.160e-02,6.391e-02]
Volatility Model
============================================================================
coef std err t P>|t| 95.0% Conf. Int.
----------------------------------------------------------------------------
omega 0.0105 1.789e-03 5.852 4.861e-09 [6.964e-03,1.398e-02]
alpha[1] 0.0970 9.191e-03 10.551 5.007e-26 [7.896e-02, 0.115]
beta[1] 0.8988 8.792e-03 102.235 0.000 [ 0.882, 0.916]
============================================================================

Covariance estimator: robust

Расчетный коэффициент для среднего значения составляет 0,0528, и он также считается статистически значимым с p-значением ниже 0,05.

Модель волатильности оценивает параметры модели GARCH(1,1), где омега постоянна на уровне 0,0105, а альфа[1] и бета[1] являются коэффициентами для запаздывающих квадратичных остатков на уровне 0,0970 и 0,8988 соответственно. Все параметры статистически значимы, их p-значения ниже порога 0,05.

ARCH(1), ARCH(2) или GARCH(1,1)?

Чтобы решить, какая из трех приведенных выше моделей лучше всего подходит для данных, мы должны посмотреть на значения AIC и BIC. Это статистические метрики, которые можно использовать для сравнения производительности разных моделей. AIC (информационный критерий Акаике) оценивает объем информации, потерянной моделью, и задается следующим уравнением:

AIC=2k−2ln(L)

Где k — количество параметров в модели, а L — оценка максимального правдоподобия функции правдоподобия для модели. Учитывая, что AIC оценивает объем потерянной информации, можно сделать вывод, что чем ниже ее значение, тем лучше модель.

BIC (байесовский информационный критерий) аналогичен AIC, но имеет другой срок наказания. Уравнение для BIC выглядит следующим образом:

BIC=kln(n)−2ln(L)

Где L — функция максимального правдоподобия модели, k — количество параметров, n — размер выборки. Опять же, предпочтение отдается модели с наименьшим значением BIC.

Наблюдая за приведенными выше сводками, становится ясно, что модель ARCH(2) наилучшим образом соответствует данным с AIC -151811 и BIC -151779 и может быть использована для прогнозирования волатильности на S&P 500.

Почему GARCH-модели терпят неудачу вне выборки

Это третий пост из короткой серии постов об экстремальных событиях в финансовых временных рядах. В первом посте мы представили теорию степенного закона для описания и экстраполяции вероятности экстремальных движений цены индекса S&P500. Во второй статье мы подробно рассмотрели, как статистические моменты могут стать бесконечными при наличии степенных хвостов, что делает обычные оценки бесполезными. В этом посте мы исследуем последствия бесконечных моментов, показывая, как популярная модель риска GARCH почти идеально описывает данные в выборке, но не может экстраполировать на данные вне выборки.

Вы можете получить доступ к интерактивной версии этой записи блога на Python здесь. Он работает на базе JupyterLite и запускается прямо в вашем браузере без какой-либо установки или настройки!

В предыдущем посте «Бесконечный эксцесс» мы смоделировали логарифмическую доходность rt индекса S&P500 с t-распределением Стьюдента со степенной хвостовой экспонентой α=3.7 (см. ниже, слева). Затем мы продолжили показывать, что эксцесс (четвертый статистический момент, измеряющий вероятность экстремальных значений) распределения с этой степенной экспонентой бесконечен. Важно отметить, что если мы оцениваем эксцесс выборки по историческим данным, мы всегда получим конечную оценку, но эта оценка не будет справедливой в будущем и будет продолжать расти всякий раз, когда в S&P500 появляется новая экстремальная доходность (см. ниже, справа). В этом посте мы рассмотрим, как популярная модель риска GARCH вводится в заблуждение из-за эксцесса конечной выборки, не экстраполируемой за пределы исторических событий!

Широко распространено мнение, что обобщенные модели авторегрессионной условной гетероскедастичности (GARCH) дают точные описания распределений доходности, поскольку они способны воспроизводить многие аномальные свойства выборочных распределений доходности, позволяя волатильности время от времени увеличиваться, тем самым имитируя самоусиливающуюся природу волатильности во время крахов и ралли. Тем не менее, мы утверждаем, что этой способности точно описать статистические свойства любой конечной выборки данных недостаточно, и что модели GARCH всегда будут удивляться новым экстремальным событиям, потому что они не экстраполируют дальше того, что уже было замечено. В простейшей модели GARCH(1,1) с постоянным ценовым трендом μ логарифмические доходы rt моделируются как

с дисперсией случайных случайных флуктуаций εt, определяемой с помощью следующей рекурсии:

Обратите внимание, что дисперсия (и, следовательно, волатильность) зависит как от предыдущей дисперсии, так и от реализованной логарифмической доходности. Заметим также, что, хотя приведенное выше уравнение определяет дисперсию εt, мы все равно можем выбрать различные распределения для получения значений. По умолчанию используется распределение Гаусса, но можно также выбрать распределение с более тяжелым хвостом, например, распределение Стьюдента-t. В Python GARCH-модели могут быть легко реализованы с помощью хорошо документированного пакета. Чтобы лучше понять модель GARCH(1,1), мы моделируем альтернативные истории S&P500 на основе подогнанных значений параметров GARCH(1,1).

Сравнивая смоделированные данные с реальными историческими данными, мы можем узнать несколько вещей: GARCH(1,1) довольно хорошо справляется с моделированием всплесков волатильности, в отношении частоты и величины пиков, и он создает реалистично выглядящие кривые акций с обвалами и ралли. Кроме того, мы замечаем, что все симуляции достигают большей совокупной доходности по сравнению с реальным индексом S&P500. Основная причина такой чрезмерно хорошей производительности заключается в том, что модель GARCH(1,1) в том виде, в каком она определена здесь, не допускает асимметрии, в то время как известно, что отрицательный хвост распределения реальной доходности показывает более экстремальные значения, чем положительный хвост.

Мы можем улучшить это, явно добавив асимметрию как к самому GARCH-процессу (в результате чего получилась модель GJR-GARCH с дополнительным параметром γ), так и к распределению, из которого мы черпаем наши шумовые члены εt (выбор стандартизованного распределения Стьюдента с асимметрией, см. здесь и здесь для получения дополнительной информации). Опять же, мы можем легко подогнать эту модель к нашим данным с помощью , а затем посмотреть, соответствуют ли результаты теперь истинному индексу S&P500:

Действительно, при учете асимметрии в распределении доходности (т.е. обвалы в среднем имеют большую величину, чем ралли), мы получаем лучшее соответствие реальным данным. Теперь, когда у нас есть некоторое представление о том, как работает модель GARCH, и мы увидели, что она довольно хорошо аппроксимирует прошлые данные S&P500, мы можем приблизиться к сложному недостатку модели GARCH. Чтобы проиллюстрировать этот недостаток, мы снова обратимся к высшим моментам распределения отдачи, а именно к эксцессу. Проблема в том, что самая сильная сторона GARCH, а именно возможность точно моделировать почти все статистические свойства имеющихся данных, является также и его самой большой слабостью, когда речь идет о жирных хвостах финансовых временных рядов.

В предыдущей статье этой короткой серии статей мы видели, что эксцесс распределения со степенными хвостами и степенной степенью α=3,7 (адаптированный к доходности S&P500) на самом деле бесконечен. Хотя мы можем косвенно вывести это свойство из степенной статистики, мы никогда не увидим бесконечного эксцесса выборки. Все выборки данных, которые у нас когда-либо будут, конечны, у нас есть определенное количество дней/месяцев/лет, чтобы оглянуться назад, и, таким образом, мы всегда можем оценить эксцесс выборки и получить какое-то конечное значение. И GARCH поддается этому: он видит конечное значение эксцесса выборки имеющихся данных, а затем воспроизводит это значение, вместо того, чтобы экстраполировать, как степенная модель. Таким образом, фокус GARCH на видимых данных, а не на еще невидимых данных, которые могут появиться в будущем, приведет к недооценке масштабов будущих аварий. Конечно, после следующей более крупной, чем когда-либо, аварии эксцесс образца возрастет, и GARCH будет следить за новым эксцессом образцов и точно моделировать его, но только после того, как ущерб будет нанесен.

Мы можем хорошо проиллюстрировать этот эффект, используя функцию моделирования пакета. Опять же, мы подгоняем реальную серию доходностей S&P500, используя базовую GARCH(1,1) с гауссовским шумом, и асимметричную GARCH(1,1) с искаженным шумом Стьюдента-t. В обоих случаях мы моделируем 500 гипотетических лет динамики S&P500. Наконец, как и раньше, когда мы обсуждали стабильность более высоких статистических моментов, мы вычисляем эксцесс выборки с течением времени, чтобы увидеть, как оценка изменяется с течением времени по мере того, как становится доступно все больше и больше данных нашего 500-летнего моделирования.

Результаты, которые мы получаем в результате этого моделирования, весьма показательны: эксцесс стандартного, симметричного процесса GARCH стабилизируется вокруг эксцесса выборки доходностей S&P500 без учета худшего дня, Черного понедельника 1987 года. Поскольку левый хвост обратного распределения S&P500 более экстремален, чем правый, подгонка симметричного процесса, естественно, приведет к недооценке вероятности экстремальных событий в левом хвосте и переоценке вероятности экстремальных событий в правом хвосте. Поскольку «черный понедельник» находится в крайнем левом хвосте и составляет около половины эксцесса выборки, симметричный процесс GARCH в конечном итоге воспроизводит эксцесс выборки, исключая эту точку данных.

Асимметричный GARCH-процесс может учесть более тяжелый левый хвост обратного распределения и, таким образом, хорошо воспроизводит эксцесс выборки данных. Однако оба этих GARCH-процесса попадают в ловушку бесконечных моментов: они воспроизводят эксцесс конечной выборки, тогда как в действительности эксцесс бесконечен. На графике выше мы также показываем пример эксцесса распределения Стьюдента-t со степенной хвостовой экспонентой $\alpha=3.7$, как мы подгоняли ранее в этой лекции. Как мы видим, эксцесс выборки степенной модели не стабилизируется, а поднимается все выше и выше, вплоть до ~100 раз превышающего эксцесс выборки данных в течение моделируемых нами 500 лет, ясно указывая на то, что истинное значение эксцесса равно бесконечности.

Режим волатильности по GARCH(1,1)&Markov

Цели:

1. Динамическое моделирование волатильности с обобщенной авторегрессионной условной гетероскедастичностью — GARCH(1,1)

2. Оптимизация параметров модели волатильности

3. Классификация режимов волатильности с помощью марковских моделей

4. Оценка эффективности классификационной модели

(Во-первых, получение пакетов и данных)

https://medium.com/media/827480a18dd9c9212931a56961e95cff

1. Анализ распределения возврата:

Мы рассмотрим высшие моменты обратного распределения. Этот шаг важен, так как он повлияет на входные данные модели волатильности.

https://medium.com/media/0072b7480ca58fddf32fd51342d4f656

https://medium.com/media/48314c00f630b567ac70589c1cbfa014

Return distribution

Затем мы будем использовать статистические тесты, чтобы определить, имеет ли распределение «нулевое среднее», а также следует ли распределение нормальному распределению. Эти тесты важны для определения допущений модели волатильности, таких как средняя модель и предположения о распределении.

https://medium.com/media/ed1d32d2b0ed98d7aa729572ea3b5023

https://medium.com/media/4751def0a17d2d1913f68a4d94586f87

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

2. Моделирование GARCH(1,1)

На основе полученных выше результатов мы построим модель волатильности и оптимизируем параметры (Оптимизация встроена в функцию).

Пакет ARCH автоматически выполнит оптимизацию параметров модели.

Поскольку распределение доходности не является нормальным, мы можем выбрать альтернативные распределения для моделирования волатильности.

Здесь мы используем гетерогенное авторегрессионное среднее и искаженное распределение t Стьюдента, основанное на максимальной вероятности.

https://medium.com/media/cf22326e90b38bfd386edb5c659fa835

https://medium.com/media/0d970e796ecec665005215deeae35f25

Теперь, оптимизировав эти параметры модели, мы вычисляем долгосрочную дисперсию по GARCH по формуле:

Долгосрочная дисперсия = омега / (1 — альфа — бета)

Красная линия показывает стандартное отклонение выборки, а зеленая — нашу оценку от GARCH.

Мы можем сравнить модель волатильности рынка с индексом VIX. Как мы видим, подразумеваемая волатильность выше, чем условная волатильность, поскольку рынок может не предполагать нейтральности риска.

Если мы построим график разницы, мы увидим, что она выше. (На всякий случай)

3. Скрытая марковская модель

Сейчас модель Скрытого Маркова является одной из часто упоминаемых, возможно, благодаря успеху технологии эпохи Возрождения. Итак, мы рассмотрим производительность модели, как улучшить модель, и действительно ли предположения верны. Сначала мы подгоним модель, используя временной ряд GARCH.

https://medium.com/media/f9c94fd39d4884ef4dffa535e6873a5a

https://medium.com/media/37b59979218ffe8c510f862757958968

После очистки выходных данных мы можем нанести их на диаграмму с областями. (Обратите внимание, что маркировка на этой диаграмме неверна)

4. Марковская коммутационная авторегрессионная модель

Эта модель была освещена в нескольких статьях. Мое внимание привлек документ ЕЦБ. Хотя это не точная реплика из-за моих ограниченных математических знаний, я все же попытался улучшить HMM с помощью примеров и реализации оригинальной статьи авторов о статистических моделях.

https://medium.com/media/1b2ada8dfc64c7d7b9217fde10f9e11f

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

https://medium.com/media/fde9d4b1b0a0294483c64ca42800be89

https://medium.com/media/60422c3bdbeb1aeb1d7ef923fa10fccb

Источник

Источник

Источник

Источник

Источник