在 Python 中使用 GARCH 预测波动率 - Arch Package
Forecasting Volatility using GARCH in Python - Arch Package
我正在测试 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
第一个系列是 Ibovespa 指数的第一个期货合约,观察到的年化波动率非常接近 Garch 预测。
我发现的第一个问题是您需要将样本重新缩放 100。为此,您可以将 return 系列乘以 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:因为我不得不重新调整我的 return 系列,我将我的预测除以 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
这非常接近观察量 23.76
这是我期待的结果。
IRFM Returns
当我对波动较小的系列执行完全相同的处理时,我得到了一个非常奇怪的结果。
# 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
为什么会这样?也许是因为重新缩放?我是否必须在预测前进行另一次调整?
谢谢
找到答案。
当模型无法收敛到结果时使用rescale=True
。因此重新缩放可能是解决问题的方法。如果模型不需要rescale,即使参数是True
,它也不会做任何事情。
Point of Attempion:如果rescale=True
,事实上,重新调整了系列。有必要调整输出。在我的问题中,我对我的波动率有多高感到困惑。那是因为我假设我的重新缩放值是 100,这不一定是真的。
正确的做法是将参数设置为True,然后获取rescale值。
为此,只需插入以下代码:
# 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
希望这对遇到同样问题的其他用户有所帮助。这是一件非常简单的事情。
谢谢。
我正在测试 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
第一个系列是 Ibovespa 指数的第一个期货合约,观察到的年化波动率非常接近 Garch 预测。
我发现的第一个问题是您需要将样本重新缩放 100。为此,您可以将 return 系列乘以 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:因为我不得不重新调整我的 return 系列,我将我的预测除以 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
这非常接近观察量 23.76
这是我期待的结果。
IRFM Returns
当我对波动较小的系列执行完全相同的处理时,我得到了一个非常奇怪的结果。
# 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
为什么会这样?也许是因为重新缩放?我是否必须在预测前进行另一次调整?
谢谢
找到答案。
当模型无法收敛到结果时使用rescale=True
。因此重新缩放可能是解决问题的方法。如果模型不需要rescale,即使参数是True
,它也不会做任何事情。
Point of Attempion:如果rescale=True
,事实上,重新调整了系列。有必要调整输出。在我的问题中,我对我的波动率有多高感到困惑。那是因为我假设我的重新缩放值是 100,这不一定是真的。
正确的做法是将参数设置为True,然后获取rescale值。
为此,只需插入以下代码:
# 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
希望这对遇到同样问题的其他用户有所帮助。这是一件非常简单的事情。
谢谢。