繁体   English   中英

在 Python 中使用 GARCH 预测波动率 - Arch 包

[英]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 返回

第一个系列是 Ibovespa 指数的第一个期货合约,观察到的年化波动率非常接近 Garch 预测。

我发现的第一个问题是您需要将样本重新缩放 100。为此,您可以将返回序列乘以 100 或在arch_model函数中设置参数arch_model rescale=True

为什么有必要这样做?

# 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明显不同

为什么会这样? 也许是因为重新缩放? 在预测之前我是否必须再做一次调整?

谢谢

找到了答案。

当模型未能收敛到结果时使用rescale=True 因此,重新缩放可能是该问题的解决方案。 如果模型不需要重新缩放,即使参数为True ,它也不会做任何事情。

尝试点:如果rescale 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

希望这可以帮助其他有同样问题的用户。 这真的是一件很简单的事情。

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM