We aim to replicate a table below by using monthly data from 1960-1 to 2020-12.
Note: The panels of Table III that this assignment asks you to replicate appear in their errata published in 1984.
ENV["COLUMNS"]=100; ENV["LINES"]=1000
# Importing packages...
using Pkg; Pkg.activate("./..");
using Distributions, Statistics, Random, HypothesisTests,
LinearAlgebra, Distances, SharedArrays,
Optim, ForwardDiff, NLSolversBase,
Plots, Printf, LaTeXStrings, PlotThemes,
CSV, DataFrames, TimeSeries, Dates,
FredApi, FredData;
Activating project at `c:\Users\jaepi\OneDrive\Documents\GitHub\Prof_Miller_structural_econometrics`
Let $\beta$ be a $k\times1$ vector, $f_i(\beta)$ be a $l\times1$ moments, and $W$ be a $l\times l$ positive definite weighting matrix. Define the GMM criterion function $J(\beta)$ as $$ J(\beta) = N \left(\frac{1}{N}\sum_{i=1}^N f_i(\beta)\right)' W \left(\frac{1}{N}\sum_{i=1}^N f_i(\beta)\right). $$ The GMM estimator is $$ \hat{\beta}_{gmm} = \underset{\beta}{\arg\min}\; J(\beta). $$
Under general regularity conditions, $\sqrt{N}(\hat{\beta}_{gmm}-\beta_0) \xrightarrow[]{d} N(0,V_\beta)$ where $$ \begin{align*} V_\beta &= (Q'WQ)^{-1}(Q'W\Omega WQ)(Q'WQ)^{-1}\\ \Omega &= \mathbb{E}(f_i f_i') \\ Q &= \mathbb{E}\left[\frac{\partial}{\partial \beta'}f_i(\beta)\right]. \end{align*} $$ If $W$ is efficient, $V_\beta = (Q'\Omega^{-1} Q)^{-1}$.
Note that when you compute standard errors for $\hat{\beta}_{gmm}$, you must divide $V_\beta$ by $N$! $V_\beta$ is the variance for $\sqrt{N}(\hat{\beta}_{gmm}-\beta)$, not $\hat{\beta}_{gmm}$ .
In order to construct the efficient GMM estimator, we need to know what is the optimal $W$ in our model. In LIV, we know that $W=(Z'Z)^{-1}$. If the optimal weighting matrix $W=\Omega^{-1}$ is unknown, then we can first estimate $W$ with a standard GMM routine (say, by setting $W=I$), and then do the GMM routine again with $W=\hat{\Omega}^{-1}$.
In this case, we can simply code GMM as follows:
There is small difference between two-step GMM and One-step GMM with $W=(Z'Z)^{-1}$ because two-step GMM estimated $W$. As you increase $N$, this difference will disappear.
One could also iterate steps as many times as you wish until the updated $\hat{\beta}_{gmm}$ converges. This is called Iterated GMM. Note, however, the two-step GMM is already asymptotically efficient. You might want to use iterated GMM if you think the estimates are suffering from small sample.
function iterated_GMM(func, γ, y, X, Z; tol=0.001, max_iter=10)
#=
func: moment(s)
X: the matrix of variables that forms moments we wish to make 0
Z: the matrix orthogonal to moment
tol: if diff<tol, we claim the update converged
max_iter: if iter>max_iter, we stop and report what we have so far.
If max_iter = 2, then it is equivalent to two-step GMM.
=#
γ_GMM = Vector{Vector{Float64}}()
σ_GMM = Vector{Vector{Float64}}()
chi2_vec = Vector{Float64}()
pval_vec = Vector{Float64}()
diff_vec = Vector{Float64}()
N = size(func(γ, y, X, Z))[1];
l = size(func(γ, y, X, Z))[2];
k = length(γ);
df = l-k
func_vec(γ) = vec(sum(func(γ, y, X, Z),dims=1));
# First step
W_1 = I;
obj_GMM_1(γ) = N * (func_vec(γ)/N)' * W_1 * (func_vec(γ)/N);
opt_1 = optimize(obj_GMM_1, randn(k), BFGS(), autodiff = :forward);
γ_GMM_1 = vec(opt_1.minimizer)
Q_1 = ForwardDiff.jacobian(γ -> func_vec(γ) , γ_GMM_1)/N;
Ω_1 = func(γ_GMM_1, y, X, Z)'*func(γ_GMM_1, y, X, Z)/N;
V_GMM_1 = inv(Q_1'*W_1*Q_1)*(Q_1'*W_1*Ω_1*W_1*Q_1)*inv(Q_1'*W_1*Q_1)/N; # remember to divide by N!
σ_GMM_1 = sqrt.(diag(V_GMM_1))
chi2 = obj_GMM_1(γ_GMM_1)
pval = ccdf(Chisq(l-k),obj_GMM_1(γ_GMM_1)) # p-val
push!(γ_GMM, γ_GMM_1)
push!(σ_GMM, σ_GMM_1)
push!(chi2_vec, chi2)
push!(pval_vec, pval)
diff = 1e6
iter = 1
# Iterated GMM
while (diff > tol) & (iter < max_iter)
W_opt = inv(Ω_1)
obj_GMM_2(γ) = N * (func_vec(γ)/N)' * W_opt * (func_vec(γ)/N);
opt_2 = optimize(obj_GMM_2, randn(k), BFGS(), autodiff = :forward);
γ_GMM_2 = vec(opt_2.minimizer)
Q_2 = ForwardDiff.jacobian(γ -> func_vec(γ) , γ_GMM_2)/N;
Ω_2 = func(γ_GMM_2, y, X, Z)'*func(γ_GMM_2, y, X, Z)/N;
V_GMM_2 = inv(Q_2'*W_opt*Q_2)*(Q_2'*W_opt*Ω_2*W_opt*Q_2)*inv(Q_2'*W_opt*Q_2)/N; # remember to divide by N!
σ_GMM_2 = sqrt.(diag(V_GMM_2));
chi2 = obj_GMM_2(γ_GMM_2)
pval = ccdf(Chisq(l-k),obj_GMM_2(γ_GMM_2)) # p-val
# update
diff = sqrt(sum((γ_GMM_2-γ_GMM_1).^2))
Ω_1 = Ω_2
γ_GMM_1 = γ_GMM_2
iter += 1
# record
push!(diff_vec, diff)
push!(γ_GMM, γ_GMM_2)
push!(σ_GMM, σ_GMM_2)
push!(chi2_vec, chi2)
push!(pval_vec, pval)
end
return γ_GMM, σ_GMM, chi2_vec, df, pval_vec, diff_vec
end;
We consider the following model $$ 1=\mathbb{E}_{t}\left[r_{t+1, k} \beta \frac{u^{\prime}\left(c_{t+1}\right)}{u^{\prime}\left(c_{t}\right)}\right] \equiv \mathbb{E}_{t}\left[r_{t+1, k} MRS_{t+1}\right] $$ where:
Subtracting 1 from each side, we have: $$ 0=\mathbb{E}_{t}\left[r_{t+1, k} \beta \frac{u^{\prime}\left(c_{t+1}\right)}{u^{\prime}\left(c_{t}\right)}-1\right] $$ Under the assumption this model is true, we use data $\{(r_{t+1,k},c_{t},c_{t+1})\}_{t=1}^{T}$ and estimate the parameters of interest.
Let's parametrize the utility function as in Hansen and Singleton (1982). $$ u\left(c_{t}\right)=(1+\alpha)^{-1} c_{t}^{1+\alpha} $$ Notice this utility function exhibits constant relative risk aversion (CRRA) if $\alpha<0$. The population moment becomes a specific nonlinear function of data and parameters: $$ \mathbb{E}_t\left[r_{t+1,k}\beta\left(\frac{c_{t+1}}{c_{t}}\right)^{\alpha}-1\right] = 0 $$ where expectation is taken over the information available at $t$. In other words, any deviation from the equality $r_{t+1,k}\beta(\frac{c_{t+1}}{c_{t}})^\alpha-1=0$ is considered as error.
We wish to use information $\mathbf{x_t} \in I_t$ where $I_t$ the information set known by the agent and $\mathbf{x_t}$ a vector of information observed by econometrician at time $t$. If $\mathbf{x_t}$ is orthogonal to the moment, we can use $\mathbf{x_t}$ as an instrument: $$ \mathbb{E}\left[\mathbf{x_t}\varepsilon_t|I_t\right]:=\mathbb{E}\left[\mathbf{x_t}\cdot\left(r_{t+1,k}\beta\left(\frac{c_{t+1}}{c_{t}}\right)^{\alpha}-1\right)\right]=0 $$
We aim to construct the following data in estimation:
We use the following data:
#%% Fred Data: API available at https://github.com/markushhh/FredApi.jl
path = "C:/Users/jaepi/OneDrive/Documents/GitHub/Prof_Miller_structural_econometrics/2. Hansen and Singleton, 1982 (GMM)"
set_api_key("...."); # you should get your own API key!
# Monthly Data:
series_code = ["PCEND","DNDGRG3M086SBEA","PCES","DSERRG3M086SBEA","CNP16OV","GS1","CPIAUCSL"];
series_name = ["PCEND","PPCEND","PCES","PPCES","POP","RF","CPI"];
# Quarterly Data:
realND_code = "A796RX0Q048SBEA"; realND_name = "pce_real_ndg";
realS_code = "A797RX0Q048SBEA"; realS_name = "pce_real_svc";
init_date = "1959-12-01"; end_date = "2020-12-01";
Fred_df = DataFrame()
Fred_df[!,:timestamp] = DataFrame(get_symbols("PCEND",init_date,end_date))[1]
Fred_df[!,Symbol.(series_name[1])] = DataFrame(get_symbols("PCEND",init_date,end_date))[2]
for (i,j) in enumerate(series_code)
Fred_df[!,Symbol(series_name[i])] = DataFrame(get_symbols(j,init_date,end_date))[2]
end
wrds = CSV.read(string(path,"/WRDS.csv"),dateformat="mm/dd/yyyy")[13:end,:]; # 1960/01 to 2020/12
Fred_xt = TimeArray(Fred_df,timestamp=:timestamp);
wrds_xt = TimeArray(wrds,timestamp=:DATE);
local API key is set.
To interpret these results, lifetime utility is: $$ \sum_{t=1}^{\infty} \beta^{t} u\left(c_{t}\right)=(1+\alpha)^{-1} \sum_{t=1}^{\infty} \beta^{t} c_{t}^{1+\alpha} $$
Real Personal Consumption Expenditure on Nondurables $$ c_t = \frac{\text{Nondurables Consumption}_t * 1\text{e}9}{\text{Nondurables CPI}_t/100}*\frac{1}{\text{Population}_t * 1\text{e}3} $$ Real Personal Consumption Expenditure on Nondurables and Services $$ c_t^* = \left(\frac{\text{Nondurables Consumption}_t * 1\text{e}9}{\text{Nondurables CPI}_t/100}+\frac{\text{Services Consumption}_t * 1\text{e}9}{\text{Services CPI}_t/100}\right)*\frac{1}{\text{Population}_t * 1\text{e}3} $$ Real Value-weighted Return (VWRETD) $$ r_t = \text{Real Value-weighted Return}_t = \frac{1+\text{Value-weighted Return}_t}{\text{CPI}_{t}/\text{CPI}_{t-1}} $$ Real Equal-weighted Return (EWRETD) $$ r_t^* = \text{Real Equal-weighted Return}_t = \frac{1+\text{Equal-weighted Return}_t}{\text{CPI}_t/\text{CPI}_{t-1}} $$ Real S&P Return (SPRTRN) $$ r_t^{**} = \text{Real S\&P Return}_t = \frac{1+\text{S\&P Return}_t}{\text{CPI}_t/\text{CPI}_{t-1}} $$
# FROM FED
PCEND = Fred_xt[:PCEND].*1_000_000_000; # Billions of Dollars, Seasonally Adjusted Annual Rate
PPCEND = Fred_xt[:PPCEND]./100; # Index 2012=100, Seasonally Adjusted
PCES = Fred_xt[:PCES].*1_000_000_000; # Billions of Dollars, Seasonally Adjusted Annual Rate
PPCES = Fred_xt[:PPCES]./100; # Index 2012=100, Seasonally Adjusted
POP = Fred_xt[:POP].*1000; # Thousands of Persons
RF =(Fred_xt[:RF]./100)[2:end]; # Percent, Not Seasonally Adjusted from 1960/01 to 2020/12
CPI = Fred_xt[:CPI]./100; # CPI
# FROM WRDS
VWRETD = wrds[:vwretd]; # Value-Weighted Return (Incldues Distributions) (vwretd)
VWRETX = wrds[:vwretx]; # Value-Weighted Return (Excluding Dividends) (vwretx)
EWRETD = wrds[:ewretd]; # Equal-Weighted Return (Includes Distributions) (ewretd)
EWRETX = wrds[:ewretx]; # Equal-Weighted Return (Excluding Dividends) (ewretx)
SPRTRN = wrds[:sprtrn]; # Return on S&P Composite Index (sprtrn)
SPINDX = wrds[:spindx]; # Level on S&P Composite Index (spindx)
# Real Personal Consumption Expenditure
rPCENDpc = PCEND./(PPCEND.*POP);
rPCESpc = PCES./(PPCES.*POP);
rPCEpc = rPCENDpc .+ rPCESpc;
rPCENDpcRatio = rPCENDpc./lag(rPCENDpc,1,padding=false);
rPCEpcRatio = rPCEpc./lag(rPCEpc,1,padding=false);
TimeSeries.rename!(rPCENDpc, :rPCENDpc);
TimeSeries.rename!(rPCESpc, :rPCESpc);
TimeSeries.rename!(rPCEpc, :rPCEpc);
TimeSeries.rename!(rPCENDpcRatio, :rPCENDpcRatio);
TimeSeries.rename!(rPCEpcRatio, :rPCEpcRatio);
# Inflation and Risk-free Return
INF = CPI./lag(CPI,1,padding=false);
nRF = RF; # Nominal risk-free rate
TimeSeries.rename!(INF, :INF);
TimeSeries.rename!(nRF, :nRF);
# S&P market return
rVWRETD = (1 .+ VWRETD) ./ INF
rEWRETD = (1 .+ EWRETD) ./ INF
rSPRTRN = (1 .+ SPRTRN) ./ INF
TimeSeries.rename!(rVWRETD, :rVWRETD);
TimeSeries.rename!(rEWRETD, :rEWRETD);
TimeSeries.rename!(rSPRTRN, :rSPRTRN);
gr(fmt=png);
min_date = Dates.Date(1960,1,1)
max_date = Dates.Date(2020,12,1)
p1 = plot(rPCENDpc,label="",
title=L"C_{t}: \textrm{PCEND per capita (Deflated)}",
xlims = Dates.value.([min_date, max_date]),
xticks= min_date:Year(10):max_date)
p2 = plot(rPCENDpcRatio,label="",
title=L"C_{t+1}/C_{t}: \textrm{PCEND per capita Ratio}",
xlims = Dates.value.([min_date, max_date]),
xticks= min_date:Year(10):max_date)
p3 = plot(rPCEpc,label="",
title=L"C_{t}^{*}: \textrm{PCE per capita (Deflated)}",
xlims = Dates.value.([min_date, max_date]),
xticks= min_date:Year(10):max_date)
p4 = plot(rPCEpcRatio,label="",
title=L"C_{t+1}^{*}/C_{t}^{*}: \textrm{PCE per capita Ratio}",
xlims = Dates.value.([min_date, max_date]),
xticks= min_date:Year(10):max_date)
fig_c=plot(p1, p2, p3, p4, layout = @layout([p1 p3; p2 p4]), label=["" ""],size=(1200,800))
p1 = plot(rVWRETD,label="",
title=L"r_{t} \textrm{: Value-weighted Return}",
xlims = Dates.value.([min_date, max_date]),
xticks= min_date:Year(15):max_date)
p2 = plot(rEWRETD,label="",
title=L"r_{t}^{*} \textrm{: Equal-weighted Return}",
xlims = Dates.value.([min_date, max_date]),
xticks= min_date:Year(15):max_date)
p3 = plot(rSPRTRN,label="",
title=L"r_{t}^{**} \textrm{: S\&P Return}",
xlims = Dates.value.([min_date, max_date]),
xticks= min_date:Year(15):max_date)
fig_r=plot(p1, p2, p3, layout = @layout([p1 p2 p3]), label=["" ""],size=(1200,360))
Before we get into Table III, let's see how we would replicate Table I:
Let's consider the first line. We are using NDS, EWR, in the moment function and one their lagged terms as instruments. $$ \mathbb{E}\left[\begin{pmatrix} 1\\ \frac{c_t^{*}}{c_{t-1}^{*}}\\ r_{t}^{*} \end{pmatrix} \cdot \left(r_{t+1}^{*}\beta\left(\frac{c_{t+1}^{*}}{c_t^{*}}\right)^{\alpha}-1\right)\right] = 0 \\ $$
# TABLE 1: EXAMPLE
# CONSUMPTION: NDS
# RETURN: EWR
# NLAG: 1
C⃰ = values(rPCEpcRatio)[2:end];
r⃰ = values(rEWRETD)[2:end];
X = [C⃰ r⃰]; # N×2 matrix
C⃰_L1 = values(lag(rPCEpcRatio,1,padding=false))[1:end];
r⃰_L1 = values(lag(rEWRETD,1,padding=false))[1:end];
Z = [ones(length(C⃰_L1)) C⃰_L1 r⃰_L1]; # N×l matrix
function f_HS_TABLE1_EXAMPLE(γ, y, X, Z)
#=
γ: parameters. γ[1]=α, γ[2]=β
X: the matrix of variables that forms moments we wish to make 0
Z: the matrix orthogonal to moment
We want to have a N×3 vector
=#
C⃰, r⃰ = X[:,1], X[:,2]
return (r⃰ .* γ[2] .* C⃰.^γ[1] .- y) .* Z # (N×1) ⊗ (N×3)
end;
γ_GMM, σ_GMM, chi2_vec, df, pval_vec, diff_vec = iterated_GMM(f_HS_TABLE1_EXAMPLE, rand(2), ones(length(C⃰)), X, Z; tol=1e-8, max_iter=100);
Note that the code returns p-values as pval_vec
, not "Prob". In Hansen and Singleton (1982), they reported (1-p-value) in the Prob column.
print("Hansen-Singleton GMM Replication: Table I \n")
print("Instrument Variable Estimates for the Period 1960:1 to 2020:12 \n")
print("One-step GMM \n")
print("Consumption | Return | NLAG | α | se(α) | β | se(α) | χ² | DF | p-value ||\n")
@printf("NDS | EWR | 1 | %7.4f | (%7.5f) | %7.4f | (%7.5f) | %6.4f | %2i | %6.4f ||\n",
γ_GMM[1][1], σ_GMM[1][1],γ_GMM[1][2], σ_GMM[1][2], chi2_vec[1], df, pval_vec[1])
Hansen-Singleton GMM Replication: Table I Instrument Variable Estimates for the Period 1960:1 to 2020:12 One-step GMM Consumption | Return | NLAG | α | se(α) | β | se(α) | χ² | DF | p-value || NDS | EWR | 1 | -6.8895 | (4.25675) | 0.9991 | (0.00618) | 0.0000 | 1 | 0.9986 ||
print("Hansen-Singleton GMM Replication: Table I \n")
print("Instrument Variable Estimates for the Period 1960:1 to 2020:12 \n")
print("Two-step GMM \n")
print("Consumption | Return | NLAG | α | se(α) | β | se(α) | χ² | DF | p-value ||\n")
@printf("NDS | EWR | 1 | %7.4f | (%7.5f) | %7.4f | (%7.5f) | %6.4f | %2i | %6.4f ||\n",
γ_GMM[2][1], σ_GMM[2][1], γ_GMM[2][2], σ_GMM[2][2], chi2_vec[2], df, pval_vec[2])
Hansen-Singleton GMM Replication: Table I Instrument Variable Estimates for the Period 1960:1 to 2020:12 Two-step GMM Consumption | Return | NLAG | α | se(α) | β | se(α) | χ² | DF | p-value || NDS | EWR | 1 | -7.9837 | (4.40576) | 1.0013 | (0.00603) | 1.1553 | 1 | 0.2824 ||
print("Hansen-Singleton GMM Replication: Table I \n")
print("Instrument Variable Estimates for the Period 1960:1 to 2020:12 \n")
print("Iterated GMM until convergence with tolerance 1e-8 \n")
print("Consumption | Return | NLAG | α | se(α) | β | se(α) | χ² | DF | p-value | Iteration ||\n")
@printf("NDS | EWR | 1 | %7.4f | (%7.5f) | %7.4f | (%7.5f) | %6.4f | %2i | %6.4f | %5i ||\n",
γ_GMM[end][1], σ_GMM[end][1], γ_GMM[end][2], σ_GMM[end][2], chi2_vec[end], df, pval_vec[end], size(γ_GMM)[1])
Hansen-Singleton GMM Replication: Table I Instrument Variable Estimates for the Period 1960:1 to 2020:12 Iterated GMM until convergence with tolerance 1e-8 Consumption | Return | NLAG | α | se(α) | β | se(α) | χ² | DF | p-value | Iteration || NDS | EWR | 1 | -8.3454 | (4.50449) | 1.0017 | (0.00613) | 0.7906 | 1 | 0.3739 | 16 ||
There is one more complication here: we now have two sets of orthogonality conditions. The first line estimates of Table III uses equally- and value-weighted returns, with one lag for each of the consumption ration and equally- and value-weighted returns. This is a set of 8 population moment conditions in 2 parameters ($\alpha,\beta$).
The degree of freedom (DF) is 2*(1+(NLAG of consumption ratio)+(NLAG of EWR)+(NLAG of VWR))-2
# TABLE 3: EXAMPLE
# CONSUMPTION: NDS
# RETURN: EWR & VWR
# NLAG: 1
C⃰ = values(rPCEpcRatio)[2:end];
r = values(rVWRETD)[2:end];
r⃰ = values(rEWRETD)[2:end];
X = [C⃰ r r⃰];
C⃰_L1 = values(lag(rPCEpcRatio,1,padding=false));
r_L1 = values(lag(rVWRETD,1,padding=false));
r⃰_L1 = values(lag(rEWRETD,1,padding=false));
Z = [ones(length(C⃰_L1)) C⃰_L1 r_L1 r⃰_L1];
function f_HS_TABLE3_EXAMPLE(γ, y, X, Z)
#=
γ: parameters. γ[1]=α, γ[2]=β
X: the matrix of variables that forms moments we wish to make 0
Z: the matrix orthogonal to moment
We want to have a N×8 vector
=#
C⃰, r, r⃰ = X[:,1], X[:,2], X[:,3];
m1 = (r⃰ .* γ[2] .* C⃰.^γ[1] - y) .* Z # (N×1) ⊗ (N×4)
m2 = (r .* γ[2] .* C⃰.^γ[1] - y) .* Z # (N×1) ⊗ (N×4)
return [m1 m2]
end;
In Hansen and Singleton (1984), they describe how they used the nominal risk-free returns:
Their claim is that the degree of freedom is 2* [constant + (risk-free ratio + NLAG for risk-free ratio) + (NLAG for consumption ratio) + (NLAG for VWR)]-2
(Credit to Christine Dabbs) However, it seems like Hansen and Singleton double-counted the number of risk-free ratios. They have df = 8, 16, 32. These numbers are replicable if we counted degree of freedoms as:
2* [constant + 2*(NLAG for risk-free ratio) + (NLAG for consumption ratio) + (NLAG for VWR)]-2
Here, you are now estimating 4 parameters, $(\alpha_1,\beta_1,\alpha_2,\beta_2)$. You may want to find $(\alpha_1,\beta_1)$ only with data from 1960.1 to 1978.12 and $(\alpha_2,\beta_2)$ with data from 1979.1 and onward. You can change f_HS_TABLE3_EXAMPLE
to do this exercise. You can only use data from 1960.1 to 1978.12 for m1
and use data from 1979.1 to 2020.12 for m2
. You may also want to use $4\times1$ vector $\vec{\gamma}$. This is your 'unconstrained' GMM.
Now, you are asked to test $(\alpha_1,\beta_1)=(\alpha_2,\beta_2)$. The following theorem will be helpful:
Let $J_{un}$ be the unconstrained GMM criterion function with $l_1$ orthogonality conditions and $k_1$ parameters. Let $J_{con}$ be the constrained GMM criterion function with $l_2$ orthogonality conditions and $k_2$ parameters. Then, $$ J_{con} - J_{un} \overset{d}{\longrightarrow} \chi^2_{(l_2-k_2)-(l_1-k_1)}. $$
Additionally, you might be able to test models with more parameters in more time frames, say, before/after the financial crisis in 2008 and before/after COVID-19. To do so, you may need more instruments using more lagged variables.
I will leave questions 4 and 5 for you to explore. Now you have basic codes to run, I am sure you can easily modify code and get the estimates.
Let’s come back to data and think about big picture here. Hansen and Singleton (1982) assumes that we have a stationary environment. Test whether any of these series we considered in question 1 have a unit root. (You should read about unit root tests first.) Is there evidencethat these series are not stationary and ergodic?
I use Augmented Dickey-Fuller (ADF) Test. I will let you discuss whether you think time series data we used are stationary and ergodic.
(Not graded) TA's conjecture: Try ADF tests with i) a constant, ii) a trend, iii) a trend and trend squared. What do these tests tell you? If Hansen and Singleton (1982) requires stationarity, how would you incorporate the findings to your model?
varDF = DataFrame(varname=Vector{String}(),
varsymbol=Vector{Symbol}(),
vardata=Vector{TimeArray}())
varDF=vcat(varDF,DataFrame(varname="PCE per Capita (deflated)",varsymbol=:rPCEpc,vardata=rPCEpc))
varDF=vcat(varDF,DataFrame(varname="PCEND per Capita (deflated)",varsymbol=:rPCENDpc,vardata=rPCENDpc))
varDF=vcat(varDF,DataFrame(varname="PCE per Capita (deflated) ratio",varsymbol=:rPCEpcRatio,vardata=rPCEpcRatio))
varDF=vcat(varDF,DataFrame(varname="PCEND per Capita (deflated) ratio",varsymbol=:rPCENDpcRatio,vardata=rPCENDpcRatio))
varDF=vcat(varDF,DataFrame(varname="Real Equal-weighted Returns",varsymbol=:rEWRETD,vardata=rEWRETD))
varDF=vcat(varDF,DataFrame(varname="Real Value-Weighted Returns",varsymbol=:rVWRETD,vardata=rVWRETD))
varDF=vcat(varDF,DataFrame(varname="Real S&P Returns",varsymbol=:rSPRTRN,vardata=rSPRTRN))
for i in 1:4
name = varDF[:varname][i]
symbol = varDF[:varsymbol][i]
data = varDF[:vardata][i]
data = DataFrame(data)[!,symbol][2:end]
print("ADF Test: $name \n")
print(" | Coefficient | Statistic | p-value | \n")
for lags = [1,2,4,6]
stat = ADFTest(data, :none, lags).stat
coef = ADFTest(data, :none, lags).coef
pval = pvalue(ADFTest(data, :none, lags))
print("NLAGS:$lags |")
@printf(" %11.8f | %11.8f | %6.4f | \n", coef, stat, pval)
end
print("\n")
end
ADF Test: PCE per Capita (deflated) | Coefficient | Statistic | p-value | NLAGS:1 | 0.00085897 | 2.85174757 | 0.9996 | NLAGS:2 | 0.00114181 | 3.93944023 | 1.0000 | NLAGS:4 | 0.00131477 | 4.43821690 | 1.0000 | NLAGS:6 | 0.00155524 | 5.11989688 | 1.0000 | ADF Test: PCEND per Capita (deflated) | Coefficient | Statistic | p-value | NLAGS:1 | 0.00128219 | 3.41828302 | 1.0000 | NLAGS:2 | 0.00164927 | 4.51403679 | 1.0000 | NLAGS:4 | 0.00176250 | 4.68681891 | 1.0000 | NLAGS:6 | 0.00189009 | 4.85354412 | 1.0000 | ADF Test: PCE per Capita (deflated) ratio | Coefficient | Statistic | p-value | NLAGS:1 | -0.00004487 | -0.13793068 | 0.6365 | NLAGS:2 | -0.00004233 | -0.14274545 | 0.6348 | NLAGS:4 | -0.00001400 | -0.05039685 | 0.6673 | NLAGS:6 | 0.00003243 | 0.12242773 | 0.7235 | ADF Test: PCEND per Capita (deflated) ratio | Coefficient | Statistic | p-value | NLAGS:1 | -0.00008071 | -0.17065202 | 0.6247 | NLAGS:2 | -0.00008845 | -0.21832532 | 0.6071 | NLAGS:4 | -0.00002615 | -0.07215051 | 0.6598 | NLAGS:6 | 0.00001318 | 0.03774306 | 0.6967 |
for i in 5:size(varDF)[1]
name = varDF[:varname][i]
symbol = varDF[:varsymbol][i]
data = varDF[:vardata][i]
data = DataFrame(data)[!,symbol][2:end]
print("ADF Test: $name \n")
print(" | Coefficient | Statistic | p-value | \n")
for lags = [1,2,4,6]
stat = ADFTest(data, :none, lags).stat
coef = ADFTest(data, :none, lags).coef
pval = pvalue(ADFTest(data, :none, lags))
print("NLAGS:$lags |")
@printf(" %11.8f | %11.8f | %6.4f | \n", coef, stat, pval)
end
print("\n")
end
ADF Test: Real Equal-weighted Returns | Coefficient | Statistic | p-value | NLAGS:1 | -0.00132420 | -0.55045316 | 0.4753 | NLAGS:2 | -0.00079946 | -0.34919278 | 0.5569 | NLAGS:4 | -0.00043876 | -0.20011743 | 0.6139 | NLAGS:6 | -0.00026769 | -0.12388804 | 0.6416 | ADF Test: Real Value-Weighted Returns | Coefficient | Statistic | p-value | NLAGS:1 | -0.00087740 | -0.43674454 | 0.5219 | NLAGS:2 | -0.00047429 | -0.25249830 | 0.5942 | NLAGS:4 | -0.00025356 | -0.14288880 | 0.6348 | NLAGS:6 | -0.00013940 | -0.07966280 | 0.6572 | ADF Test: Real S&P Returns | Coefficient | Statistic | p-value | NLAGS:1 | -0.00082647 | -0.42204541 | 0.5279 | NLAGS:2 | -0.00043780 | -0.24036229 | 0.5988 | NLAGS:4 | -0.00022709 | -0.13279936 | 0.6384 | NLAGS:6 | -0.00012772 | -0.07558289 | 0.6586 |
References: