############################################################################################ # # Univariate stochastic volatility model # ############################################################################################ # # HEDIBERT FREITAS LOPES # Associate Professor of Econometrics and Statistics # The University of Chicago Booth School of Business # 5807 South Woodlawn Avenue # Chicago, Illinois, 60637 # Email : hlopes@ChicagoBooth.edu # URL: http://faculty.chicagobooth.edu/hedibert.lopes/research/ # ############################################################################################ #------------------------------------------------------- # Univariate FFBS: # y(t) ~ N(alpha(t)+F(t)*theta(t);V(t)) # theta(t) ~ N(gamma+G*theta(t-1);W) # #------------------------------------------------------- ffbsu = function(y,F,alpha,V,G,gamma,W,a1,R1,nd=1){ n = length(y) if (length(F)==1){F = rep(F,n)} if (length(alpha)==1){alpha = rep(alpha,n)} if (length(V)==1){V = rep(V,n)} a = rep(0,n) R = rep(0,n) m = rep(0,n) C = rep(0,n) B = rep(0,n-1) H = rep(0,n-1) # time t=1 a[1] = a1 R[1] = R1 f = alpha[1]+F[1]*a[1] Q = R[1]*F[1]**2+V[1] A = R[1]*F[1]/Q m[1] = a[1]+A*(y[1]-f) C[1] = R[1]-Q*A**2 # forward filtering for (t in 2:n){ a[t] = gamma + G*m[t-1] R[t] = C[t-1]*G**2 + W f = alpha[t]+F[t]*a[t] Q = R[t]*F[t]**2+V[t] A = R[t]*F[t]/Q m[t] = a[t]+A*(y[t]-f) C[t] = R[t]-Q*A**2 B[t-1] = C[t-1]*G/R[t] H[t-1] = sqrt(C[t-1]-R[t]*B[t-1]**2) } # backward sampling like = 0.0 theta = matrix(0,nd,n) theta[,n] = rnorm(nd,m[n],sqrt(C[n])) like = dnorm(theta[1,n],m[n],sqrt(C[n]),log=TRUE) for (t in (n-1):1){ theta[,t] = rnorm(nd,m[t]+B[t]*(theta[,t+1]-a[t+1]),H[t]) like = like + dnorm(theta[1,t],m[t]+B[t]*(theta[,t+1]-a[t+1]),H[t],log=TRUE) } if (nd==1){ return(list(theta=theta[1,],like=like)) } else{ theta } } #------------------------------------------------------- # y = X*beta + u u ~ N(0,sig2*I_n) # beta|sig2 ~ N(b,sig2*inv(A)) # sig2 ~ IG(v/2,v*lam/2) #------------------------------------------------------- fixedpar = function(y,X,A,b,v,lam){ n = length(y) k = ncol(X) par1 = (v+n)/2 var = solve(crossprod(X,X)+A) mean = matrix(var%*%(crossprod(X,y)+crossprod(A,b)),k,1) par2 = v*lam + sum((y-crossprod(t(X),mean))^2) par2 = (par2 + crossprod(t(crossprod(mean-b,A)),mean-b))/2 sig2 = 1/rgamma(1,par1,par2) var = var*sig2 mean = mean + crossprod(t(chol(var)),rnorm(2)) return(c(mean,sig2)) } #---------------------------------------------------------------------------- # Sample Z from 1,2,...,k, with P(Z=i) proportional to q[i]N(mu[i],sig2[i]) #---------------------------------------------------------------------------- ncind = function(y,mu,sig,q){ w = dnorm(y,mu,sig)*q return(sample(1:length(q),size=1,prob=w/sum(w))) } #------------------------------------------------ # Quantile statistics #------------------------------------------------ quant05 = function(x){quantile(x,0.05)} quant95 = function(x){quantile(x,0.95)} #------------------------------------------------ # Sampling the log-volatilities in a # standard univariate stochastic volatility model #------------------------------------------------ svu = function(y,lambda,gamma,G,W,a1,R1){ mu = c(-11.40039,-5.24321,-9.83726,1.50746,-0.65098,0.52478,-2.35859) sig2 = c(5.795960,2.613690,5.179500,0.167350,0.640090,0.340230,1.262610) q = c(0.007300,0.105560,0.000020,0.043950,0.340010,0.245660,0.257500) y = log(y^2) sig = sqrt(sig2) z = sapply(y-lambda,ncind,mu,sig,q) run = ffbsu(y,1.0,mu[z],sig2[z],G,gamma,W,a1,R1) return(list(lambda=run$theta,like=run$like)) } ############################################################################## # Approximating a log-Chi^2(1) by a N(-1.270399;4.934854) ############################################################################## x = seq(-20,10,length=10000) den = exp(-(x)/2)*exp(-0.5*exp(x))*exp(x)/sqrt(2*pi) norm = dnorm(x,-1.270399,sqrt(4.934854)) par(mfrow=c(1,1)) plot(x,den,ylab="density",main="",type='n') lines(x,den,col=1,lty=1,lwd=2) lines(x,norm,col=2,lty=2,lwd=2) legend(-15,0.2,legend=c("log chi^2_1","normal"),lty=1:2,col=1:2,lwd=c(2,2),bty="n") title("E(log chi^2_1)=-1.270399 -- V(log chi^2_1)=4.934854") ##################################################################################### # STOCHASTIC VOLATILITY: NORMAL APPROXIMATION + FORWARD FILTERING BACKWARD SAMPLING # ##################################################################################### set.seed(1243) gamma = -0.00645 G = 0.99 W = 0.15^2 lambda0 = 0.0 n = 1000 lambda = rep(0,n) error = rnorm(n,0.0,sqrt(W)) lambda[1] = gamma+G*lambda0+error[1] for (t in 2:n) lambda[t] = gamma+G*lambda[t-1]+error[t] h = exp(lambda/2) y = rnorm(n,0,h) plot(y,type="l") # Prior hyperparameters b = c(0,0) A = diag(0.00000001,2) v = 0.00000002 lam = 1.00000000 a1 = 0 R1 = 1000 # Initial values lambdas = lambda pars = c(gamma,G,sqrt(W)) M0 = 100 M = 100 # Transformations y1 = log(y^2) alpha = -1.270399 V = 4.934854 output = ffbsu(y1,1,alpha,V,G,gamma,W,a1,R1,nd=1) lambda = output$theta prop = output$like logden = sum(dnorm(y,0,exp(lambda/2),log=TRUE))+ sum(dnorm(lambda[2:n],gamma+G*lambda[1:(n-1)],sqrt(W),log=TRUE))-prop accept = rep(0,M0+M) accepted = 0 for (iter in 1:(M0+M)){ print(iter) output = ffbsu(y1,1,alpha,V,G,gamma,W,a1,R1,nd=1) lambda1 = output$theta prop = output$like lognum = sum(dnorm(y,0,exp(lambda1/2),log=TRUE))+sum(dnorm(lambda1[2:n],gamma+G*lambda1[1:(n-1)],sqrt(W),log=TRUE))-prop accept[iter] = min(0,lognum-logden) if (log(runif(1))