Optim DomainError

question

#1

I am fitting U.S. Kerosene daily price percentage change with Heston Nandi GARCH model. I use the Optim.optimize function for my MLE but got a domain error.

My code



using RData, Optim


function LoadData()
    return load("Sample.RData")["Sample"]
end




function HNGARCH(param, sample = Sample)
    
        
    lambda = param[1]
    omega = param[2]
    beta = param[3]
    alpha = param[4]
    gamma = param[5]
    delta = param[6]
    
    

    y = sample[:log_return]
    r = sample[:rf_rate]

    h1 = var(y)

    T = length(y)



    z = zeros(T)
    h = zeros(T)
    h[1] = h1

    z[1] = (y[1] - r[1] - lambda*h[1])/sqrt(h[1])



    for i = 2:T
        h[i] = omega + beta*h[i-1] + alpha*(z[i-1] - gamma*sqrt(h[i-1]))^2
        z[i] = (y[i] - r[i] - lambda*h[i])/sqrt(h[i])
    end
    
    delta = minimum(h)
    
    logL = -0.5*T*log(2*pi) - 0.5*sum(log.(h) + z.^2)


    logL_neg = -logL

    return logL_neg
end
    



function main()
    
    global Sample = LoadData()

   
   
    lower = [-Inf, 0, 0, 0, -Inf, 0]
    upper = [Inf, Inf, Inf, Inf, Inf, Inf]
    initial_param = [0.05, 0.2, 0.66, 0.3, 0.5, 0.01]
    
    res1 = optimize(HNGARCH, initial_param, lower, upper) 

   
    return res1

end 

main()

My data Sample looks like this:


2049ร—3 DataFrames.DataFrame
โ”‚ Row  โ”‚ date         โ”‚ log_return  โ”‚ rf_rate โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1    โ”‚ "2010-01-05" โ”‚ 0.0         โ”‚ 0.0041  โ”‚
โ”‚ 2    โ”‚ "2010-01-06" โ”‚ 0.00368834  โ”‚ 0.004   โ”‚
โ”‚ 3    โ”‚ "2010-01-07" โ”‚ -0.00785405 โ”‚ 0.004   โ”‚
โ”‚ 4    โ”‚ "2010-01-08" โ”‚ 0.0156469   โ”‚ 0.0037  โ”‚
โ”‚ 5    โ”‚ "2010-01-11" โ”‚ -0.0156469  โ”‚ 0.0035  โ”‚
โ”‚ 6    โ”‚ "2010-01-12" โ”‚ -0.0187271  โ”‚ 0.0034  โ”‚
โ‹ฎ
โ”‚ 2043 โ”‚ "2018-03-09" โ”‚ 0.0106117   โ”‚ 0.0203  โ”‚
โ”‚ 2044 โ”‚ "2018-03-12" โ”‚ -0.0111733  โ”‚ 0.0205  โ”‚
โ”‚ 2045 โ”‚ "2018-03-13" โ”‚ 0.00560226  โ”‚ 0.0203  โ”‚
โ”‚ 2046 โ”‚ "2018-03-14" โ”‚ 0.00390299  โ”‚ 0.0205  โ”‚
โ”‚ 2047 โ”‚ "2018-03-15" โ”‚ 0.00444198  โ”‚ 0.0207  โ”‚
โ”‚ 2048 โ”‚ "2018-03-16" โ”‚ 0.00882521  โ”‚ 0.0208  โ”‚
โ”‚ 2049 โ”‚ "2018-03-19" โ”‚ -0.00330033 โ”‚ 0.0208  โ”‚

My error message:

ERROR: DomainError:
Stacktrace:
 [1] HNGARCH(::Array{Float64,1}) at ./none:22
 [2] value(::NLSolversBase.NonDifferentiable{Float64,Array{Float64,1},Val{false}}, ::Array{Float64,1}) at /home/Yifan/.julia/v0.6/NLSolversBase/src/interface.jl:19
 [3] update_state!(::NLSolversBase.NonDifferentiable{Float64,Array{Float64,1},Val{false}}, ::Optim.NelderMeadState{Array{Float64,1},Float64,Array{Float64,1}}, ::Optim.NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters}) at /home/Yifan/.julia/v0.6/Optim/src/multivariate/solvers/zeroth_order/nelder_mead.jl:187
 [4] optimize(::NLSolversBase.NonDifferentiable{Float64,Array{Float64,1},Val{false}}, ::Array{Float64,1}, ::Optim.NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters}, ::Optim.Options{Float64,Void}, ::Optim.NelderMeadState{Array{Float64,1},Float64,Array{Float64,1}}) at /home/Yifan/.julia/v0.6/Optim/src/multivariate/optimize/optimize.jl:51
 [5] optimize(::NLSolversBase.NonDifferentiable{Float64,Array{Float64,1},Val{false}}, ::Array{Float64,1}, ::Optim.NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters}, ::Optim.Options{Float64,Void}) at /home/Yifan/.julia/v0.6/Optim/src/multivariate/optimize/optimize.jl:25
 [6] #optimize#151(::Array{Any,1}, ::Function, ::Tuple{#HNGARCH}, ::Array{Float64,1}) at /home/Yifan/.julia/v0.6/Optim/src/multivariate/optimize/interface.jl:62
 [7] #optimize#148(::Array{Any,1}, ::Function, ::Function, ::Array{Float64,1}) at /home/Yifan/.julia/v0.6/Optim/src/multivariate/optimize/interface.jl:52
 [8] optimize(::Function, ::Array{Float64,1}) at /home/Yifan/.julia/v0.6/Optim/src/multivariate/optimize/interface.jl:52
 [9] macro expansion at ./REPL.jl:97 [inlined]
 [10] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:73

edit: the updated code works now


Optim.jl --- Do all Methods Allow Box Constraints? Should all Work Without Them?
#2

One of h probably becomes negative. You need to handle that somehow, either by constraints such that the function is never evaluated there or detect the situation and return something else (Inf?).


#3

Thanks. I think this is the issue. How can I impose such constraints?


#4

Use Fminbox. http://julianlsolvers.github.io/Optim.jl/latest/user/minimization/

Edit: Oh, itโ€™s something else that becomes negative? Well box constraints can still help if you know the general area. Also, itโ€™s the only constraints Optim.jl has.


#5

Also, loading the sample for every calculation is probably suboptiomal. Load it once, use a closure, eg

data = load(...)

function likelihood(params, data)
   ...
end

optimize(params -> likelihood(params, data), initial_params)

#6

Yeah, I do know the constraints, but I do not know how to add this one

beta + alpha*gamma^2 <1


#7

Change your variables. Define delta = beta + alpha*gamma^2. Then beta = delta - alpha*gamma^2. Use Fminbox with the constraint that delta<1.


#8

I tried this, but still got an domain error. So I make delta the minimum of my vector h, and constrain it to be positive, the issue is solved.