I am trying to convert a model I had put together using R's DLM (Dynamic Linear Model) into Eviews Sspace framework. The model is a Nelson Siegal style latent factor model, using inflation expectations rather than bond yields. I can't seem to get estimates anywhere near what I get with R. I've provided the same starting parameters, using the same data, but I get an error "Near singular matrix in "DLM_INFE.ML" on line 525." I suspect the issue is coming in with how I am specifying my error variances, currently I am imposing non-negativity by

Code: Select all

`dlm_infe.append @evar var(g1) = (infe_dlm(18)^2) `

When I change this to the exponential

Code: Select all

`exp(infe_dlm(18))`

I don't get the error, but I do get junk results.

As you are probably aware, the state space representation of the NS model popularised by Diebold and Li, has a VAR(1) process for the state. In R, I parameterise the state VCV matrix directly by setting the matrix Q = to a 3x3 lower triangular matrix of parameters to be estimated (see code below), which then multiply by it's transpose to impose non-negativity and symmetry. So I suspect this is where I am going wrong with my Eviews model, as everything else seems to be the same, however, I am directly imposing the constraints in Eviews.

My Eviews code is below:

Code: Select all

`if @isobject("dlm_infe") =1 then`

delete dlm_infe

endif

vector(6) mprior = 0

sym(6,6) vprior = 0

vprior(1,1) = 0.1

vprior(2,2) = 0.1

vprior(3,3) = 0.1

vprior(4,4) = 0.1

vprior(5,5) = 0.1

vprior(6,6) = 0.1

param infe_dlm(1) 0.06

for !i = 2 to 10

param infe_dlm(!i) 0.5

next

for !i = 11 to 17

param infe_dlm(!i) -1.5

next

for !i = 18 to 23

param infe_dlm(!i) -1

next

'

sspace dlm_infe

dlm_infe.append @vprior vprior

dlm_infe.append @mprior mprior

' Measurment errors

dlm_infe.append @ename e1

dlm_infe.append @ename e2

dlm_infe.append @ename e3

dlm_infe.append @ename e4

dlm_infe.append @ename e5

dlm_infe.append @ename e6

dlm_infe.append @ename e7

'State errors

dlm_infe.append @ename g1

dlm_infe.append @ename g2

dlm_infe.append @ename g3

' Measurment equations

dlm_infe.append @signal infe_1 = level + ((1-exp(-infe_dlm(1)*40 ))/(infe_dlm(1)*40))*slope+(((1-exp(-infe_dlm(1)*40))/(infe_dlm(1)*40)-exp(infe_dlm(1)*40)))*curv + e1

dlm_infe.append @signal infe_2 = level + ((1-exp(-infe_dlm(1)*1))/(infe_dlm(1)*1))*slope+(((1-exp(-infe_dlm(1)*1))/(infe_dlm(1)*1)-exp(infe_dlm(1)*1)))*curv +e2

dlm_infe.append @signal infe_3 = level + ((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4))*slope+(((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4)-exp(infe_dlm(1)*4)))*curv +e3

dlm_infe.append @signal infe_4 = level + ((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4))*slope+(((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4)-exp(infe_dlm(1)*4)))*curv +e4

dlm_infe.append @signal infe_5 = level + ((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8))*slope+(((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8)-exp(infe_dlm(1)*8)))*curv +e5

dlm_infe.append @signal infe_6 = level + ((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4))*slope+(((1-exp(-infe_dlm(1)*4))/(infe_dlm(1)*4)-exp(infe_dlm(1)*4)))*curv +e6

dlm_infe.append @signal infe_7 = level + ((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8))*slope+(((1-exp(-infe_dlm(1)*8))/(infe_dlm(1)*8)-exp(infe_dlm(1)*8)))*curv +e7

' State equations

dlm_infe.append @state level = infe_dlm(2)*level(-1)+infe_dlm(3)*slope(-1)+infe_dlm(4)*curv(-1)+(1-infe_dlm(2))*mean_level(-1)-infe_dlm(3)*mean_slope(-1)-infe_dlm(4)*mean_curv(-1) +g1

dlm_infe.append @state slope = infe_dlm(5)*level(-1)+infe_dlm(6)*slope(-1)+infe_dlm(7)*curv(-1)-infe_dlm(5)*mean_level(-1)+(1-infe_dlm(6))*mean_slope(-1)-infe_dlm(7)*mean_curv(-1) +g2

dlm_infe.append @state curv = infe_dlm(8)*level(-1)+infe_dlm(9)*slope(-1)+infe_dlm(10)*curv(-1)-infe_dlm(8)*mean_level(-1)-infe_dlm(9)*mean_slope(-1)+(1-infe_dlm(10))*mean_curv(-1) +g3

dlm_infe.append @state mean_level = mean_level(-1)

dlm_infe.append @state mean_slope = mean_slope(-1)

dlm_infe.append @state mean_curv = mean_curv(-1)

dlm_infe.append @evar var(e1) = (infe_dlm(11)^2) 'exp(infe_dlm(11)) '

dlm_infe.append @evar var(e2) = (infe_dlm(12)^2) 'exp(infe_dlm(12)) '

dlm_infe.append @evar var(e3) = (infe_dlm(13)^2) 'exp(infe_dlm(13)) '

dlm_infe.append @evar var(e4) = (infe_dlm(14)^2) 'exp(infe_dlm(14))'

dlm_infe.append @evar var(e5) = (infe_dlm(15)^2) 'exp(infe_dlm(15)) '

dlm_infe.append @evar var(e6) = (infe_dlm(16)^2) 'exp(infe_dlm(16)) '

dlm_infe.append @evar var(e7) = (infe_dlm(17)^2) 'exp(infe_dlm(17)) '

' State error variances

dlm_infe.append @evar var(g1) = (infe_dlm(18)^2) 'exp(infe_dlm(18)) '

dlm_infe.append @evar var(g2) = (infe_dlm(19)^2) 'exp(infe_dlm(19)) '

dlm_infe.append @evar var(g3) = (infe_dlm(20)^2) 'exp(infe_dlm(20)) '

dlm_infe.append @evar cov(g1,g2) = infe_dlm(21)

dlm_infe.append @evar cov(g1,g3) = infe_dlm(22)

dlm_infe.append @evar cov(g2,g3) = infe_dlm(23)

smpl 1989:3 2020:1

dlm_infe.ml

And my R code (relevant sections, the matrix qq and W). Note, the exph[] vector simply contains the following, c(40, 1,4,4,8,4,8) which I have hard entered above in the eviews code.

Code: Select all

buildNSInf <- function(p){

exph <- exph

# Deibold and Li Loadings

ff <- c(1,(1-exp(-p[1]*exph[1]))/(p[1]*exph[1]),((1-exp(-p[1]*exph[1]))/(p[1]*exph[1])-exp(-p[1]*exph[1])),0,0,0,

1,(1-exp(-p[1]*exph[2]))/(p[1]*exph[2]),((1-exp(-p[1]*exph[2]))/(p[1]*exph[2])-exp(-p[1]*exph[2])),0,0,0,

1,(1-exp(-p[1]*exph[3]))/(p[1]*exph[3]),((1-exp(-p[1]*exph[3]))/(p[1]*exph[3])-exp(-p[1]*exph[3])),0,0,0,

1,(1-exp(-p[1]*exph[4]))/(p[1]*exph[4]),((1-exp(-p[1]*exph[4]))/(p[1]*exph[4])-exp(-p[1]*exph[4])),0,0,0,

1,(1-exp(-p[1]*exph[5]))/(p[1]*exph[5]),((1-exp(-p[1]*exph[5]))/(p[1]*exph[5])-exp(-p[1]*exph[5])),0,0,0,

1,(1-exp(-p[1]*exph[6]))/(p[1]*exph[6]),((1-exp(-p[1]*exph[6]))/(p[1]*exph[6])-exp(-p[1]*exph[6])),0,0,0,

1,(1-exp(-p[1]*exph[7]))/(p[1]*exph[7]),((1-exp(-p[1]*exph[7]))/(p[1]*exph[7])-exp(-p[1]*exph[7])),0,0,0

)

gg <- c(p[2],p[3],p[4],(1-p[2]),-p[3],-p[4],

p[5],p[6],p[7],-p[5],(1-p[6]),-p[7],

p[8],p[9],p[10],-p[8],-p[9],(1-p[10]),

0, 0,0,1,0,0,

0, 0,0,0,1,0,

0, 0,0,0,0,1

)

qq <- c(p[11],0,0,0,0,0,

p[12],p[13],0,0,0,0,

p[14],p[15],p[16],0,0,0,

0,0,0,0,0,0,

0,0,0,0,0,0,

0,0,0,0,0,0)

hh <- c( p[17],0,0,0,0,0,0,

0,p[18],0,0,0,0,0,

0,0,p[19],0,0,0,0,

0,0,0,p[20],0,0,0,

0,0,0,0,p[21],0,0,

0,0,0,0,0,p[22],0,

0,0,0,0,0,0,p[23])

FF1 <- matrix(ff,7,6, byrow = TRUE)

GG1 <- matrix(gg, 6, 6, byrow = TRUE)

W1 <- matrix(qq,6,6, byrow = TRUE)

V1 <- matrix(hh,7,7, byrow = TRUE)

return(list(

m0 = c(0,0,0,0,0,0),

C0 = bdiag(diag(0.1,3),diag(0.1,3)),

FF = FF1,

GG = GG1,

W = W1%*%t(W1),

V = V1%*%t(V1)

))

}

ggp <- rep(0.5,9)

wp <- rep(-1,6)

vp <- rep(-1.5,7)

dat1 <- matrix(as.numeric(unlist(RBA1[,-c(1:2)])),nrow=nrow(RBA1))

LC <- rep(exp(-8),25)

UC <- rep(exp(12),25)

LC[2:10] <- -Inf

UC[2:10] <- Inf

NSml <- dlmMLE(dat1, parm =c(lam,ggp,wp,vp) , build = buildNSInf,

lower=LC ,

upper=UC ,

control = list(trace = 6, REPORT = 5, maxit = 500))

Of course, I can call R from Eviews to run this code (which, by the way is a fantastic application) but I would really like to understand why R's DLM produces something sensible and why I can't recreate this with Eviews. By sensible, my model converges and the the states look reasonable.

I'm not saying DLM is correct, the error here is no-doubt my own, I just want to understand it so I know for next time :)

Thanks

Adam

I am using Eviews 12 and have updated for the latest patch

More details on R's DLM can be found here:

https://cran.r-project.org/web/packages ... es/dlm.pdf