Skip to content

Commit

Permalink
update to allow subjective beliefs
Browse files Browse the repository at this point in the history
  • Loading branch information
alanlujan91 committed Feb 15, 2024
1 parent 257a064 commit 6b8e88e
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 34 deletions.
3 changes: 1 addition & 2 deletions code/Portfolio.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
"metadata": {},
"outputs": [],
"source": [
"portfolio_agent = PortfolioLifeCycleConsumerType(\n",
" **parameters.init_consumer_objects)\n",
"portfolio_agent = PortfolioLifeCycleConsumerType(**parameters.init_consumer_objects)\n",
"\n",
"\n",
"portfolio_agent.CRRA = CRRA\n",
Expand Down
20 changes: 20 additions & 0 deletions code/do_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ def run_replication():
q quit: exit without executing.\n\n"""
)

subjective_markets = input(
"""Would you like to add subjective stock or labor market beliefs to the model?:
[1] No
[2] Subjective Stock Market Beliefs
[3] Subjective Labor Market Beliefs
[4] Both\n\n"""
)

replication_specs = {}

if which_model == "1" or which_model == "":
Expand Down Expand Up @@ -124,6 +136,14 @@ def run_replication():
print("Invalid replication choice.")
return

if subjective_markets == "2" or subjective_markets == "4":
replication_specs["subjective_stock_market"] = True
print("Adding subjective stock market beliefs...")

if subjective_markets == "3" or subjective_markets == "4":
replication_specs["subjective_labor_market"] = True
print("Adding subjective labor market beliefs...")

estimate(**replication_specs)


Expand Down
28 changes: 28 additions & 0 deletions code/estimark/calibration/estimation_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@
bootstrap_size = 50 # Number of re-estimations to do during bootstrap
seed = 31382 # Just an integer to seed the estimation

options = {
"initial_wealth_income_ratio_vals": initial_wealth_income_ratio_vals,
"initial_wealth_income_ratio_probs": initial_wealth_income_ratio_probs,
"num_agents": num_agents,
"bootstrap_size": bootstrap_size,
"seed": seed,
"DiscFacAdj_start": DiscFacAdj_start,
"CRRA_start": CRRA_start,
"DiscFacAdj_bound": DiscFacAdj_bound,
"CRRA_bound": CRRA_bound,
"DiscFac_timevary": DiscFac_timevary,
}

# -----------------------------------------------------------------------------
# -- Set up the dictionary "container" for making a basic lifecycle type ------
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -141,6 +154,21 @@
},
}

# from Mateo's JMP for College Educated
ElnR = 0.020
VlnR = 0.424**2

init_subjective_stock_market = {
"Rfree": 1.019, # from Mateo's JMP
"RiskyAvg": np.exp(ElnR + 0.5 * VlnR),
"RiskyStd": np.sqrt(np.exp(2 * ElnR + VlnR) * (np.exp(VlnR) - 1)),
}

init_subjective_labor_market = { # from Tao's JMP
"TranShkStd": [0.03] * len(inc_calib["TranShkStd"]),
"PermShkStd": [0.03] * len(inc_calib["PermShkStd"]),
}

if show_PermGroFacAgg_error:
pass # do nothing
else:
Expand Down
8 changes: 8 additions & 0 deletions code/estimark/calibration/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"make_contour_plot": False,
"compute_standard_errors": False,
"compute_sensitivity": False,
"subjective_stock_market": False,
"subjective_labor_market": False,
}
# Author note:
# This takes approximately 90 seconds on a laptop with the following specs:
Expand All @@ -16,6 +18,8 @@
"make_contour_plot": True,
"compute_standard_errors": False,
"compute_sensitivity": True,
"subjective_stock_market": False,
"subjective_labor_market": False,
}
# Author note:
# This takes approximately 7 minutes on a laptop with the following specs:
Expand All @@ -26,6 +30,8 @@
"make_contour_plot": False,
"compute_standard_errors": True,
"compute_sensitivity": True,
"subjective_stock_market": False,
"subjective_labor_market": False,
}
# Author note:
# This takes approximately 30 minutes on a laptop with the following specs:
Expand All @@ -36,6 +42,8 @@
"make_contour_plot": True,
"compute_standard_errors": True,
"compute_sensitivity": True,
"subjective_stock_market": False,
"subjective_labor_market": False,
}
# Author note:
# This takes approximately 40 minutes on a laptop with the following specs:
Expand Down
69 changes: 43 additions & 26 deletions code/estimark/estimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
"""

# Parameters for the consumer type and the estimation
import estimark.calibration.estimation_parameters as parameters
from estimark.calibration.estimation_parameters import (
init_consumer_objects,
init_subjective_labor_market,
init_subjective_stock_market,
options,
)
import estimark.calibration.setup_scf_data as scf_data # SCF 2004 data on household wealth
import csv
from estimark.agents import (
Expand Down Expand Up @@ -103,8 +108,8 @@ def simulate_moments(
DiscFacAdj,
CRRA,
agent,
DiscFacAdj_bound=parameters.DiscFacAdj_bound,
CRRA_bound=parameters.CRRA_bound,
DiscFacAdj_bound=options["DiscFacAdj_bound"],
CRRA_bound=options["CRRA_bound"],
map_simulated_to_empirical_cohorts=scf_data.simulation_map_cohorts_to_age_indices,
):
"""
Expand All @@ -121,7 +126,7 @@ def simulate_moments(
return 1e30 * np.ones(len(map_simulated_to_empirical_cohorts))

# Update the agent with a new path of DiscFac based on this DiscFacAdj (and a new CRRA)
agent.DiscFac = [b * DiscFacAdj for b in parameters.DiscFac_timevary]
agent.DiscFac = [b * DiscFacAdj for b in options["DiscFac_timevary"]]
agent.CRRA = CRRA
# Solve the model for these parameters, then simulate wealth data
agent.solve() # Solve the microeconomic model
Expand Down Expand Up @@ -153,8 +158,8 @@ def smm_obj_func(
CRRA,
agent,
tgt_moments,
DiscFacAdj_bound=parameters.DiscFacAdj_bound,
CRRA_bound=parameters.CRRA_bound,
DiscFacAdj_bound=options["DiscFacAdj_bound"],
CRRA_bound=options["CRRA_bound"],
map_simulated_to_empirical_cohorts=scf_data.simulation_map_cohorts_to_age_indices,
):
"""
Expand Down Expand Up @@ -358,20 +363,20 @@ def compute_std_err_bootstrap(
# Estimate the model:
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print(
f"Computing standard errors using {parameters.bootstrap_size} bootstrap replications."
f"Computing standard errors using {options['bootstrap_size']} bootstrap replications."
)
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

t_bootstrap_guess = time_to_estimate * parameters.bootstrap_size
t_bootstrap_guess = time_to_estimate * options["bootstrap_size"]
minutes, seconds = divmod(t_bootstrap_guess, 60)
print(f"This will take approximately {int(minutes)} min, {int(seconds)} sec.")

t_start_bootstrap = time()
std_errors = calculate_std_err_bootstrap(
model_estimate,
N=parameters.bootstrap_size,
N=options["bootstrap_size"],
agent=EstimationAgent,
seed=parameters.seed,
seed=options["seed"],
verbose=True,
)
t_end_bootstrap = time()
Expand Down Expand Up @@ -416,8 +421,8 @@ def simulate_moments_redux(x):
x[0],
x[1],
agent=EstimationAgent,
DiscFacAdj_bound=parameters.DiscFacAdj_bound,
CRRA_bound=parameters.CRRA_bound,
DiscFacAdj_bound=options["DiscFacAdj_bound"],
CRRA_bound=options["CRRA_bound"],
map_simulated_to_empirical_cohorts=scf_data.simulation_map_cohorts_to_age_indices,
)

Expand Down Expand Up @@ -515,6 +520,8 @@ def estimate(
compute_standard_errors=local_compute_standard_errors,
compute_sensitivity=local_compute_sensitivity,
make_contour_plot=local_make_contour_plot,
subjective_stock_market=False,
subjective_labor_market=False,
):
"""
Run the main estimation procedure for SolvingMicroDSOP.
Expand Down Expand Up @@ -546,20 +553,30 @@ def estimate(
elif estimation_agent == "WealthPortfolio":
agent_type = WealthPortfolioLifeCycleConsumerType

if subjective_stock_market or subjective_labor_market:
estimation_agent += "Sub"
if subjective_stock_market:
estimation_agent += "(Stock)"
init_consumer_objects.update(init_subjective_stock_market)
if subjective_labor_market:
estimation_agent += "(Labor)"
init_consumer_objects.update(init_subjective_labor_market)
estimation_agent += "Market"

# Make a lifecycle consumer to be used for estimation, including simulated
# shocks (plus an initial distribution of wealth)
# Make a TempConsumerType for estimation
EstimationAgent = agent_type(**parameters.init_consumer_objects)
EstimationAgent = agent_type(**init_consumer_objects)
# Set the number of periods to simulate
EstimationAgent.T_sim = EstimationAgent.T_cycle + 1
# Choose to track bank balances as wealth
EstimationAgent.track_vars = ["bNrm"]
# Draw initial assets for each consumer
EstimationAgent.aNrmInit = DiscreteDistribution(
parameters.initial_wealth_income_ratio_probs,
parameters.initial_wealth_income_ratio_vals,
seed=parameters.seed,
).draw(N=parameters.num_agents)
options["initial_wealth_income_ratio_probs"],
options["initial_wealth_income_ratio_vals"],
seed=options["seed"],
).draw(N=options["num_agents"])
EstimationAgent.make_shock_history()

targeted_moments = get_targeted_moments()
Expand All @@ -575,7 +592,7 @@ def estimate(

initial_guess = np.genfromtxt(csv_file_path, skip_header=1, delimiter=",")
except:
initial_guess = [parameters.DiscFacAdj_start, parameters.CRRA_start]
initial_guess = [options["DiscFacAdj_start"], options["CRRA_start"]]

# Estimate the model using Nelder-Mead
if estimate_model:
Expand Down Expand Up @@ -631,24 +648,24 @@ def estimate_all():
# Make a lifecycle consumer to be used for estimation, including simulated
# shocks (plus an initial distribution of wealth)
# Make a TempConsumerType for estimation
EstimationAgent = agent_type(**parameters.init_consumer_objects)
EstimationAgent = agent_type(**init_consumer_objects)
# Set the number of periods to simulate
EstimationAgent.T_sim = EstimationAgent.T_cycle + 1
# Choose to track bank balances as wealth
EstimationAgent.track_vars = ["bNrm"]
# Draw initial assets for each consumer
EstimationAgent.aNrmInit = DiscreteDistribution(
parameters.initial_wealth_income_ratio_probs,
parameters.initial_wealth_income_ratio_vals,
seed=parameters.seed,
).draw(N=parameters.num_agents)
options["initial_wealth_income_ratio_probs"],
options["initial_wealth_income_ratio_vals"],
seed=options["seed"],
).draw(N=options["num_agents"])
EstimationAgent.make_shock_history()

targeted_moments = get_targeted_moments()

idx = np.unravel_index(count, (2, 2))

initial_guess = [parameters.DiscFacAdj_start, parameters.CRRA_start]
initial_guess = [options["DiscFacAdj_start"], options["CRRA_start"]]
print("----------------------------------------------------------------------")
print(
f"Now estimating the model using Nelder-Mead from an initial guess of {initial_guess}..."
Expand Down Expand Up @@ -695,8 +712,8 @@ def simulate_moments_redux(x):
x[0],
x[1],
agent=EstimationAgent,
DiscFacAdj_bound=parameters.DiscFacAdj_bound,
CRRA_bound=parameters.CRRA_bound,
DiscFacAdj_bound=options["DiscFacAdj_bound"],
CRRA_bound=options["CRRA_bound"],
map_simulated_to_empirical_cohorts=scf_data.simulation_map_cohorts_to_age_indices,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DiscFacAdj,CRRA
0.9900216884662436,4.1368574835978205
Expand Down
4 changes: 2 additions & 2 deletions code/tables/IndShock_estimate_results.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
DiscFacAdj,CRRA
0.9552205116274122,1.3759978446748666
DiscFacAdj,CRRA
0.9552205116274122,1.3759978446748666
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DiscFacAdj,CRRA
0.9911742480356607,6.034052128020187
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DiscFacAdj,CRRA
0.9756577076244863,8.846001517130244
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DiscFacAdj,CRRA
0.9861730357696492,4.425749877454312
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DiscFacAdj,CRRA
0.8623504474809875,7.657921805596357
Expand Down
4 changes: 0 additions & 4 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ channels:
- conda-forge
dependencies:
- python=3.10
- matplotlib
- numpy
- scipy
- pandas
- pip
- pip:
- git+https://github.com/econ-ark/HARK@master

0 comments on commit 6b8e88e

Please sign in to comment.