[R-SIG-Finance] Cox, Ingersoll, Ross/Vasicek parameter estimationviaKalman-Filter (SSPIR)

Thomas Steiner finbref.2006 at gmail.com
Wed May 2 11:55:11 CEST 2007


Hi Gyadav,

Here is some sample code to show my estimation. It uses optim() to estimate.
best
thomas


#data as of 2005-07-25 (EUR)
mat=c(0.002777778, 0.019230769,0.083333333, 0.250000000, 0.500000000,
1.000000000, 2.000000000, 3.000000000, 5.000000000, 7.000000000,
10.000000000, 20.000000000, 30.000000000)
yield=c( 0.02054941, 0.02079584, 0.02104154, 0.02118381, 0.02131600,
0.02159514, 0.02221619, 0.02345148, 0.02602769, 0.02854222,
0.03145786, 0.03411269, 0.03453254)

## very simple example, yields in Vasicek, notation as in Brigo/Mercurio
#takes log(z) as parameter (nonnegativ)
yvas<-function(x,z,rt) {
  z=exp(z)
  k=z[1]
  theta=z[2]
  sigma2=(z[3])^2
  B=1/k*(1-exp(-k*x))
  lnA=(theta-sigma2/(2*k^2))*(B-x)-sigma2/(4*k)*B^2
  return(-(lnA-B*rt)/x)
}

#squaredistance, flag "familie" allowes for other estimation
procedures (CIR, Nelson-Siegel, Svensson)
l2norm<-function(y, z, familie, rt=y[1,2]) { #y is a two-column
datavector with "time(ttm)" und "yield", z are the parameters
  if(familie=="yvasicek") {
    x=y[,1]
    abstand = y[,2] - yvas(x=x,z=z,rt=rt)
    res<-sum(abstand^2)
    return( res )
  }
}

t=seq(from=min(mat),to=max(mat)+8,length=500)
yestV<-nlm(f=l2norm,p=log(c(exp(0.174),yield[1],0.004)),y=cbind(mat,yield),
familie="yvasicek", rt=yield[1], steptol=1e-10, iterlim=500)
#take the exp() to get the real parameter-values
vas.par=exp(yestV$estimate)

plot(mat,yield,col="blue",type="p")
lines(t,yvas(t,log(vas.par),yield[1]),lty="dashed")



More information about the R-SIG-Finance mailing list