我正在尝试对给定股票未来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,此脚本得出以下实际波动率与拟合波动率/预测波动率的曲线图:
这导致以下两个问题:
对看不见的数据的这种预测似乎令人惊讶,尤其是考虑到苹果最近在测试集中的波动率很高-高于该模型所适用的任何波动率。此滚动预测是否按我期望的方式工作?还是模型实际上以某种方式在最后30天看到了这些?
如果此滚动预测能够按我预期的那样工作,那么我现在如何使该模型适合我迄今拥有的整个训练数据时间序列,然后在未来30天进行滚动预测?我无法在文档中找到任何可实现此目的的示例或任何在线示例。无论该模型对我执行的历史数据进行测试的效果如何,如果不能用于对未来进行实际预测,那将是完全没有用的。