HW8 Part 2
HW8 Part 2¶
# imports here
# TODO
# import the data from sign_svar_data.txt
# TODO
# The series are the logs of quarterly US real GDP and CPI, from 1950 until 2009.
# Create a pandas dataframe with proper datetime index and column labels
# make a plot.
# TODO
# Transform the data into annualized growth rates (first difference multiplied by 400)
# create a new dataframe with the growth rates, and label the columns accordingly
# TODO
# Create a VAR model for the growth rates
# TODO
# estimate the model with p=2 including a constant and a time trend
# TODO
# Compute and print the covariance matrix of the residuals, call it Sigma
#Sigma =
#array([[12.17167405, -0.30910097],
# [-0.30910097, 5.92258163]])
# TODO
# Compute the companion matrix of the estimated VAR
# TODO
# Compute and store in variable MA_VAR1 the first 10 coefficients of
# the MA representation of the VAR(1) representaton of the estimated VAR
# Note: use a loop. The function np.linalg.matrix_power may be helpful. The dimensions of MA_VAR1 must be (10, 4, 4)
# TODO from MA_VAR1 compute the coefficients of the MA representation of the estimated VAR. Store in MA_VAR2
# Note: use a selection matrix. The dimensions of MA_VAR2 must be (10, 2, 2)
# TODO
# confirm that MA_VAR2 is identical to the output from results.ma_rep(maxn=10) (results is the estimated VAR)
# Note: you can use numpy's testing.assert_allclose
Suppose that we want to identify aggregate supply and demand shocks. We could impose the following sign restrictions:
a supply shock has a positive effect on output and a negative effect on prices
a demand shock has a positive effect on both output and prices.
Note that these are restrictions on the effect of the shocks on the levels of our variable. We can transform impulse responses of growth rates into impulse responses of levels by computing the cumulative sums.
To impose the sign restrictions we need to find an orthogonal matrix \(Q\) such that the matrix
results in reponses with the right signs, where \(P\) is any matrix such that $\(P P^{\prime} = \Sigma\)$
We can use the Cholesky factor of \(\Sigma\) as our \(P\).
# TODO
# One trivial candidate for Q is the identity matrix.
# Check if it results in impulse responses satisfying our sign restrictions.
# Tip: Remember that we need the cumulative impulse responses. You should make a plot and
# think whether the two orthogonal shocks identified with the Cholesky factor satisfy the sign restrictions
# Also, make sure you understand the order of variables and shocks in the impulse responses you computed.
# At this point we just ask if the shocks could be a supply and a demand shock, but dont impose an order.
Define \(Q(\theta)\) as
for \(\theta \in (0, 2 \pi)\)
# TODO
# Compute Q for theta = 0.2*np.pi. Confirm that it is an orthogonal matrix. Confirm that (P@Q)@(P@Q).T = Sigma
# TODO
# Check if this choice of Q results in impulse responses satisfying our sign restrictions.
# Again, make sure you understand the order of variables and shocks in the impulse responses you computed.
#Tip: You should see responses consistent with our sign restrictions. This can be used to fix the order - which shock is supply and which demand.
Given a 10x2x2 array of impulse responses, we want to be able to check if our sign restroctions are satisfied. That is, see if all responses of output to a supply and demand shocks are positive, all responses of prices to a supply shock are negative, and all responses of prices to a demand shock are positive.
Some ideas for useful ways to index numpy arrays can be explored here
# TODO
#Generate 1000 sets of impulse responses that satisfy the sign restrictions as follows
#- draw theta from the interval (0, 2*pi)
#- compute Q(theta)
#- compute the impulse responses and check if the sign restrictions are satisfied. If yes keep them, otherwise dont.
#- continue until you have 1000 valid sets of impulse responses
# TODO
# Make a 2x2 plot of all impulse responses for each variable and shock.
# Label each subplot (which variable and shock)
# use the same color for each line, and some small value for transparancy (e.g. alpha=0.01)
Another method for generating candidates for Q is based on the QR decomposition. One common approach is to apply it to a random matrix \(H\) with that \(H_{ij} \sim N(0, 1)\), which guarantees that \(H\) is invertable with probability 1. The QR factorization of \(H\) will be unique if the diagonal elements of \(R\) are positive. This can be enforced by reversing the signs of the elements of the i-th column of \(Q\) if the i-th diagonal element of \(R\) is negative. Here is one way to generate such \(Q\) in python
[Q,R] = np.linalg.qr(np.random.randn(n,n))
for j in range(n):
if R[j,j]<0:
Q[:,j] = -Q[:,j]
# TODO
# Generate another 1000 sets of impulse responses that satisfy the sign restrictions using the QR approach.
# Make another 2x2 plot of all impulse responses for each variable and shock.