Прогнозирование волатильности с использованием GARCH в Python - пакет Arch - PullRequest
0 голосов
/ 23 января 2020

Я тестирую пакет ARCH для прогнозирования дисперсии (стандартного отклонения) двух серий с использованием GARCH (1,1).

Это первая часть моего кода

import pandas as pd
import numpy as np
from arch import arch_model


returns = pd.read_csv('ret_full.csv', index_col=0)
returns.index = pd.to_datetime(returns.index)

Ibovespa Returns

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

Первая проблема, которую я обнаружил, заключается в том, что вы необходимо изменить масштаб выборки на 100. Для этого вы можете умножить свой возвращаемый ряд на 100 или установить параметр rescale=True в функции arch_model.

Зачем это нужно делать?

# Ibov
ret_ibov = returns['IBOV_1st']
model_ibov = arch_model(ret_ibov, vol='Garch', p=1, o=0, q=1, dist='Normal', rescale=True)
res_ibov = model_ibov.fit()

После подбора модели я прогнозирую дисперсию (всего 5 шагов, чтобы проиллюстрировать проблему), получить стандартное отклонение и сделать это в годовом исчислении. Obs: Поскольку мне пришлось изменить масштаб моего ряда возврата, я делю свой прогноз на 10000 (100 ** 2, из-за изменения масштаба)

# Forecast
forecast_ibov = res_ibov.forecast(horizon=5)

# Getting Annualized Standard Deviation
# Garch Vol
vol_ibov_for = (forecast_ibov.variance.iloc[-1]/10000)**0.5 * np.sqrt(252) * 100
# Observed Vol
vol_ibov = ret_ibov.std() * np.sqrt(252) * 100

И это результат прогноза

vol_ibov_for
h.1    24.563208
h.2    24.543245
h.3    24.523969
h.4    24.505357
h.5    24.487385

Что действительно близко к Observed Vol 23.76

Это результаты, которые я ожидал.

IRFM Возвращает

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

# IRFM
ret_irfm = returns['IRFM1M']
model_irfm = arch_model(ret_irfm, vol='Garch', p=1, o=0, q=1, dist='Normal', rescale=True)
res_irfm = model_irfm.fit()

# Forecast
forecasts_irfm = res_irfm.forecast(horizon=5)

# Getting Annualized Standard Deviation
# Garch Vol
vol_irfm_for = (forecasts_irfm.variance.iloc[-1]/10000)**0.5 * np.sqrt(252) * 100
# Observed Vol
vol_irfm = ret_irfm.std() * np.sqrt(252) * 100

Прогноз на выходе:

vol_irfm_for
h.1    47.879679
h.2    49.322351
h.3    50.519282
h.4    51.517356
h.5    52.352894

И это значительно отличается от наблюдаемой волатильности 5.39

Почему это происходит? Может быть из-за масштабирования? Должен ли я сделать еще одну корректировку до прогноза?

Спасибо

1 Ответ

0 голосов
/ 23 января 2020

Найден ответ.

rescale=True используется, когда модель не может сходиться к результату. Таким образом, масштабирование может быть решением проблемы. Если модель не требует масштабирования, даже если параметр True, она ничего не будет делать.

Точка попытки : Если rescale=True и, фактически, пересмотрел серию. Необходимо настроить выходы. В моем вопросе я был озадачен тем, насколько высока моя волатильность. Это потому, что я предполагал, что мои значения масштабирования были равны 100, что необязательно является истинным значением.

Правильно было бы установить для параметра значение True и получить после этого значение масштабирования.

Для этого просто нужно вставить следующий код:

# IRFM
ret_irfm = returns['IRFM1M']
model_irfm = arch_model(ret_irfm, vol='Garch', p=1, o=0, q=1, dist='Normal', rescale=True, mean='Zero')
res_irfm = model_irfm.fit()
scale = res_irfm.scale  # New part of the code

# Forecast
forecasts_irfm = res_irfm.forecast(horizon=5)

# Getting Annualized Standard Deviation
# Garch Vol
# New part of the code: Divide variance by scale^2
vol_irfm_for = (forecasts_irfm.variance.iloc[-1] / np.power(scale, 2))**0.5 * np.sqrt(252) * 100 
# Observed Vol
vol_irfm = ret_irfm.std() * np.sqrt(252) * 100

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

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...