簡體   English   中英

在 Python 中使用 GARCH 預測波動率 - Arch 包

[英]Forecasting Volatility using GARCH in Python - Arch Package

我正在測試 ARCH 包以使用 GARCH(1,1) 預測兩個系列的方差(標准偏差)。

這是我的代碼的第一部分

import pandas as pd
import numpy as np
from arch import arch_model


returns = pd.read_csv('ret_full.csv', index_col=0)
returns.index = pd.to_datetime(returns.index)

Ibovespa 返回

第一個系列是 Ibovespa 指數的第一個期貨合約,觀察到的年化波動率非常接近 Garch 預測。

我發現的第一個問題是您需要將樣本重新縮放 100。為此,您可以將返回序列乘以 100 或在arch_model函數中設置參數arch_model rescale=True

為什么有必要這樣做?

# Ibov
ret_ibov = returns['IBOV_1st']
model_ibov = arch_model(ret_ibov, vol='Garch', p=1, o=0, q=1, dist='Normal', rescale=True)
res_ibov = model_ibov.fit()

擬合模型后,我預測了方差(只需 5 個步驟來說明問題),得到標准差並將其年化。 Obs:因為我不得不重新調整我的回報系列,我將我的預測除以 10000(100**2,因為重新調整)

# Forecast
forecast_ibov = res_ibov.forecast(horizon=5)

# Getting Annualized Standard Deviation
# Garch Vol
vol_ibov_for = (forecast_ibov.variance.iloc[-1]/10000)**0.5 * np.sqrt(252) * 100
# Observed Vol
vol_ibov = ret_ibov.std() * np.sqrt(252) * 100

這就是預測輸出

vol_ibov_for
h.1    24.563208
h.2    24.543245
h.3    24.523969
h.4    24.505357
h.5    24.487385

這與 Observed Vol 23.76非常接近

這是我期待的結果。

IRFM 回報

當我對一個不那么不穩定的系列做完全相同的過程時,我得到了一個非常奇怪的結果。

# IRFM
ret_irfm = returns['IRFM1M']
model_irfm = arch_model(ret_irfm, vol='Garch', p=1, o=0, q=1, dist='Normal', rescale=True)
res_irfm = model_irfm.fit()

# Forecast
forecasts_irfm = res_irfm.forecast(horizon=5)

# Getting Annualized Standard Deviation
# Garch Vol
vol_irfm_for = (forecasts_irfm.variance.iloc[-1]/10000)**0.5 * np.sqrt(252) * 100
# Observed Vol
vol_irfm = ret_irfm.std() * np.sqrt(252) * 100

預測輸出:

vol_irfm_for
h.1    47.879679
h.2    49.322351
h.3    50.519282
h.4    51.517356
h.5    52.352894

這與觀察到的波動率5.39明顯不同

為什么會這樣? 也許是因為重新縮放? 在預測之前我是否必須再做一次調整?

謝謝

找到了答案。

當模型未能收斂到結果時使用rescale=True 因此,重新縮放可能是該問題的解決方案。 如果模型不需要重新縮放,即使參數為True ,它也不會做任何事情。

嘗試點:如果rescale rescale=True並且實際上重新調整了系列。 有必要調整輸出。 在我的問題中,我對我的波動性有多高感到困惑。 那是因為我假設我的重新調整值為 100,這不一定是真的。

正確的做法是將參數設置為 True 並在此之后獲取重新縮放值。

為此,只需要插入以下代碼:

# IRFM
ret_irfm = returns['IRFM1M']
model_irfm = arch_model(ret_irfm, vol='Garch', p=1, o=0, q=1, dist='Normal', rescale=True, mean='Zero')
res_irfm = model_irfm.fit()
scale = res_irfm.scale  # New part of the code

# Forecast
forecasts_irfm = res_irfm.forecast(horizon=5)

# Getting Annualized Standard Deviation
# Garch Vol
# New part of the code: Divide variance by scale^2
vol_irfm_for = (forecasts_irfm.variance.iloc[-1] / np.power(scale, 2))**0.5 * np.sqrt(252) * 100 
# Observed Vol
vol_irfm = ret_irfm.std() * np.sqrt(252) * 100

希望這可以幫助其他有同樣問題的用戶。 這真的是一件很簡單的事情。

謝謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM