Скользящий прогноз с использованием модели GARCH - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь выполнить скользящий прогноз волатильности данной акции через 30 дней в будущем (т. Е. Прогнозируемое время t + 1, затем использовать этот прогноз при прогнозировании t + 2 и т. Д.)

Я делаю это, используя пакет R's 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 для получения дневных цен, но его можно изменить на вашсобственные данные цены для выполнения кода.

Для AAPL этот сценарий приводит к следующему графику фактической зависимости от установленной / прогнозируемой волатильности:

enter image description here

Это приводит к следующим 2 вопросам:

  1. Этот прогноз по невидимым данным кажется подозрительно впечатляющим, особенно с учетом того, что недавняя волатильность Apple была настолько высокой в ​​тестовом наборе - выше, чем что-либо другое.Модель была приспособлена для.Этот скользящий прогноз работает так, как я ожидаю?Или модель как-то видит эти последние 30 дней во время подгонки?

  2. Если этот скользящий прогноз работает так, как я ожидаю, как теперь я могу подогнать модель под весь временной ряд обучения?У меня есть данные до сегодняшнего дня, а затем выполнить скользящий прогноз на 30 дней в будущее?Я не могу найти ничего в документации или каких-либо примерах онлайн, которые делают это.Независимо от того, насколько хороша модель для этого теста исторических данных, которые я выполнил, она совершенно бесполезна, если ее нельзя использовать для составления реальных прогнозов в будущее.

...