Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sign-restrictions #84

Closed
msh855 opened this issue Jun 26, 2023 · 12 comments
Closed

Sign-restrictions #84

msh855 opened this issue Jun 26, 2023 · 12 comments
Labels
question Further information is requested test Requires some more testing

Comments

@msh855
Copy link

msh855 commented Jun 26, 2023

I get an error when I try to use sign restrictions.


irf(run, opt_irf)
Error in sign_restr(sigma_chol = sigma_chol, sign_restr = sign_restr,  : 
  No matrix fitting the sign restrictions found.

Below MWE to reproduce:

data = na.omit(data_raw)
data[, names(data[1])] <- as.Date(data[, names(data[1])])  
data = xts(data[, 2:length(colnames(data))], data[, names(data[1])])

keep <- c("X10Y_GER_daily_change", "EUR_Stocks_daily_log_dif","US_Stocks_daily_log_dif","EURUSD_daily_log_dif",  "Spread_yields_daily_change")
data_var = data[,keep]

mn <- bv_minnesota(lambda = bv_lambda(mode = 0.2, sd = 0.4, min = 0.0001, max = 5), alpha = bv_alpha(mode = 2), var = 1e07)
priors <- bv_priors(mn = bv_mn(b = 0))
mh <- bv_metropolis(scale_hess = 0.05, adjust_acc = TRUE, acc_lower = 0.25, acc_upper = 0.45)
run <- bvar(data_var, lags = 5, priors = priors, 
            mh = mh, 
            n_draw = 50000, 
            n_burn = 25000, 
            n_thin = 1,
            verbose = TRUE)

sr <- matrix(c(1, -1, NA, 1, 1, 
               1, 1, NA, 1,1, 
               1,NA,-1,-1,-1,
               1,NA,1,-1,-1,
               1,1,1,1,-1), ncol = 5)


opt_irf <- bv_irf(horizon = 10, identification = TRUE,  sign_restr = sr)
irf_model <-irf(run, opt_irf, conf_bands = c(0.05, 0.16))

Attached the raw data
bvar_data_raw.csv

@nk027
Copy link
Owner

nk027 commented Jun 26, 2023

Hey Moustafa,
This is not an issue with the code, but rather the restrictions in light of the data (and arguably the algorithm to find suitable matrices). If you think the signs ought to work and this is an issue, you can increase the number of draw attempts (from 1000):

opt_irf <- bv_irf(horizon = 10, identification = TRUE,  sign_restr = sr, sign_lim = 10000)

@nk027 nk027 closed this as completed Jun 26, 2023
@msh855
Copy link
Author

msh855 commented Jun 26, 2023

Thank you,

Still does not work

I literary followed and imposed the sign restrictions as in this paper:
image

https://www.ecb.europa.eu/pub/pdf/scpwps/ecb.wp2560~f98f3c7d78.en.pdf

Though the paper does not follow the HBVAR method, but I expect not be an issue this difference.

@nk027
Copy link
Owner

nk027 commented Jun 27, 2023

That's interesting - if it doesn't stop early on (no shocks found at all) you can increase the allowed draws further. Otherwise I'll try to have a look.

@nk027 nk027 reopened this Jun 27, 2023
@nk027 nk027 added question Further information is requested test Requires some more testing labels Jun 27, 2023
@msh855
Copy link
Author

msh855 commented Jun 27, 2023

I tried already with a very large number of draws.

I would appreciate if you can test it. I send before the input data and the relevant code.

@nk027
Copy link
Owner

nk027 commented Jun 27, 2023

Could it be that the ordering of the variables in Table 1 is off? They list

  • restrictive EA MP & EA LTY versus 10Y GER
  • fav EA macro & EA equity versus EUR Stocks
  • restrictive US MP & US equity versus US Stocks
  • fav US macro & EUR-USD versus EUR-USD
  • fav global risk & LTY spread versus Spreads

Seems like restrictive US MP doesn't fit?

@msh855
Copy link
Author

msh855 commented Jun 28, 2023

Not sure I fully understand what you mean.

Can you please suggest how the table with the sign restrictions should be ?

@msh855
Copy link
Author

msh855 commented Jun 28, 2023

Update
-------

The identification strategy worked with the BEAR toolbox by ECB.

So, it might be the case that Hierarchical BVARs need other configurations or not stable for this problem.

@nk027
Copy link
Owner

nk027 commented Jun 29, 2023

They name a restrictive EA MP shock as based on German bonds, and a favourable EA macro shock as based on European stocks. However, for the US they base a restrictive MP shock o US stocks. That seems inconsistent?

Interesting, that shouldn't be the case – but gives me something to work with.

@msh855
Copy link
Author

msh855 commented Jun 29, 2023

The way you should read from the economics point of view is that a restrictive US MP shock should simultaneously a) increase EURO's area yields, b) depress asset prices in the US, c) narrow the bond spreads and d) appreciate USD vs EUR.

Their identification strategy makes a lot of sense and I don't see some inconsistency (working in trading floor myself what they say is also very true and accurate).

In their identification strategy, they also take into account the global position of US. i.e. if the US "sneezes the rest of the world catches a cold". This is why in their paper discuss about spillovers.

I recommend to try the BEAR toolbox (i can help sending the file with the data in the format BEAR wants it as this part is a bit of a pain) and see why BEAR can do it and not your library.

I think your package has a lot of potentials if you keep working on it - you only need some extra functionalities (e.g. Historical decomposition, ) and make it as robust and flexible as possible.

Please keep me updated and thanks for the help.

@luisgruber
Copy link

Update -------

The identification strategy worked with the BEAR toolbox by ECB.

So, it might be the case that Hierarchical BVARs need other configurations or not stable for this problem.

I don't think that Hierarchical BVARs are not stable for this problem. It seems to me that negative/restrictive shocks are not allowed in the current implementation:

Q <- Q %*% diag((diag(Q) > 0) - (diag(Q) < 0)) # Positive

So, with the sign matrix under consideration,

> sr <- matrix(c(1, -1, NA, 1, 1, 
+                1, 1, NA, 1,1, 
+                1,NA,-1,-1,-1,
+                1,NA,1,-1,-1,
+                1,1,1,1,-1), ncol = 5)
> sr
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]   -1    1   NA   NA    1
[3,]   NA   NA   -1    1    1
[4,]    1    1   -1   -1    1
[5,]    1    1   -1   -1   -1

it will not be possible finding a matrix fitting the sign restrictons.

Would it be valid to change the signs in the columns with a negative diagonal element, then compute the IRFs and eventually change the signs of the IRFs where one is interested in a restrictive shock? E.g.

set.seed(123)
mn <- bv_minnesota(lambda = bv_lambda(mode = 0.2, sd = 0.4, min = 0.0001, max = 5), alpha = bv_alpha(mode = 2), var = 1e07)
priors <- bv_priors(mn = bv_mn(b = 0))
mh <- bv_metropolis(scale_hess = 0.05, adjust_acc = TRUE, acc_lower = 0.25, acc_upper = 0.45)
run <- bvar(data_var, lags = 5, priors = priors, 
            mh = mh, 
            n_draw = 100, 
            n_burn = 90, 
            n_thin = 1,
            verbose = TRUE)
sr_star <- t(t(sr)*c(1,1,-1,-1,-1))
opt_irf <- bv_irf(horizon = 10, identification = TRUE,  sign_restr = sr_star, sign_lim = 50000)
irf_model <-irf(run, opt_irf, conf_bands = c(0.05, 0.16))
irf_model$quants <- aperm(aperm(irf_model$quants,c(4,1,2,3))*c(1,1,-1,-1,-1),c(2,3,4,1))
plot(irf_model)

@nk027
Copy link
Owner

nk027 commented Jan 22, 2024

Hey, I haven't had time to retrace everything, but figured I'd mention that Lukas updated the sign-restriction algorithm in a branch:
https://github.com/nk027/bvar/tree/dev_signs
These restrictions seem to work there, but if there's a bug I'm happy for more details or a PR.

Also, note to self – we really need to test and release these fixed and the HDecomp features.

@nk027
Copy link
Owner

nk027 commented Feb 13, 2024

Had the time to revisit this –
@luisgruber, your approach makes a lot of sense to me.
@msh855, e647054 merges the improvement to how sign restrictions are computed into the main branch – your code runs now – provided you increase sign_lim = 100000 or somewhere around that. I'm leaving the lower default to avoid users getting stuck waiting, but the error message once it fails due to the limit is now more verbose (also irf() now has a verbose argument, which can be used to track the progress).

@nk027 nk027 closed this as completed Feb 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested test Requires some more testing
Projects
None yet
Development

No branches or pull requests

3 participants