Python 基于GARCH模型的滚动预测

Python 基于GARCH模型的滚动预测,python,r,statistics,forecasting,volatility,Python,R,Statistics,Forecasting,Volatility,我试图在未来30天内对给定股票的波动性进行滚动预测(即预测时间t+1,然后在预测t+2时使用该预测,以此类推……) 我使用的是R的rugarch包,我使用rpy2包在Python中实现了这个包。(我发现Python包的文档记录得很差,使用起来更困难。这些包中的大多数在R中要成熟得多) 这是我迄今为止的代码,其中模型适用于股票收益率的整个时间序列,直到我拥有的最后30天的数据。然后,我(我认为)对我所拥有的未查看数据的最后30天进行滚动预测 import numpy as np import pa

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

我使用的是R的
rugarch
包,我使用
rpy2
包在Python中实现了这个包。(我发现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来检索每日价格,但是可以将其更改为您自己的价格数据来运行代码

对于AAPL,该脚本生成实际与拟合/预测波动率的下图:

这导致了以下两个问题:

  • 这一对未知数据的预测似乎令人难以置信地印象深刻,特别是考虑到苹果最近的波动性在测试集中如此之高——高于该模型适用的任何数据。这个滚动预测是否按我预期的方式运行?或者,模型是否真的在试穿过程中看到了最后30天

  • 如果该滚动预测如我所预期的那样工作,那么我现在如何使模型适合到今天为止我拥有的整个训练数据时间序列,然后在未来30天内执行滚动预测?我在文档或网上找不到任何这样做的例子。不管这个模型在我所做的历史数据测试中有多好,如果它不能用于对未来进行实际预测,那么它是完全无用的