Это правильный способ прогнозировать волатильность цены акций с помощью GARCH - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь сделать прогноз волатильности акций в будущем (скажем, на 90 дней). Кажется, что GARCH - традиционно используемая модель для этого.

Я реализовал это ниже, используя библиотеку Python arch. Все, что я делаю, объясняется в комментариях, единственное, что нужно изменить, чтобы запустить код, - это указывать свои собственные ежедневные цены, а не то, где я получаю их из своего собственного API.

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

ticker = 'AAPL'         # Ticker to retrieve data for
forecast_horizon = 90   # Number of days to forecast

# Retrive prices from IEX API
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)         # Annualize monthly standard devation
df = df.dropna().reset_index(drop=True)

# Convert decimal returns to %
returns = df['daily_returns'] * 100

# Fit GARCH model
am = arch.arch_model(returns[:-forecast_horizon])
res = am.fit(disp='off')

# Calculate fitted variance values from model parameters
# Convert variance to standard deviation (volatility)
# Revert previous multiplication by 100
fitted = 0.1 * np.sqrt(
    res.params['omega'] +
    res.params['alpha[1]'] *
    res.resid**2 +
    res.conditional_volatility**2 *
    res.params['beta[1]']
)

# Make forecast
# Convert variance to standard deviation (volatility)
# Revert previous multiplication by 100
forecast = 0.1 * np.sqrt(res.forecast(horizon=forecast_horizon).variance.values[-1])

# Store actual, fitted, and forecasted results
vol = pd.DataFrame({
    'actual': df['annual_vol'],
    'model': np.append(fitted, forecast)
})

# Plot Actual vs Fitted/Forecasted
plt.plot(vol['actual'][:-forecast_horizon], label='Train')
plt.plot(vol['actual'][-forecast_horizon - 1:], label='Test')
plt.plot(vol['model'][:-forecast_horizon], label='Fitted')
plt.plot(vol['model'][-forecast_horizon - 1:], label='Forecast')
plt.legend()
plt.show()

Для Apple получается следующий график:

enter image description here

Очевидно, что установленные значения постоянно намного ниже, чем фактические значения, и это приводит к тому, что прогноз также является огромной недооценкой (это плохой пример, учитывая, что волатильность Apple была необычно высокой в ​​этот тестовый период, но со всеми компании, которые я стараюсь, модель всегда недооценивает установленные значения).

Я все делаю правильно, а модель GARCH просто не очень мощная, или моделирование волатильности очень сложно? Или я делаю какую-то ошибку?

...