CHAPTER 21 GENERALIZED ERROR DISTRIBUTION 21.1 ASSIGNMENT Write R functions for the Generalized Error Distribution, GED. Nelson [1991] introduced the Generalized Error Distribution for modeling GARCH time series processes. The GED has exponentially stretched tails. The GED includes the normal distribution as a special case, along with many other distributions. Some are more fat tailed than the normal, for example the double exponential, and others are more thin-tailed like the uniform distribution. Write R functions to compute density, probabilities and quantiles for the GED. Write an R function to generate random variates. Write an R function to estimate the parameters for a GED using the maximum log-likelihood approach. References Daniel B. Nelson, 1991, Conditional Heteroskedasticity in Asset : A New Approach Econometrica 59, 347 370 Wikipedia, Generalized Normal Distribution, 2010, http://en.wikipedia.org/wiki/generalized_normal_distribution 21.2 R IMPLEMENTATION The density of the standardized GED is described by the following formula f (x )= νexp[ 1 z 2 /λν ] λ2 (1+1/ν) Γ(1/ν) where Γ() is the gamma function, and (21.1) 213
214 GENERALIZED ERROR DISTRIBUTION λ [2 2/ν Γ(1/ν)/Γ(3/ν)] 1/2 (21.2) ν is a tail-thickness parameter. When ν = 2, x has a standard normal distribution. For ν<2, the distribution of x has thicker tails than the normal. For example when ν = 1, x has a double exponential distribution. For ν>2, the distribution has thinner tails than the normal, for ν =, x is uniformly distributed on the interval [ 3, 3]. GED density function Write an R function to compute the density for the GED > dged <- function(x, mean = 0, sd = 1, nu = 2) { z = (x - mean)/sd lambda = sqrt(2^(-2/nu) * gamma(1/nu)/gamma(3/nu)) g = nu/(lambda * (2^(1 + 1/nu)) * gamma(1/nu)) density = g * exp(-0.5 * (abs(z/lambda))^nu)/sd density GED probability function Write an R function to compute the probability function for the GED. > pged <- function(q, mean = 0, sd = 1, nu = 2) { q = (q - mean)/sd lambda = sqrt(2^(-2/nu) * gamma(1/nu)/gamma(3/nu)) g = nu/(lambda * (2^(1 + 1/nu)) * gamma(1/nu)) h = 2^(1/nu) * lambda * g * gamma(1/nu)/nu s = 0.5 * (abs(q)/lambda)^nu probability = 0.5 + sign(q) * h * pgamma(s, 1/nu) probability GED quantile function Write an R function to compute the quantile function for the GED. > qged <- function(p, mean = 0, sd = 1, nu = 2) { lambda = sqrt(2^(-2/nu) * gamma(1/nu)/gamma(3/nu)) q = lambda * (2 * qgamma((abs(2 * p - 1)), 1/nu))^(1/nu) quantiles = q * sign(2 * p - 1) * sd + mean quantiles GED random number generation Write an R function to generate random variates from the GED.
21.3. EXAMPLES 215 > rged <- function(n, mean = 0, sd = 1, nu = 2) { lambda = sqrt(2^(-2/nu) * gamma(1/nu)/gamma(3/nu)) r = rgamma(n, 1/nu) z = lambda * (2 * r)^(1/nu) * sign(runif(n) - 1/2) rvs = z * sd + mean rvs GED parameter estimation Write an R function to estimate the parameters from empirical return series data for a GED using the maximum log-likelihood approach. > gedfit <- function(x,...) { start = c(mean = mean(x), sd = sqrt(var(x)), nu = 2) loglik = function(x, y = x) { f = -sum(log(dged(y, x[1], x[2], x[3]))) f fit = nlminb(start = start, objective = loglik, lower = c(-inf, 0, 0), upper = c(inf, Inf, Inf), y = x,...) names(fit$par) = c("mean", "sd", "nu") fit 21.3 EXAMPLES Plot GED density Compute and display the GED with zero mean and unit variance in the range (-4,4) for three different parameter settings of ν,1,2,and3. > x = seq(-4, 4, length = 501) > y = dged(x, mean = 0, sd = 1, nu = 1) > plot(x, y, type = "l",, col = "blue", main = "GED", ylab = "", xlab = "") > y = dged(x, mean = 0, sd = 1, nu = 2) > lines(x, y, col = "red") > y = dged(x, mean = 0, sd = 1, nu = 3) > lines(x, y, col = "green") > abline(h = 0, col = "grey") Normalization of the GED density Show for a random parameter setting of the mean and standard deviation that the GED density is normalized. > set.seed(4711) > MEAN = rnorm(1) > SD = runif(1) > for (NU in 1:3) print(integrate(dged, -Inf, Inf, mean = MEAN,
216 GENERALIZED ERROR DISTRIBUTION GED 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 4 2 0 2 4 FIGURE 21.1: GED Plots for nu=c(1, 2, 3) sd = SD, nu = NU)) 1 with absolute error < 0.00012 1 with absolute error < 5.5e-07 1 with absolute error < 5.6e-05 Repeat this computation for other settings of MEAN and SD. Check the pged and qged functions To check these functions, here for zero mean and unit standard deviation, we compute the quantiles from the probabilities of quantiles. > q = c(0.001, 0.01, 0.1, 0.5, 0.9, 0.99, 0.999) > q [1] 0.001 0.010 0.100 0.500 0.900 0.990 0.999 > p = pged(q) > p [1] 0.50040 0.50399 0.53983 0.69146 0.81594 0.83891 0.84110
21.3. EXAMPLES 217 > qged(p) [1] 0.001 0.010 0.100 0.500 0.900 0.990 0.999 LPP histogram plot We want to test the three Swiss Pension Fund Indices if they are normal distributed. These are Pictet s so calle LPP indices named LPP25, LPP40, and LPP60. The numbers reflect the amount of equities included, thus the indices reflect benchmarks with increasing risk levels. The data set is downloadable from the r-forge web site as a semicolon separated csv file. The file has 10 columns, the first holds the dates, the next 6 index data of bond, reit and stock indices, and the last tree the Swiss pension fund index benchmarks. Download the data and select columns 2 to 4 > library(fecofin) > data(swxlp) > LPP.INDEX <- SWXLP[, 5:7] > head(lpp.index) LP25 LP40 LP60 1 99.81 99.71 99.55 2 98.62 97.93 96.98 3 98.26 97.36 96.11 4 98.13 97.20 95.88 5 98.89 98.34 97.53 6 99.19 98.79 98.21 Compute daily percentual returns > LPP = 100 * diff(log(as.matrix(lpp.index))) Create a nice histogram plot which adds a normal distribution fit to the histogram, adds the mean as a vertical Line, and adds rugs to the x-axis. Use nice colors to display the histogram. > histplot <- function(x,...) { X = as.vector(x) H = hist(x = X,...) box() grid() abline(h = 0, col = "grey") mean = mean(x) sd = sd(x) xlim = range(h$breaks) s = seq(xlim[1], xlim[2], length = 201) lines(s, dnorm(s, mean, sd), lwd = 2, col = "brown") abline(v = mean, lwd = 2, col = "orange") Text = paste("mean:", signif(mean, 3)) mtext(text, side = 4, adj = 0, col = "darkgrey", cex = 0.7) rug(x, ticksize = 0.01, quiet = TRUE) invisible(s)
218 GENERALIZED ERROR DISTRIBUTION LP25 LP40 Mean: 0.0139 Mean: 0.0135 LP60 Mean: 0.0123 FIGURE 21.2: Histogram Plots for the LPP Benchmark Indices Plot the three histograms > par(mfrow = c(2, 2)) > main = colnames(lpp) > for (i in 1:3) histplot(lpp[, i], main = main[i], col = "steelblue", border = "white", nclass = 25, freq = FALSE, xlab = "") Parameter estimation Fit the parameters to a GED for the three LPP benchmark series > param = NULL > for (i in 1:3) param = rbind(param, gedfit(lpp[, i])$par) > rownames(param) = colnames(lpp) > param mean sd nu LP25 0.023525 0.25266 1.1693 LP40 0.032626 0.39439 1.1178 LP60 0.040193 0.59533 1.1053
21.4. EXERCISES 219 LP25 LP40 Mean: 0.0139 Mean: 0.0135 LP60 Mean: 0.0123 FIGURE 21.3: LPP Histogram Plots with fitted Normal (brown) and GED (green). Note that all three histogram plots are on the same scale. Overlay the histograms with a fitted GED > par(mfrow = c(2, 2)) > main = colnames(lpp) > for (i in 1:3) { u = histplot(lpp[, i], main = main[i], col = "steelblue", border = "white", nclass = 25, freq = FALSE, xlab = "") v = dged(u, mean = param[i, 1], sd = param[i, 2], nu = param[i, 3]) lines(u, v, col = "darkgreen", lwd = 2) 21.4 EXERCISES Rewrite the functions dged() as in the case of dnorm() > args(dnorm)
220 GENERALIZED ERROR DISTRIBUTION function (x, mean = 0, sd = 1, log = FALSE) NULL with an additional argument of log. Use this function for the estimation of the distributional parameters in the function gedfit(). Rewrite the functions pged() and qged() as in the case of pnorm() and qnorm() > args(pnorm) function (q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) NULL > args(qnorm) function (p, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) NULL with additional arguments of lower.tail and log.p. The arguments log and log.p are logical values, if TRUE probabilities p are given as log(p). lower.tail is a logical value; if TRUE, probabilities are P[X x ], otherwise, P[X > x ].