Actualmente estoy trabajando con el siguiente proceso GARCH de Heston y Nandi (2000): rt+1−rf=λht+1−ht+12+√ht+1zt+1ht+1=ω+βht+α(zt−γ√ht)2 dado zt+1∼N(0,1) podemos estimar los parámetros del modelo por máxima verosimilitud. Escribí un código python para simular el proceso y, a continuación, calcular la verosimilitud en los valores hipotéticos de los parámetros. La densidad para cada observación viene dada por:
f(rt+1−r|ht+1)=1√2πht+1exp(−(rt+1−r−λht+1+ht+12)22ht+1)
Mi problema es ¿cómo debo calcular la maximización? Obviamente, |1−β−αγ2|<1 asegura que el proceso de varianza condicional es estacionario en la covarianza. Además, (ω+α)/(1−β−αγ2)>0 garantiza que la varianza incondicional sea positiva. Así que, como algunos podrían sospechar, estoy teniendo problemas para asegurarme de que el algoritmo de maximización pueda converger hacia los valores reales de los parámetros y estoy buscando cómo debería abordar esta cuestión.
import numpy as np
from numpy import sqrt, exp, log
from matplotlib.pyplot import plot, hist
from statistics import mean
from scipy.optimize import minimize
#%%
r = 0.05/252
param = [-9.765e-07, 2.194e-06, 0.8986, 205.15, 3.930]
omega, alpha, beta, gamma, Lambda = param
sigma2 = (omega+alpha)/(1-beta-alpha*gamma**2)
h0 = sigma2
T = 1000
z = np.random.normal(loc=0, scale=1, size=T)
R = np.zeros(shape=T)
h = h0*np.ones(shape=T)
for tt in range(0,T-1):
h[tt+1] = omega + beta*h[tt] + alpha*(z[tt] - gamma*sqrt(h[tt]))**2
R[tt+1] = r + Lambda*h[tt+1] - h[tt+1]/2 + sqrt(h[tt+1])*z[tt+1]
hh = h
Rt = R - r
def TS_Loglik_HN(Rt, h0, param):
'''
Author: Stéphane Surprenant, UQAM
Creation: 02/04/2020
Description: This function returns the value of the log-likelihood for the
Heston and Nandi (2000) process under the physical measure.
INPUTS DESCRIPTION
Rt : (float) Series of (log) returns minus the risk-free rate.
h0 : (float) Initial value of the variance (Daily)
param: (float) Parameters of the model
[omega, alpha, beta, gamma, Lambda] = param
OUTOUTS DESRIPTION
loglik (float) Log-likelihood value
Model:
Rt[tt+1] := R[tt+1] - r
= Lambda*h[tt+1] - h[tt+1]/2 + sqrt(h[tt+1])*z[tt+1]
h[tt+1] = omega + beta*h[tt] + alpha*(z[tt] - gamma*sqrt(h[tt]))**2
'''
# Assign parameter values
omega, alpha, beta, gamma, Lambda = param
# Initialize matrices
T = len(Rt)
h = h0*np.ones(shape=T)
e = np.zeros(shape=T)
# Filtering volatility
for tt in range(0,T-1):
e[tt] = (Rt[tt] - Lambda*h[tt] + h[tt]/2)/sqrt(h[tt])
h[tt+1] = omega + beta*h[tt] + alpha*(e[tt] - gamma*sqrt(h[tt]))**2
e[T-1] = (Rt[T-1] - Lambda*h[T-1] + h[T-1]/2)/sqrt(h[T-1])
# Compute Log-likelihood
l = -0.5*(log(2*np.pi) + log(h) + e**2)
loglik = sum(l)
return(loglik)
# Example:
f = lambda x: -TS_Loglik_HN(Rt, h0, x)
results = minimize(f, param)
0 votos
Nunca he hecho ningún tipo de optimización con Python hasta ahora, pero ¿no deberías simplemente introducir tus restricciones al optimizador ( docs.scipy.org/doc/scipy/reference/generated/ ), véase la sección de restricciones. ?
0 votos
Busco lo que se suele hacer en esas circunstancias.
0 votos
Acabo de hacer eso en R con un GARCH(1,1) "estándar" hoy y todo lo que tuve que hacer fue suministrar las restricciones lineales habituales al optimizador.
0 votos
Un enfoque de fuerza bruta sería simplemente dejar que su probabilidad se vuelva MUY negativa si se viola una restricción. Una vez más, ese no es el camino a seguir, pero a veces basta con la fuerza bruta...
0 votos
No conozco este modelo, ¿conoces las condiciones necesarias o suficientes para obtener una varianza cond. positiva? En caso afirmativo, es habitual utilizar un algoritmo que permita imponer estas condiciones (restricciones no lineales) durante la estimación (ej: ver method='SLSQP' en scipy.optimize).
0 votos
Ver también quant.stackexchange.com/a/41540/7008
0 votos
@Kermittfrog parte del problema aquí es que no estoy seguro de qué restricciones debo suministrar. El modelo anterior es un tipo especial de GARCH que permite introducir una respuesta asimétrica de la varianza a través de la γ parámetro. También viene con su propia ecuación media.