s-broda / ARCHModels.jl

A Julia package for estimating ARMA-GARCH models.
https://juliaeconometrics.wordpress.com/
Other
90 stars 18 forks source link

`meanspect = Intercept()` doesn't work? #93

Closed nilshg closed 3 years ago

nilshg commented 3 years ago

Another "am I using this right" issue:

julia> using ARCHModels, MarketData, DataFrames

julia> d = dropmissing(DataFrame(yahoo("^FTSE")));

julia> rs = log.(d.AdjClose[end-251:end]) .- log.(d.AdjClose[end-252:end-1]);

julia> garch_model_NI = fit(GARCH{1, 1}, rs, meanspec = NoIntercept);

julia> garch_model_NI.meanspec
NoIntercept{Float64}(Float64[])

julia> garch_model_I0 = fit(GARCH{1, 1}, rs, meanspec = Intercept(0.0));

julia> garch_model_I0.meanspec
Intercept{Float64}([0.000645515581577216])

I was expecting garch_model_I0 to have zero mean as well, but it seems that it ignores the 0 and just estimates the mean from the data? Similarly, I can't work out how to set means for multivariate models, passing something like meanspec = [Intercept(0.0), Intercept(0.0), Intercept(0.0)] errors.

My usecase - I want to simulate paths for underlying assets of derivatives in MC simulations and therefore manually pass the drift parameter based on risk free rate, dividend yield, and Ito correction. So far the only way I've managed to do this is to first estimate the model with an intercept and then do

julia> garch_model_I0.meanspec = Intercept(0.001)
Intercept{Float64}([0.001])

after estimation, but I feel like this is what should happen in the first place when using the kwarg? Unfortunately I couldn't find examples in the docs of using meanspec in fit.

s-broda commented 3 years ago

Yes, this is intended; there is no option to fix parameters during estimation. What you could do is fit the model without intercept, then use the constructor to build a model with an identical volatility spec but with a zero intercept:

julia> using ARCHModels

julia> am = fit(GARCH{1, 1}, BG96; meanspec=NoIntercept);

julia> am2 = UnivariateARCHModel(am.spec, am.data; dist=am.dist, meanspec=Intercept(0.), fitted=false)

GARCH{1, 1} model with Gaussian errors, T=1974.

──────────────────────────────
                             μ
──────────────────────────────
Mean equation parameters:  0.0
──────────────────────────────
────────────────────────────────────────────────────────
                                   ω        β₁        α₁
────────────────────────────────────────────────────────
Volatility parameters:     0.0108661  0.804431  0.154597
────────────────────────────────────────────────────────

This will result in slightly different volatility parameters from your method above, because it forces the mean to be zero during estimation.

The same approach works for multivariate models as well:

julia> am = fit(DCC, DOW29; meanspec=NoIntercept);

julia> am2 = MultivariateARCHModel(am.spec, am.data; dist=am.dist, meanspec=[Intercept(0.) for _ in 1:size(am.data)[2]], fitted=false)

29-dimensional DCC{1, 1} - GARCH{1, 1} - Intercept{Float64} specification, T=2785.

DCC parameters
─────────────────────
        β₁         α₁
─────────────────────
  0.889328  0.0552282
─────────────────────

Notice that the API for the multivariate case is a bit hacky, because I haven't implemented any "proper" multivariate mean specifications yet.

Also note that the constructors do not make copies of their arguments, so if you modify am2 in any way, these changes are reflected in am. You can make a deepcopy of each argument in the am2 = ... call to avoid this.