使用GARCH模型的滚动预测

时间:2019-01-26 10:31:20

标签: python r statistics forecasting volatility

我正在尝试对给定股票未来30天的波动性进行滚动预测(即预测时间t + 1,然后在预测t + 2时使用该预测,依此类推...)

我这样做是使用R的rugarch包,我已经在Python中使用rpy2包实现了它。 (我发现Python软件包的文档记录不清,更难使用。其中大多数软件包在R语言中也更加成熟)。

到目前为止,这是我的代码,该模型适用于直到我拥有的最后30天数据的股票回报的整个时间序列。然后,我对我拥有的未见数据的最后30天进行滚动预测(我认为)。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from rpy2.robjects.packages import importr
import rpy2.robjects as robjects
from rpy2.robjects import numpy2ri

ticker = 'AAPL'
forecast_horizon = 30

prices = utils.dw.get(filename=ticker, source='iex', iex_range='5y')
df = prices[['date', 'close']]

df['daily_returns'] = np.log(df['close']).diff()            # Daily log returns
df['monthly_std'] = df['daily_returns'].rolling(21).std()   # Standard deviation across trading month
df['annual_vol'] = df['monthly_std'] * np.sqrt(252)         # Convert monthly standard devation to annualized volatility
df = df.dropna().reset_index(drop=True)

# Initialize R GARCH model
rugarch = importr('rugarch')
garch_spec = rugarch.ugarchspec(
    mean_model=robjects.r('list(armaOrder = c(0,0))'),
    variance_model=robjects.r('list(garchOrder=c(1,1))'),
    distribution_model='std'
)

# Used to convert training set to R list for model input
numpy2ri.activate()

# Train R GARCH model on returns as %
garch_fitted = rugarch.ugarchfit(
    spec=garch_spec,
    data=df['daily_returns'].values * 100,
    out_sample=forecast_horizon
)

numpy2ri.deactivate()

# Model's fitted standard deviation values
# Revert previous multiplication by 100
# Convert to annualized volatility
fitted = 0.01 * np.sqrt(252) * np.array(garch_fitted.slots['fit'].rx2('sigma')).flatten()

# Forecast using R GACRH model
garch_forecast = rugarch.ugarchforecast(
    garch_fitted,
    n_ahead=1,
    n_roll=forecast_horizon - 1
)

# Model's forecasted standard deviation values
# Revert previous multiplication by 100
# Convert to annualized volatility
forecast = 0.01 * np.sqrt(252) * np.array(garch_forecast.slots['forecast'].rx2('sigmaFor')).flatten()

volatility = pd.DataFrame({
    'actual': df['annual_vol'].values,
    'model': np.append(fitted, forecast),
})

plt.plot(volatility['actual'][:-forecast_horizon], label='Train')
plt.plot(volatility['actual'][-forecast_horizon - 1:], label='Test')
plt.plot(volatility['model'][:-forecast_horizon], label='Fitted')
plt.plot(volatility['model'][-forecast_horizon - 1:], label='Forecasted')
plt.legend()
plt.show()

此代码使用我自己的API检索每日价格,但是可以将其更改为您自己的价格数据以运行该代码。

对于APL,此脚本得出以下实际波动率与拟合波动率/预测波动率的曲线图:

enter image description here

这导致以下两个问题:

  1. 对看不见的数据的这种预测似乎令人惊讶,尤其是考虑到苹果最近在测试集中的波动率很高-高于该模型所适用的任何波动率。此滚动预测是否按我期望的方式工作?还是模型实际上以某种方式在最后30天看到了这些?

  2. 如果此滚动预测能够按我预期的那样工作,那么我现在如何使该模型适合我迄今拥有的整个训练数据时间序列,然后在未来30天进行滚动预测?我无法在文档中找到任何可实现此目的的示例或任何在线示例。无论该模型对我执行的历史数据进行测试的效果如何,如果不能用于对未来进行实际预测,那将是完全没有用的。

0 个答案:

没有答案