Coverage for HARK / Calibration / Income / IncomeTools.py: 93%
111 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-07 05:16 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-07 05:16 +0000
1"""
2Created on Sat Dec 19 15:08:54 2020
4@author: Mateo
5"""
7# %% Preamble
9import numpy as np
11from HARK import _log
12from HARK.Calibration.cpi.us.CPITools import cpi_deflator
13from HARK.interpolation import LinearInterp
15__all__ = [
16 "parse_time_params",
17 "Sabelhaus_Song_cohort_trend",
18 "Sabelhaus_Song_all_years",
19 "sabelhaus_song_var_profile",
20 "Cagetti_income",
21 "CGM_income",
22 "parse_income_spec",
23 "find_profile",
24]
27# %% Tools for setting time-related parameters
30def parse_time_params(age_birth, age_death):
31 """
32 Converts simple statements of the age at which an agent is born and the
33 age at which he dies with certainty into the parameters that HARK needs
34 for figuring out the timing of the model.
36 Parameters
37 ----------
38 age_birth : int
39 Age at which the agent enters the model, e.g., 21.
40 age_death : int
41 Age at which the agent dies with certainty, e.g., 100.
43 Returns
44 -------
45 dict
46 Dictionary with parameters "T_cycle" and "T_age" which HARK expects
47 and which map to the birth and death ages specified by the user.
49 """
50 # T_cycle is the number of non-terminal periods in the agent's problem
51 T_cycle = age_death - age_birth
52 # T_age is the age at which the agents are killed with certainty in
53 # simulations (at the end of the T_age-th period)
54 T_age = age_death - age_birth
56 return {"T_cycle": T_cycle, "T_age": T_age}
59# %% Tools for finding the mean profiles of permanent income.
62def age_log_poly_to_growth_rates(coefs, age_min, age_max):
63 """
64 The deterministic component of permanent income is often expressed as a
65 log-polynomial of age. In multiple HARK models, this part of the income
66 process is expressed in a sequence of growth factors 'PermGroFac'.
68 This function computes growth factors from the coefficients of a
69 log-polynomial specification
71 The form of the polynomial is assumed to be
72 alpha_0 + age/10 * alpha_1 + age^2/100 * alpha_2 + ... + (age/10)^n * alpha_n
73 Be sure to adjust the coefficients accordingly.
75 Parameters
76 ----------
77 coefs : numpy array or list of floats
78 Coefficients of the income log-polynomial, in ascending degree order
79 (starting with the constant).
80 age_min : int
81 Starting age at which the polynomial applies.
82 age_max : int
83 Final age at which the polynomial applies.
85 Returns
86 -------
87 GrowthFac : [float] of length age_max - age_min + 1
88 List of growth factors that replicate the polynomial.
90 P0 : float
91 Initial level of income implied my the polynomial
92 """
93 # Figure out the degree of the polynomial
94 deg = len(coefs) - 1
96 # Create age matrices
97 age_10 = np.arange(age_min, age_max + 1).reshape(age_max - age_min + 1, 1) / 10
98 age_mat = np.hstack(list(map(lambda n: age_10**n, range(deg + 1))))
100 # Fing the value of the polynomial
101 lnYDet = np.dot(age_mat, np.array(coefs))
103 # Find the starting level
104 P0 = np.exp(lnYDet[0])
106 # Compute growth factors
107 GrowthFac = np.exp(np.diff(lnYDet))
108 # The last growth factor is nan: we do not know lnYDet(age_max+1)
109 GrowthFac = np.append(GrowthFac, np.nan)
111 return GrowthFac.tolist(), P0
114def find_PermGroFacs(age_min, age_max, age_ret, AgePolyCoefs, ReplRate):
115 r"""
116 Finds initial income and sequence of growth factors from a polynomial
117 specification of log-income, an optional retirement age and a replacement
118 rate.
120 Retirement income will be Income_{age_ret} * ReplRate.
122 Parameters
123 ----------
124 age_min : int
125 Initial age at which to compute the income specification.
126 age_max : int
127 Maximum age up to which the income process must be specified.
128 age_ret : int
129 Age of retirement. Note that retirement happens after labor income is
130 received. For example, age_ret = 65 then the agent will receive labor
131 income up to age 65 and retirement benefits starting at age 66.
132 If age_ret is None, there will be no retirement.
133 AgePolyCoefs : numpy array or list of floats
134 Coefficients of the income log-polynomial, in ascending degree order
135 (starting with the constant). Income follows the specification:
136 ln(P)_age = \sum_{i=1}^{len(AgePolyCoefs)} (age/10)^i * AgePolyCoefs[i]
137 ReplRate : float
138 Replacement rate for retirement income.
140 Returns
141 -------
142 GroFacs : list
143 List of income growth factors.
144 Y0 : float
145 Level of income at age_min
146 """
148 if age_ret is None:
149 # If there is no retirement, the age polynomial applies for the whole
150 # lifetime
151 GroFacs, Y0 = age_log_poly_to_growth_rates(AgePolyCoefs, age_min, age_max)
153 else:
154 # First find working age growth rates and starting income
155 WrkGroFacs, Y0 = age_log_poly_to_growth_rates(AgePolyCoefs, age_min, age_ret)
157 # Replace the last item, which must be NaN, with the replacement rate
158 WrkGroFacs[-1] = ReplRate
160 # Now create the retirement phase
161 n_ret_years = age_max - age_ret
162 RetGroFacs = [1.0] * (n_ret_years - 1) + [np.nan]
164 # Concatenate
165 GroFacs = WrkGroFacs + RetGroFacs
167 return GroFacs, Y0
170def find_profile(GroFacs, Y0):
171 """
172 Generates a sequence {Y_{t}}_{t=0}^N from an initial Y_0 and a sequence
173 of growth factors GroFac[n] = Y_{n+1}/Y_n
175 Parameters
176 ----------
177 GroFacs : list or numpy array
178 Growth factors in chronological order.
179 Y0 : float
180 initial value of the series.
182 Returns
183 -------
184 Y : numpy array
185 Array with the values of the series.
187 """
188 factors = np.array([Y0] + GroFacs)
189 Y = np.cumprod(factors)
191 return Y
194# %% Tools for life-cycle profiles of income volatility
196# The raw results shared by John Sabelhaus contain the following two
197# sets of estimates (with and without cohor trends), which we will
198# use for constructing the age profiles.
200# The first specification contains a cohort trend. The variance of
201# (transitory or permanent) shocks to income of a person born in year
202# "cohort" and who is now age "age" is
203# age_dummy(age) + beta * (cohort - 1926)
204# Where we have dummies for ages 27 to 54
205Sabelhaus_Song_cohort_trend = {
206 "Ages": np.arange(27, 55),
207 "AgeDummiesPrm": np.array(
208 [
209 0.0837941,
210 0.0706855,
211 0.0638561,
212 0.0603879,
213 0.0554693,
214 0.0532388,
215 0.0515262,
216 0.0486079,
217 0.0455297,
218 0.0456573,
219 0.0417433,
220 0.0420146,
221 0.0391508,
222 0.0395776,
223 0.0369826,
224 0.0387158,
225 0.0365356,
226 0.036701,
227 0.0364236,
228 0.0358601,
229 0.0348528,
230 0.0362901,
231 0.0373366,
232 0.0372724,
233 0.0401297,
234 0.0415868,
235 0.0434772,
236 0.046668,
237 ]
238 ),
239 "AgeDummiesTrn": np.array(
240 [
241 0.1412842,
242 0.1477754,
243 0.1510265,
244 0.1512203,
245 0.1516837,
246 0.151412,
247 0.1489388,
248 0.148521,
249 0.1470632,
250 0.143514,
251 0.1411806,
252 0.1378733,
253 0.135245,
254 0.1318365,
255 0.1299689,
256 0.1255799,
257 0.1220823,
258 0.1178995,
259 0.1148793,
260 0.1107577,
261 0.1073337,
262 0.102347,
263 0.0962066,
264 0.0918819,
265 0.0887777,
266 0.0835057,
267 0.0766663,
268 0.0698848,
269 ]
270 ),
271 "CohortCoefPrm": -0.0005966,
272 "CohortCoefTrn": -0.0017764 / 2,
273}
275# The second specification contains no cohort trend. The variance of
276# (transitory or permanent) shocks to income of a person born in year
277# "cohort" and who is now age "age" is: age_dummy(age)
278# Where we have dummies for ages 27 to 54. We use this "aggregate"
279# specification if no cohort is provided.
280Sabelhaus_Song_all_years = {
281 "Ages": np.arange(27, 55),
282 "AgeDummiesPrm": np.array(
283 [
284 0.0599296,
285 0.0474176,
286 0.0411848,
287 0.0383132,
288 0.0339912,
289 0.0323573,
290 0.0312414,
291 0.0289196,
292 0.0264381,
293 0.0271623,
294 0.0238449,
295 0.0247128,
296 0.0224456,
297 0.0234691,
298 0.0214706,
299 0.0238005,
300 0.0222169,
301 0.0229789,
302 0.0232982,
303 0.0233312,
304 0.0229205,
305 0.0249545,
306 0.0265975,
307 0.02713,
308 0.0305839,
309 0.0326376,
310 0.0351246,
311 0.038912,
312 ]
313 ),
314 "AgeDummiesTrn": np.array(
315 [
316 0.1061999,
317 0.1135794,
318 0.1177187,
319 0.1188007,
320 0.1201523,
321 0.1207688,
322 0.1191838,
323 0.1196542,
324 0.1190846,
325 0.1164236,
326 0.1149784,
327 0.1125594,
328 0.1108192,
329 0.1082989,
330 0.1073195,
331 0.1038188,
332 0.1012094,
333 0.0979148,
334 0.0957829,
335 0.0925495,
336 0.0900136,
337 0.0859151,
338 0.0806629,
339 0.0772264,
340 0.0750105,
341 0.0706267,
342 0.0646755,
343 0.0587821,
344 ]
345 ),
346 "CohortCoefPrm": 0,
347 "CohortCoefTrn": 0,
348}
351def sabelhaus_song_var_profile(age_min=27, age_max=54, cohort=None, smooth=True):
352 """
353 This is a function to find the life-cycle profiles of the volatilities
354 of transitory and permanent shocks to income using the estimates in
355 [1] Sabelhaus and Song (2010).
357 Parameters
358 ----------
359 age_min : int, optional
360 Minimum age at which to construct volatilities. The default is 27.
361 age_max : int, optional
362 Maximum age at which to construct volatilities. The default is 54.
363 cohort : int, optional
364 Birth year of the hypothetical person for which the volatilities will
365 be constructed. The default is None, and in this case the we will
366 use the specification that does not have cohort trends.
367 smooth: bool, optional
368 Boolean indicating whether to smooth the variance profile estimates
369 using third degree polynomials for the age dummies estimated by
370 Sabelhaus and Song. If False, the original dummies are used.
372 Returns
373 -------
374 profiles : dict
375 Dictionary with entries:
376 - Ages: array of ages for which we found income volatilities in
377 ascending order
378 - TranShkStd: array of standard deviations of transitory income
379 shocks. Position n corresponds to Ages[n].
380 - PermShkStd: array of standard deviations of permanent income
381 shocks. Position n corresponds to Ages[n].
383 Note that TransShkStd[n] and PermShkStd[n] are the volatilities of
384 shocks _experienced_ at age Age[n], (not those expected at Age[n+1]
385 from the perspective of Age[n]).
387 Note that Sabelhaus and Song work in discrete time and with periods
388 that represent one year. Therefore, the outputs must be interpreted
389 at the yearly frequency.
390 """
392 assert age_max >= age_min, (
393 "The maximum age can not be lower than the " + "minimum age."
394 )
396 # Determine which set of estimates to use based on wether a cohort is
397 # provided or not.
398 if cohort is None:
399 spec = Sabelhaus_Song_all_years
400 cohort = 0
401 _log.debug("No cohort was provided. Using aggregate specification.")
403 else:
404 spec = Sabelhaus_Song_cohort_trend
406 # Extract coefficients
407 beta_eps = spec["CohortCoefTrn"]
408 beta_eta = spec["CohortCoefPrm"]
409 tran_age_dummies = spec["AgeDummiesTrn"]
410 perm_age_dummies = spec["AgeDummiesPrm"]
412 # Smooth out dummies using a 3rd degree polynomial if requested
413 if smooth:
414 # Fit polynomials
415 tran_poly = np.poly1d(np.polyfit(spec["Ages"], tran_age_dummies, deg=3))
416 perm_poly = np.poly1d(np.polyfit(spec["Ages"], perm_age_dummies, deg=3))
418 # Replace dummies
419 tran_age_dummies = tran_poly(spec["Ages"])
420 perm_age_dummies = perm_poly(spec["Ages"])
422 # Make interpolators for transitory and permanent dummies. Alter to use
423 # flat extrapolation.
425 # We use Sabelhaus and Song (2010) dummies for ages 27-54 and extrapolate
426 # outside of that just using the endpoints.
427 tran_dummy_interp = LinearInterp(
428 np.arange(min(spec["Ages"]) - 1, max(spec["Ages"]) + 2),
429 np.concatenate(
430 [[tran_age_dummies[0]], tran_age_dummies, [tran_age_dummies[-1]]]
431 ),
432 lower_extrap=True,
433 )
435 perm_dummy_interp = LinearInterp(
436 np.arange(min(spec["Ages"]) - 1, max(spec["Ages"]) + 2),
437 np.concatenate(
438 [[perm_age_dummies[0]], perm_age_dummies, [perm_age_dummies[-1]]]
439 ),
440 lower_extrap=True,
441 )
443 if age_min < 27 or age_max > 54:
444 _log.debug(
445 "Sabelhaus and Song (2010) provide variance profiles for ages "
446 + "27 to 54. Extrapolating variances using the extreme points."
447 )
449 if cohort < 1926 or cohort > 1980:
450 _log.debug(
451 "Sabelhaus and Song (2010) use data from birth cohorts "
452 + "[1926,1980]. Extrapolating variances."
453 )
455 cohort = max(min(cohort, 1980), 1926)
457 # Construct variances
458 # They use 1926 as the base year for cohort effects.
459 ages = np.arange(age_min, age_max + 1)
460 tran_var = tran_dummy_interp(ages) + (cohort - 1926) * beta_eps
461 perm_var = perm_dummy_interp(ages) + (cohort - 1926) * beta_eta
463 profiles = {
464 "Age": list(ages),
465 "TranShkStd": list(np.sqrt(tran_var)),
466 "PermShkStd": list(np.sqrt(perm_var)),
467 }
469 return profiles
472# %% Encompassing tool to parse full income specifications
475def parse_income_spec(
476 base_monet_year,
477 age_min,
478 age_max,
479 age_ret=None,
480 AgePolyCoefs=None,
481 ReplRate=None,
482 AgePolyRetir=None,
483 YearTrend=None,
484 start_year=None,
485 PermShkStd=None,
486 TranShkStd=None,
487 SabelhausSong=False,
488 adjust_infl_to=None,
489):
490 r"""
491 A function that produces income growth rates and income shock volatilities
493 Parameters
494 ----------
495 base_monet_year : int
496 Base monetary year in which the income process is specified. Answer to
497 "In what year's U.S. dollars was income expressed in the process that
498 will be parsed?".
499 age_min : int
500 Age at which agents enter the model.
501 age_max : int
502 Age at whih agents die with certainty. E.g., if age_max = 100, the
503 agent dies at the end of his 100th year of life.
504 age_ret : int, optional
505 Age of retirement. The default is None.
506 AgePolyCoefs : numpy array or list of floats
507 Coefficients of the income log-polynomial, in ascending degree order
508 (starting with the constant). Permanent income follows the specification:
509 ln(P)_age = \sum_{i=1}^{len(AgePolyCoefs)} (age/10)^i * AgePolyCoefs[i].
510 The default is None.
511 ReplRate : float, optional
512 Replacement rate for retirement income. Retirement income will be
513 Income_{age_ret} * ReplRate. The default is None.
514 AgePolyRetir : numpy array or list of floats
515 Specifies a different age polynomial for income after retirement. It
516 follows the same convention as AgePolyCoefs. The default is None.
517 YearTrend : dict, optional
518 Dictionary with entries "Coef" (float) and "ZeroYear" (int). Allows
519 a time trend to be added to log-income. If provided, mean log-income at
520 age a and year t will be:
521 ln P = polynomial(a) + Coef * (t - ZeroYear)
522 The default is None.
523 start_year : int, optional
524 Year at which the agent enters the model. This is important only for
525 specifications with a time-trend for income profiles.
526 The default is None.
527 PermShkStd : float, optional
528 Standard deviation of log-permanent-income shocks, if it is constant.
529 The default is None.
530 TranShkStd : float, optional
531 Standard deviation of log-transitory-income shocks, if it is constant.
532 The default is None.
533 SabelhausSong : bool, optional
534 Indicates whether to use transitory and permanent income shock
535 volatilities from Sabelhaus & Song (2010) "The Great Moderation in
536 Micro Labor Earnings". The default is False.
537 adjust_infl_to : int, optional
538 Year at which nominal quantities should be expressed. Answers the
539 question "In what year's U.S. dollars should income be expressed".
540 The default is None. In such case, base_monet_year will be used.
542 Returns
543 -------
544 income_params : dict
545 Dictionary with entries:
546 - P0: initial level of permanent income.
547 - pLogInitMean: mean of the distribution of log-permanent income.
548 np.log(P0) = pLogInitMean
549 - PermGroFac : list of deterministic growth factors for permanent
550 income.
551 - PermShkStd: list of standard deviations of shocks to
552 log-permanent income.
553 - TranShkStd: list of standard deviations of transitory shocks
554 to income.
555 - PermGroFacAgg: if a yearly trend in income is provided, this will
556 be the aggregate level of growth in permanent incomes.
557 - T_retire : period of the agent's problem after which they retire.
559 This dictionary has the names and formats that various models in HARK
560 expect, so that it can be directly updated into other parameter
561 dictionaries.
562 """
564 income_params = {}
565 # How many non-terminal periods are there.
566 N_periods = age_max - age_min
568 if age_ret is not None:
569 # How many non terminal periods are spent working
570 N_work_periods = age_ret - age_min + 1
571 # How many non terminal periods are spent in retirement
572 N_ret_periods = age_max - age_ret - 1
574 # Growth factors
575 if AgePolyCoefs is not None:
576 if AgePolyRetir is None:
577 PermGroFac, P0 = find_PermGroFacs(
578 age_min, age_max, age_ret, AgePolyCoefs, ReplRate
579 )
581 else:
582 # Working period
583 PermGroWrk, P0 = find_PermGroFacs(
584 age_min, age_ret, None, AgePolyCoefs, ReplRate
585 )
586 PLast = find_profile(PermGroWrk[:-1], P0)[-1]
588 # Retirement period
589 PermGroRet, R0 = find_PermGroFacs(
590 age_ret + 1, age_max, None, AgePolyRetir, ReplRate
591 )
593 # Input the replacement rate into the Work grow factors
594 PermGroWrk[-1] = R0 / PLast
595 PermGroFac = PermGroWrk + PermGroRet
597 # In any case, PermGroFac[-1] will be np.nan, signaling that there is
598 # no expected growth in the terminal period. Discard it, as HARK expect
599 # list of growth rates for non-terminal periods
600 PermGroFac = PermGroFac[:-1]
602 # Apply the yearly trend if it is given
603 if YearTrend is not None:
604 # Compute and apply the compounding yearly growth factor
605 YearGroFac = np.exp(YearTrend["Coef"])
606 PermGroFac = [x * YearGroFac for x in PermGroFac]
608 # Aggregate growth
609 income_params["PermGroFacAgg"] = YearGroFac
611 # Adjust P0 with the year trend
612 if start_year is not None:
613 P0 = P0 * np.power(YearGroFac, start_year - YearTrend["ZeroYear"])
615 income_params["PermGroFac"] = PermGroFac
617 else:
618 # Placeholder for future ways of storing income calibrations
619 raise NotImplementedError()
621 # Volatilities
622 # In this section, it is important to keep in mind that IncomeDstn[t]
623 # is the income distribution from period t to t+1, as perceived in period
624 # t.
625 # Therefore (assuming an annual model with agents entering at age 0),
626 # IncomeDstn[3] would contain the distribution of income shocks that occur
627 # at the start of age 4.
628 if SabelhausSong:
629 if age_ret is None:
630 IncShkStds = sabelhaus_song_var_profile(
631 cohort=1950, age_min=age_min + 1, age_max=age_max
632 )
633 PermShkStd = IncShkStds["PermShkStd"]
634 TranShkStd = IncShkStds["TranShkStd"]
636 else:
637 IncShkStds = sabelhaus_song_var_profile(
638 cohort=1950, age_min=age_min + 1, age_max=age_ret
639 )
640 PermShkStd = IncShkStds["PermShkStd"] + [0.0] * (N_ret_periods + 1)
641 TranShkStd = IncShkStds["TranShkStd"] + [0.0] * (N_ret_periods + 1)
643 else:
644 if isinstance(PermShkStd, float) and isinstance(TranShkStd, float):
645 if age_ret is None:
646 PermShkStd = [PermShkStd] * N_periods
647 TranShkStd = [TranShkStd] * N_periods
649 else:
650 PermShkStd = [PermShkStd] * (N_work_periods - 1) + [0.0] * (
651 N_ret_periods + 1
652 )
653 TranShkStd = [TranShkStd] * (N_work_periods - 1) + [0.0] * (
654 N_ret_periods + 1
655 )
657 else:
658 # Placeholder for future ways of specifying volatilities
659 raise NotImplementedError()
661 income_params["PermShkStd"] = PermShkStd
662 income_params["TranShkStd"] = TranShkStd
664 # Apply inflation adjustment if requested
665 if adjust_infl_to is not None:
666 # Deflate using the CPI september measurement, which is what the SCF
667 # uses.
668 defl = cpi_deflator(
669 from_year=base_monet_year, to_year=adjust_infl_to, base_month="SEP"
670 )[0]
672 else:
673 defl = 1
675 P0 = P0 * defl
676 income_params["P0"] = P0
677 income_params["pLogInitMean"] = np.log(P0)
678 income_params["T_retire"] = N_work_periods
680 return income_params
683# %% Income specifications from various papers
685# Processes from Cocco, Gomes, Maenhout (2005):
686# Cocco, J. F., Gomes, F. J., & Maenhout, P. J. (2005). Consumption and
687# portfolio choice over the life cycle. The Review of Financial Studies,
688# 18(2), 491-533.
689# - The profiles are provided as presented in the original paper.
690# - It seem to us that income peaks at very young ages.
691# - We suspect this might be due to the author's treatment of trends in income
692# growth.
693# - This can be adressed using the YearTrend and pLvlGroFacAgg options.
694CGM_income = {
695 "NoHS": {
696 "AgePolyCoefs": [-2.1361 + 2.6275, 0.1684 * 10, -0.0353 * 10, 0.0023 * 10],
697 "age_ret": 65,
698 "ReplRate": 0.8898,
699 "PermShkStd": np.sqrt(0.0105),
700 "TranShkStd": np.sqrt(0.1056),
701 "base_monet_year": 1992,
702 },
703 "HS": {
704 "AgePolyCoefs": [-2.1700 + 2.7004, 0.1682 * 10, -0.0323 * 10, 0.0020 * 10],
705 "age_ret": 65,
706 "ReplRate": 0.6821,
707 "PermShkStd": np.sqrt(0.0106),
708 "TranShkStd": np.sqrt(0.0738),
709 "base_monet_year": 1992,
710 },
711 "College": {
712 "AgePolyCoefs": [-4.3148 + 2.3831, 0.3194 * 10, -0.0577 * 10, 0.0033 * 10],
713 "age_ret": 65,
714 "ReplRate": 0.9389,
715 "PermShkStd": np.sqrt(0.0169),
716 "TranShkStd": np.sqrt(0.0584),
717 "base_monet_year": 1992,
718 },
719}
721# Processes from Cagetti (2003)
722# Cagetti, M. (2003). Wealth accumulation over the life cycle and precautionary
723# savings. Journal of Business & Economic Statistics, 21(3), 339-353.
724# - The author generously provided estimates from which the age polynomials
725# and yearly trends were recovered.
726# - He uses volatilities from Carroll-Samwick (1997)
727# - He expresses income in dollars. It is more amicable to express it in
728# thousands of dollars, also making it comparable to CGM. Thus, we substract
729# ln(1e3) = 3*ln(10) from intercepts, which is equivalent to dividing income
730# by a thousand.
731Cagetti_income = {
732 "NoHS": {
733 "AgePolyCoefs": [
734 7.99641616 - 3.0 * np.log(10),
735 1.06559456,
736 -0.14449728,
737 0.00048128,
738 0.0004096,
739 ],
740 "AgePolyRetir": [10.84636791 - 3.0 * np.log(10), -0.24562326],
741 "YearTrend": {"Coef": 0.016, "ZeroYear": 1980},
742 "age_ret": 65,
743 "PermShkStd": np.sqrt(0.0214), # Take 9-12 from CS
744 "TranShkStd": np.sqrt(0.0658), # Take 9-12 from CS
745 "base_monet_year": 1992,
746 },
747 "HS": {
748 "AgePolyCoefs": [
749 10.01333075 - 3.0 * np.log(10),
750 -0.563234304,
751 0.348710528,
752 -0.059442176,
753 0.002947072,
754 ],
755 "AgePolyRetir": [11.21721558 - 3.0 * np.log(10), -0.26820465],
756 "YearTrend": {"Coef": 0.016, "ZeroYear": 1980},
757 "age_ret": 65,
758 "PermShkStd": np.sqrt(0.0277), # Take HS diploma from CS
759 "TranShkStd": np.sqrt(0.0431), # Take HS diploma from CS
760 "base_monet_year": 1992,
761 },
762 "College": {
763 "AgePolyCoefs": [
764 9.916855488 - 3.0 * np.log(10),
765 -0.057984416,
766 0.146196992,
767 -0.027623424,
768 0.001282048,
769 ],
770 "AgePolyRetir": [10.81011279 - 3.0 * np.log(10), -0.16610233],
771 "YearTrend": {"Coef": 0.016, "ZeroYear": 1980},
772 "age_ret": 65,
773 "PermShkStd": np.sqrt(0.0146), # Take College degree from CS
774 "TranShkStd": np.sqrt(0.0385), # Take College degree from CS
775 "base_monet_year": 1992,
776 },
777}