1
2# This library is free software; you can redistribute it and/or
3# modify it under the terms of the GNU Library General Public
4# License as published by the Free Software Foundation; either
5# version 2 of the License, or (at your option) any later version.
6#
7# This library is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10# GNU Library General Public License for more details.
11#
12# You should have received a copy of the GNU Library General
13# Public License along with this library; if not, write to the
14# Free Foundation, Inc., 59 Temple Place, Suite 330, Boston,
15# MA  02111-1307  USA
16
17
18################################################################################
19# FUNCTION:               SPECIFICATION:
20#  garchSpec               Creates a 'garchSpec' object from scratch
21###############################################################################
22
23
24garchSpec <-
25    function (model = list(), presample = NULL,
26    cond.dist = c("norm", "ged", "std", "snorm", "sged", "sstd"),
27    rseed = NULL)
28{
29    # A function implemented by Diethelm Wuertz
30
31    # Description:
32    #   Creates a "garchSpec" object from scratch.
33
34    # Arguments:
35    #   model - a list with the model parameters as entries
36    #     omega - the variance value for GARCH/APARCH
37    #       specification,
38    #     alpha - a vector of autoregressive coefficients
39    #       of length p for the GARCH/APARCH specification,
40    #     gamma - a vector of leverage coefficients of
41    #       length p for the APARCH specification,
42    #     beta - a vector of moving average coefficients of
43    #       length q for the GARCH/APARCH specification,
44    #     mu - the mean value for ARMA specification,
45    #     ar - a vector of autoregressive coefficients of
46    #       length m for the ARMA specification,
47    #     ma - a vector of moving average coefficients of
48    #       length n for the ARMA specification,
49    #     delta - the exponent value used in the variance equation.
50    #     skew - a numeric value listing the distributional
51    #        skewness parameter.
52    #     shape - a numeric value listing the distributional
53    #        shape parameter.
54    #   presample - either a multivariate "timeSeries", a
55    #       multivariate "ts", a "data.frame" object or a numeric
56    #       "matrix" with 3 columns and at least max(m,n,p,q)
57    #       rows. The first culumn are the innovations, the second
58    #       the conditional variances, and the last the time series.
59    #   condd.dist - a character string naming the distribution
60    #       function.
61    #   rseed - optional random seed.
62
63    # Slots:
64    #   call - the function call.
65    #   formula - a formula object describing the model, e.g.
66    #       ARMA(m,n) + GARCH(p,q). ARMA can be missing or
67    #       specified as AR(m) or MA(n) in the case of pure
68    #       autoregressive or moving average models. GARCH may
69    #       alternatively specified as ARCH(p) or APARCH(p,q).
70    #       If formula is set to "NA", the formula is constructed
71    #       from the "model" list.
72    #   model - as declared in the input.
73
74    # FUNCTION:
75
76    # Match Arguments:
77    cond.dist = match.arg(cond.dist)
78
79    # Skewness Parameter Settings:
80    skew = list(
81        "norm" = NULL,
82        "ged" = NULL,
83        "std" = NULL,
84        "snorm" = 0.9,
85        "sged" = 0.9,
86        "sstd" = 0.9)
87
88    # Shape Parameter Settings:
89    shape = list(
90        "norm" = NULL,
91        "ged" = 2,
92        "std" = 4,
93        "snorm" = NULL,
94        "sged" = 2,
95        "sstd" = 4)
96
97    # Default Model:
98    control = list(
99        omega = 1.0e-6,
100        alpha = 0.1,
101        gamma = NULL,
102        beta = 0.8,
103        mu = NULL,
104        ar = NULL,
105        ma = NULL,
106        delta = 2,
107        skew = skew[[cond.dist]],
108        shape = shape[[cond.dist]]
109        )
110
111    # Update Control:
112    control[names(model)] <- model
113    model <- control
114
115    # check if alpha and beta are well defined
116    if (sum(c(model$alpha, model$beta))>1)
117        warnings("sum(alpha)+sum(beta)>1")
118
119    # Model Orders:
120    order.ar = length(model$ar)
121    order.ma = length(model$ma)
122    order.alpha = length(model$alpha)
123    if (sum(model$beta) == 0) {
124        order.beta = 0
125    } else {
126        order.beta = length(model$beta)
127    }
128
129    # Compose Mean Formula Object:
130    if (order.ar == 0 && order.ma == 0) {
131        formula.mean = ""
132    }
133    if (order.ar > 0 && order.ma == 0) {
134        formula.mean = paste ("ar(", as.character(order.ar), ")", sep = "")
135    }
136    if (order.ar == 0 && order.ma > 0) {
137        formula.mean = paste ("ma(", as.character(order.ma), ")",  sep = "")
138    }
139    if (order.ar > 0 && order.ma > 0) {
140        formula.mean = paste ("arma(", as.character(order.ar), ", ",
141            as.character(order.ma), ")", sep = "")
142    }
143
144    # Compose Variance Formula Object:
145    formula.var = "garch"
146    if (order.beta == 0) formula.var = "arch"
147    if (!is.null(model$gamma) != 0) formula.var = "aparch"
148    if (model$delta != 2) formula.var = "aparch"
149
150    if (order.beta == 0) {
151        formula.var = paste(formula.var, "(", as.character(order.alpha), ")",
152            sep = "")
153    } else {
154        formula.var = paste(formula.var, "(", as.character(order.alpha),
155            ", ", as.character(order.beta), ")", sep = "")
156    }
157
158    # Compose Mean-Variance Formula Object:
159    if (formula.mean == "") {
160        formula = as.formula(paste("~", formula.var))
161    } else {
162        formula = as.formula(paste("~", formula.mean, "+", formula.var))
163    }
164
165    # Add NULL default entries:
166    if (is.null(model$mu)) model$mu = 0
167    if (is.null(model$ar)) model$ar = 0
168    if (is.null(model$ma)) model$ma = 0
169    if (is.null(model$gamma)) model$gamma = rep(0, times = order.alpha)
170    # print(unlist(model))
171
172    # Seed:
173    if (is.null(rseed)) {
174        rseed = 0
175    } else {
176        set.seed(rseed)
177    }
178
179    # Define Missing Presample:
180    order.max = max(order.ar, order.ma, order.alpha, order.beta)
181    iterate = TRUE
182    if (!is.matrix(presample)) {
183        if (is.null(presample)) {
184            iterate = FALSE
185            n.start = order.max
186        } else {
187            n.start = presample
188        }
189        z = rnorm(n = n.start)
190        # GARCH(p, q):
191        h = rep(model$omega/(1-sum(model$alpha)-sum(model$beta)),
192            times = n.start)
193        y = rep(model$mu/(1-sum(model$ar)), times = n.start)
194        # APARCH(p,q):
195        #  ... we initialize all models with norm-GARCH(p,q) processes
196    } else {
197        z = presample[, 1]
198        h = presample[, 2]
199        y = presample[, 3]
200    }
201    presample = cbind(z, h, y)
202
203    # Presample Iteration:
204    if (iterate) {
205        n.iterate = length(z) - order.max
206        deltainv = 1/model$delta
207        for (i in n.iterate:1) {
208            h[i] = model$omega +
209                sum(model$alpha*(abs(abs(y[i+(1:order.alpha)]) -
210                    model$gamma*y[i+(1:order.alpha)])^model$delta)) +
211                sum(model$beta*h[i+(1:order.beta)])
212            y[i] = model$mu  +
213                sum(model$ar*y[i+(1:order.ar)]) +
214                sum(model$ma*(h[i+(1:order.ma)]**deltainv)) +
215                h[i]^deltainv * z[i]
216        }
217    }
218
219    # Result:
220    new("fGARCHSPEC",
221        call = match.call(),
222        formula = formula,
223        model = list(omega = model$omega, alpha = model$alpha,
224            gamma = model$gamma, beta = model$beta, mu = model$mu,
225            ar = model$ar, ma = model$ma, delta = model$delta,
226            skew = model$skew, shape = model$shape),
227        presample = as.matrix(presample),
228        distribution = as.character(cond.dist),
229        rseed = as.numeric(rseed)
230    )
231}
232
233
234################################################################################
235
236