1 Simulating returns following a SV-AR(1) structure

library(stochvol)
set.seed(51413)
n     = 500
mu    = -7.3
phi   = 0.98
tau   = 0.18
alpha = mu*(1-phi)
true  = c(alpha,phi,tau)
h     = rep(mu,n)
for (t in 2:n)
  h[t] = alpha+phi*h[t-1]+rnorm(1,0,tau)
y = rnorm(n,0,exp(h/2))

par(mfrow=c(2,1))
ts.plot(exp(h/2),ylab="",main="Time-varying standard deviation")
ts.plot(y,ylab="",main="Simulated returns")

2 Particle filter (pure filter)

set.seed(1234)
m0 = mu
C0 = 1
M  = 10000
h  = rnorm(M,m0,sqrt(C0))
hs = matrix(0,M,n)
pftime = system.time({
for (t in 1:n){
  h1 = rnorm(M,alpha+phi*h,tau)
  w  = dnorm(y[t],0,exp(h1/2))
  h  = sample(h1,replace=TRUE,size=M,prob=w)
  hs[,t] = h
}
})
qsig.smc = t(apply(exp(hs/2),2,quantile,c(0.05,0.5,0.95)))

par(mfrow=c(1,1))
ts.plot(qsig.smc,col=c(3,2,3),ylim=range(qsig.smc),ylab="standard deviation")
lines(0.2*abs(y),type="h")

3 Markov chain Monte Carlo (MCMC)

ndraw = 10000
mcmctime = system.time({
  svfit = svsample(y,draws=ndraw,quiet=TRUE)
})
param = svfit$para[[1]][,1:3]
stdev = exp(svfit$latent[[1]]/2)
qmcmc = t(apply(stdev,2,quantile,c(0.025,0.5,0.975)))

par(mfrow=c(1,1))
ts.plot(qsig.smc,ylim=range(qsig.smc,qmcmc),ylab="Standard deviation")
lines(qmcmc[,1],col=2)
lines(qmcmc[,2],col=2)
lines(qmcmc[,3],col=2)

4 Brute-force MCMC

ts     = seq(5,n,by=5)
nt     = length(ts)
params = array(0,c(nt,ndraw,3))
sigs   = matrix(0,nt,ndraw)
bfmcmctime = system.time({
for (t in 1:nt){
  svfit       = svsample(y[1:ts[t]],draws=ndraw,quiet=TRUE)
  params[t,,] = svfit$para[[1]][,1:3]
  sigs[t,]   = exp(svfit$latent[[1]]/2)[,ts[t]]
}
})
alphas  = t(apply(params[,,1]*(1-params[,,2]),1,quantile,c(0.05,0.5,0.95)))
phis    = t(apply(params[,,2],1,quantile,c(0.05,0.5,0.95)))
taus    = t(apply(params[,,3],1,quantile,c(0.05,0.5,0.95)))
qsig.bf = t(apply(sigs,1,quantile,c(0.05,0.5,0.95)))

par(mfrow=c(2,2))
plot(ts,alphas[,2],ylim=range(alphas),main=expression(alpha),type="l",ylab="")
lines(ts,alphas[,1],lty=2)
lines(ts,alphas[,3],lty=2)
abline(h=true[1],col=2)

plot(ts,phis[,2],ylim=range(phis),main=expression(phi),type="l",ylab="")
lines(ts,phis[,1],lty=2)
lines(ts,phis[,3],lty=2)
abline(h=true[2],col=2)

plot(ts,taus[,2],ylim=range(taus),main=expression(tau),type="l",ylab="")
lines(ts,taus[,1],lty=2)
lines(ts,taus[,3],lty=2)
abline(h=true[3],col=2)

plot(ts,qsig.bf[,2],ylim=range(qsig.bf),main=expression(sigma[t]),type="l",ylab="")
lines(ts,qsig.bf[,1],lty=2)
lines(ts,qsig.bf[,3],lty=2)

5 Comparing SMC and brute-force-MCMC

par(mfrow=c(1,1))
ts.plot(qsig.smc,ylim=range(qsig.smc,qsig.bf),ylab="Standard deviation")
lines(ts,qsig.bf[,1],col=2,type="b",pch=16,cex=0.5)
lines(ts,qsig.bf[,1],col=2,type="b",pch=16,cex=0.5)
lines(ts,qsig.bf[,3],col=2,type="b",pch=16,cex=0.5)
legend("topright",legend=c(
  paste("Sequential Monte Carlo (time=",round(pftime[3],1),"secs)",sep=""),
  paste("Brute-force MCMC (time=",round((ts[2]-ts[1])*bfmcmctime[3],1),"secs)",sep="")),
  col=1:2,lty=1,bty="n",lwd=2)
title(paste("SMC is ",round((ts[2]-ts[1])*bfmcmctime[3]/pftime[3])," faster than Brute-force MCMC",sep=""))

LS0tCnRpdGxlOiAiU1YtQVIoMSkgbW9kZWwiCnN1YnRpdGxlOiAiQnJ1dGUtZm9yY2UgTUNNQyB2cyBTZXF1ZW50aWFsIE1DIgphdXRob3I6ICJIZWRpYmVydCBGcmVpdGFzIExvcGVzIgpkYXRlOiAiMi8xNy8yMDIzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAyCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQotLS0KICAKICBgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCgojIFNpbXVsYXRpbmcgcmV0dXJucyBmb2xsb3dpbmcgYSBTVi1BUigxKSBzdHJ1Y3R1cmUKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMCwgZmlnLmFsaWduID0gJ2NlbnRlcid9CmxpYnJhcnkoc3RvY2h2b2wpCnNldC5zZWVkKDUxNDEzKQpuICAgICA9IDUwMAptdSAgICA9IC03LjMKcGhpICAgPSAwLjk4CnRhdSAgID0gMC4xOAphbHBoYSA9IG11KigxLXBoaSkKdHJ1ZSAgPSBjKGFscGhhLHBoaSx0YXUpCmggICAgID0gcmVwKG11LG4pCmZvciAodCBpbiAyOm4pCiAgaFt0XSA9IGFscGhhK3BoaSpoW3QtMV0rcm5vcm0oMSwwLHRhdSkKeSA9IHJub3JtKG4sMCxleHAoaC8yKSkKCnBhcihtZnJvdz1jKDIsMSkpCnRzLnBsb3QoZXhwKGgvMikseWxhYj0iIixtYWluPSJUaW1lLXZhcnlpbmcgc3RhbmRhcmQgZGV2aWF0aW9uIikKdHMucGxvdCh5LHlsYWI9IiIsbWFpbj0iU2ltdWxhdGVkIHJldHVybnMiKQpgYGAKCiMgUGFydGljbGUgZmlsdGVyIChwdXJlIGZpbHRlcikKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01LCBmaWcuYWxpZ24gPSAnY2VudGVyJ30Kc2V0LnNlZWQoMTIzNCkKbTAgPSBtdQpDMCA9IDEKTSAgPSAxMDAwMApoICA9IHJub3JtKE0sbTAsc3FydChDMCkpCmhzID0gbWF0cml4KDAsTSxuKQpwZnRpbWUgPSBzeXN0ZW0udGltZSh7CmZvciAodCBpbiAxOm4pewogIGgxID0gcm5vcm0oTSxhbHBoYStwaGkqaCx0YXUpCiAgdyAgPSBkbm9ybSh5W3RdLDAsZXhwKGgxLzIpKQogIGggID0gc2FtcGxlKGgxLHJlcGxhY2U9VFJVRSxzaXplPU0scHJvYj13KQogIGhzWyx0XSA9IGgKfQp9KQpxc2lnLnNtYyA9IHQoYXBwbHkoZXhwKGhzLzIpLDIscXVhbnRpbGUsYygwLjA1LDAuNSwwLjk1KSkpCgpwYXIobWZyb3c9YygxLDEpKQp0cy5wbG90KHFzaWcuc21jLGNvbD1jKDMsMiwzKSx5bGltPXJhbmdlKHFzaWcuc21jKSx5bGFiPSJzdGFuZGFyZCBkZXZpYXRpb24iKQpsaW5lcygwLjIqYWJzKHkpLHR5cGU9ImgiKQpgYGAKCiMgTWFya292IGNoYWluIE1vbnRlIENhcmxvIChNQ01DKQoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTUsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQpuZHJhdyA9IDEwMDAwCm1jbWN0aW1lID0gc3lzdGVtLnRpbWUoewogIHN2Zml0ID0gc3ZzYW1wbGUoeSxkcmF3cz1uZHJhdyxxdWlldD1UUlVFKQp9KQpwYXJhbSA9IHN2Zml0JHBhcmFbWzFdXVssMTozXQpzdGRldiA9IGV4cChzdmZpdCRsYXRlbnRbWzFdXS8yKQpxbWNtYyA9IHQoYXBwbHkoc3RkZXYsMixxdWFudGlsZSxjKDAuMDI1LDAuNSwwLjk3NSkpKQoKcGFyKG1mcm93PWMoMSwxKSkKdHMucGxvdChxc2lnLnNtYyx5bGltPXJhbmdlKHFzaWcuc21jLHFtY21jKSx5bGFiPSJTdGFuZGFyZCBkZXZpYXRpb24iKQpsaW5lcyhxbWNtY1ssMV0sY29sPTIpCmxpbmVzKHFtY21jWywyXSxjb2w9MikKbGluZXMocW1jbWNbLDNdLGNvbD0yKQpgYGAKCgojIEJydXRlLWZvcmNlIE1DTUMKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMCwgZmlnLmFsaWduID0gJ2NlbnRlcid9CnRzICAgICA9IHNlcSg1LG4sYnk9NSkKbnQgICAgID0gbGVuZ3RoKHRzKQpwYXJhbXMgPSBhcnJheSgwLGMobnQsbmRyYXcsMykpCnNpZ3MgICA9IG1hdHJpeCgwLG50LG5kcmF3KQpiZm1jbWN0aW1lID0gc3lzdGVtLnRpbWUoewpmb3IgKHQgaW4gMTpudCl7CiAgc3ZmaXQgICAgICAgPSBzdnNhbXBsZSh5WzE6dHNbdF1dLGRyYXdzPW5kcmF3LHF1aWV0PVRSVUUpCiAgcGFyYW1zW3QsLF0gPSBzdmZpdCRwYXJhW1sxXV1bLDE6M10KICBzaWdzW3QsXSAgID0gZXhwKHN2Zml0JGxhdGVudFtbMV1dLzIpWyx0c1t0XV0KfQp9KQphbHBoYXMgID0gdChhcHBseShwYXJhbXNbLCwxXSooMS1wYXJhbXNbLCwyXSksMSxxdWFudGlsZSxjKDAuMDUsMC41LDAuOTUpKSkKcGhpcyAgICA9IHQoYXBwbHkocGFyYW1zWywsMl0sMSxxdWFudGlsZSxjKDAuMDUsMC41LDAuOTUpKSkKdGF1cyAgICA9IHQoYXBwbHkocGFyYW1zWywsM10sMSxxdWFudGlsZSxjKDAuMDUsMC41LDAuOTUpKSkKcXNpZy5iZiA9IHQoYXBwbHkoc2lncywxLHF1YW50aWxlLGMoMC4wNSwwLjUsMC45NSkpKQoKcGFyKG1mcm93PWMoMiwyKSkKcGxvdCh0cyxhbHBoYXNbLDJdLHlsaW09cmFuZ2UoYWxwaGFzKSxtYWluPWV4cHJlc3Npb24oYWxwaGEpLHR5cGU9ImwiLHlsYWI9IiIpCmxpbmVzKHRzLGFscGhhc1ssMV0sbHR5PTIpCmxpbmVzKHRzLGFscGhhc1ssM10sbHR5PTIpCmFibGluZShoPXRydWVbMV0sY29sPTIpCgpwbG90KHRzLHBoaXNbLDJdLHlsaW09cmFuZ2UocGhpcyksbWFpbj1leHByZXNzaW9uKHBoaSksdHlwZT0ibCIseWxhYj0iIikKbGluZXModHMscGhpc1ssMV0sbHR5PTIpCmxpbmVzKHRzLHBoaXNbLDNdLGx0eT0yKQphYmxpbmUoaD10cnVlWzJdLGNvbD0yKQoKcGxvdCh0cyx0YXVzWywyXSx5bGltPXJhbmdlKHRhdXMpLG1haW49ZXhwcmVzc2lvbih0YXUpLHR5cGU9ImwiLHlsYWI9IiIpCmxpbmVzKHRzLHRhdXNbLDFdLGx0eT0yKQpsaW5lcyh0cyx0YXVzWywzXSxsdHk9MikKYWJsaW5lKGg9dHJ1ZVszXSxjb2w9MikKCnBsb3QodHMscXNpZy5iZlssMl0seWxpbT1yYW5nZShxc2lnLmJmKSxtYWluPWV4cHJlc3Npb24oc2lnbWFbdF0pLHR5cGU9ImwiLHlsYWI9IiIpCmxpbmVzKHRzLHFzaWcuYmZbLDFdLGx0eT0yKQpsaW5lcyh0cyxxc2lnLmJmWywzXSxsdHk9MikKYGBgCgojIENvbXBhcmluZyBTTUMgYW5kIGJydXRlLWZvcmNlLU1DTUMKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01LCBmaWcuYWxpZ24gPSAnY2VudGVyJ30KcGFyKG1mcm93PWMoMSwxKSkKdHMucGxvdChxc2lnLnNtYyx5bGltPXJhbmdlKHFzaWcuc21jLHFzaWcuYmYpLHlsYWI9IlN0YW5kYXJkIGRldmlhdGlvbiIpCmxpbmVzKHRzLHFzaWcuYmZbLDFdLGNvbD0yLHR5cGU9ImIiLHBjaD0xNixjZXg9MC41KQpsaW5lcyh0cyxxc2lnLmJmWywxXSxjb2w9Mix0eXBlPSJiIixwY2g9MTYsY2V4PTAuNSkKbGluZXModHMscXNpZy5iZlssM10sY29sPTIsdHlwZT0iYiIscGNoPTE2LGNleD0wLjUpCmxlZ2VuZCgidG9wcmlnaHQiLGxlZ2VuZD1jKAogIHBhc3RlKCJTZXF1ZW50aWFsIE1vbnRlIENhcmxvICh0aW1lPSIscm91bmQocGZ0aW1lWzNdLDEpLCJzZWNzKSIsc2VwPSIiKSwKICBwYXN0ZSgiQnJ1dGUtZm9yY2UgTUNNQyAodGltZT0iLHJvdW5kKCh0c1syXS10c1sxXSkqYmZtY21jdGltZVszXSwxKSwic2VjcykiLHNlcD0iIikpLAogIGNvbD0xOjIsbHR5PTEsYnR5PSJuIixsd2Q9MikKdGl0bGUocGFzdGUoIlNNQyBpcyAiLHJvdW5kKCh0c1syXS10c1sxXSkqYmZtY21jdGltZVszXS9wZnRpbWVbM10pLCIgZmFzdGVyIHRoYW4gQnJ1dGUtZm9yY2UgTUNNQyIsc2VwPSIiKSkKYGBgCgoK