I'm trying to estimate the maximum likelihood of a realized GARCH model. Below are the equations and the parameters I want to estimate
I'm using the below function to maximise the likelihood, but it has being very inconsistent. Moreover, it is highly sensitive to the initial parameters, it always spits out value very very close to the initial parameters. I've tried using real data and also simulated data, so I could check against the true parameters. Am I doing anything wrong in the code? I know that GARCH models usually have a flat likelihood but still I thought I would get some different values from my initial ones
garch11_realised <- function (returns, params, RM) { #Starting our parameters omega <- params[1] beta <- params[2] gamma <- params[3] xi <- params[4] phi <- params[5] tau1 <- params[6] tau2 <- params[7] T <- length(returns) log_sigma2 <- numeric(T) sigma2 <- numeric(T) log_x <- log(RM) ut <- numeric(T) z <- numeric(T) tau_z <- numeric(T) log_sigma2[1] <- log((omega + gamma * xi) / (1 - (beta + gamma*phi))) sigma2[1] <- exp(log_sigma2[1]) z[1] <- returns[1] / sqrt(exp(log_sigma2[1])) for (t in 2:T){ #we are using log here because that's how the model is specified in most of the papers log_sigma2[t] <- omega + beta * log_sigma2[t-1] + gamma * log_x[t-1] sigma2[t] <- exp(log_sigma2[t]) z[t] <- returns[t] / sqrt(exp(log_sigma2[t])) tau_z[t] <- tau1 *z[t] + tau2 * (z[t] ^ 2 - 1) #our leverage function ut[t]<- log_x[t] - xi - phi * log_sigma2[t] - tau_z[t] # rearranging measurement equation to calculate the residuals } return(list(sigma2 = sigma2, ut = ut, z = z)) } neg_loglik_realised <- function(returns, params, RM){ omega <- params[1] beta <- params[2] gamma <- params[3] xi <- params[4] phi <- params[5] tau1 <- params[6] tau2 <- params[7] sigma_ut <- params[8] #variance of our ut in the measurement equation T <- length(returns) model_results <- garch11_realised(returns,params, RM) sigma2 <- model_results$sigma2 ut <- model_results$ut #required conditions for realized garch - https://core.ac.uk/download/pdf/41239655.pdf - page 6 of this paper # 0 < β + φγ < 1 and ω + γξ > 0 if (all(is.finite(params)) && omega > 0 && beta > 0 && gamma > 0 && 0 < (beta + phi * gamma) && (beta + phi * gamma) < 1 && (omega + gamma * xi) > 0) { #quasi log-likelihood log_lik_1 <- - T/2* log(2*pi) - 1/2 * sum(log(sigma2)) - 1/2 * sum(returns^2 / sigma2) #this is the first part l(r) log_lik_2 <- - T/2 * log(2 * pi) - 1/2 * sum(log(sigma_ut)) -1/2 * sum((ut ^ 2 / sigma_ut ^ 2)) #this is the second part l(x|r) neg_lik <- - (log_lik_1 + log_lik_2) } else { neg_lik <- Inf } return(neg_lik) } estimating_mle_realised <- function(start_params,returns, RM) { lower_bounds = c(1e-8, 1e-8, 1e-8, -1, -1, -1, -1, -1) upper_bounds = c(1, 0.99, 0.99, 1, 99, 1, 1, 1) mle <- nlminb(start = start_params, objective = function(start_params) objective_fn(start_params,returns, RM), lower = lower_bounds, upper = upper_bounds) return(mle) } Cheers


if ... elsestatement at the bottom, to see how often your optimizer searches outside the parameter space and returnsInf. $\endgroup$