Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
7377c2a
add new parameters to determination of r_gov
jdebacker Jun 16, 2025
04ea584
SS r_gov updates
jdebacker Jun 16, 2025
3167610
update DG path
jdebacker Jun 16, 2025
b5322d8
new param tools
jdebacker Jun 17, 2025
3011630
update get_r_gov for scalar case
jdebacker Jun 17, 2025
fafeef0
make dy params scalars
jdebacker Jun 25, 2025
e238d83
fix if else
jdebacker Jun 25, 2025
f20deb4
fix order of r_gv[t]
jdebacker Jun 25, 2025
c4b5852
test scalar case
jdebacker Jun 25, 2025
7e9abf3
update r_gov in docs
jdebacker Jun 25, 2025
fca981d
update r_gov tests
jdebacker Jun 25, 2025
ee2b4ae
format
jdebacker Jun 25, 2025
c4d84ce
create rather than read in base_params
jdebacker Jun 26, 2025
626b246
create rather than read in params
jdebacker Jun 26, 2025
641bff5
remove unused pkl files from test folder
jdebacker Jun 26, 2025
594d659
create rather than read in params
jdebacker Jun 26, 2025
7e072cd
format
jdebacker Jun 26, 2025
ec6f1ca
fix capital letters in debt_ratio_ss param
jdebacker Jun 26, 2025
f4db5b8
add new test with r_gov as function of D/Y
jdebacker Jun 26, 2025
2e7837f
bump version
jdebacker Jun 26, 2025
7b20c48
bump version and update changelog
jdebacker Jun 26, 2025
0c73554
different initial values
jdebacker Jun 30, 2025
8ebc4e2
more testing
jdebacker Jul 1, 2025
0be7e96
temp changes
jdebacker Jul 9, 2025
c53c4bf
conform test dims with get_r_gov function expected dims
jdebacker Jul 11, 2025
41e75dd
temp save
jdebacker Jul 14, 2025
bd16dab
remove pickle files and replace with params in dicts in tets
jdebacker Nov 24, 2025
02ea910
format
jdebacker Nov 24, 2025
5bd880c
uncomment tests
jdebacker Nov 24, 2025
ae20415
add back params
jdebacker Nov 24, 2025
3512ec5
use rnew
jdebacker Dec 3, 2025
5df7fa2
temp change for testing
jdebacker Dec 3, 2025
810db2b
merge in master and fix version
jdebacker Jan 18, 2026
0c34775
format with black 26.1
jdebacker Jan 18, 2026
0e4b368
bump version
jdebacker Jan 18, 2026
6555003
remove comment
jdebacker Jan 18, 2026
90f8ec7
sync master and resolve conflicts:
jdebacker Jan 18, 2026
fdeb8e4
use scalar method for ss
jdebacker Jan 19, 2026
0d46b60
fix test params
jdebacker Jan 19, 2026
7d40f8a
change order of determining r_gov
jdebacker Jan 19, 2026
165f248
consistent use of var mapping
jdebacker Jan 19, 2026
dbfa3ec
uncomment all full run tests
jdebacker Jan 19, 2026
ce41278
format
jdebacker Jan 19, 2026
224b326
update changelog
jdebacker Jan 20, 2026
53aaa46
update outputs for extra run
jdebacker Jan 21, 2026
36270b2
format
jdebacker Jan 21, 2026
6b2a7fc
update date in changelog
jdebacker Jan 22, 2026
c653499
add some diagnostics
jdebacker Jan 22, 2026
bc9dc7a
copy arrays
jdebacker Jan 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.15.2] - 2025-01-22 12:00:00

### Added

- A new parameters, `r_gov_DY` and `r_gov_DY2`, that allow the government interest rate to be a function of the debt-to-GDP ratio. See PR [#1037](https://github.com/PSLmodels/OG-Core/pull/1037)

## [0.15.1] - 2026-01-19 12:00:00

### Added
Expand Down Expand Up @@ -493,6 +499,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Any earlier versions of OG-USA can be found in the [`OG-Core`](https://github.com/PSLmodels/OG-Core) repository [release history](https://github.com/PSLmodels/OG-Core/releases) from [v.0.6.4](https://github.com/PSLmodels/OG-Core/releases/tag/v0.6.4) (Jul. 20, 2021) or earlier.


[0.15.2]: https://github.com/PSLmodels/OG-Core/compare/v0.15.1...v0.15.2
[0.15.1]: https://github.com/PSLmodels/OG-Core/compare/v0.15.0...v0.15.1
[0.15.0]: https://github.com/PSLmodels/OG-Core/compare/v0.14.14...v0.15.0
[0.14.14]: https://github.com/PSLmodels/OG-Core/compare/v0.14.13...v0.14.14
[0.14.13]: https://github.com/PSLmodels/OG-Core/compare/v0.14.12...v0.14.13
Expand Down
6 changes: 3 additions & 3 deletions docs/book/content/theory/government.md
Original file line number Diff line number Diff line change
Expand Up @@ -667,14 +667,14 @@ Note that the budget closure rule (described in Section ref{`SecUnbalGBCcloseRul
(SecRateWedge)=
## Interest Rate on Government Debt and Household Savings

Despite the model having no aggregate risk, it may be helpful to build in an interest rate differential between the rate of return on private capital and the interest rate on government debt. Doing so helps to add realism by including a risk premium. `OG-Core` allows users to set an exogenous wedge between these two rates. The interest rate on government debt,
Despite the model having no aggregate risk, it may be helpful to build in an interest rate differential between the rate of return on private capital and the interest rate on government debt. Doing so helps to add realism by including a risk premium. `OG-Core` allows users to set an exogenous wedge between these two rates. `OG-Core` also allows for the risk premium on debt to be a quadratic function of the debt-to-GDP ratio. The interest rate on government debt is given by:

```{math}
:label: EqUnbalGBC_rate_wedge
r_{gov, t} = (1 - \tau_{d, t})r_{t} - \mu_{d}
r_{gov, t} = (1 - \tau_{d, t})r_{t} - \mu_{d} + \beta_{1}\frac{D_t}{Y_t} + \beta_{2}\left(\frac{D_t}{Y_t}\right)^2
```

where $r_t$ is the marginal product of capital faced by firms. The two parameters, $\tau_{d,t}$ and $\mu_{d,t}$ can be used to allow for a government interest rate that is a percentage hair cut from the market rate or a government interest rate with a constant risk premium.
where $r_t$ is the marginal product of capital faced by firms. The two parameters, $\tau_{d,t}$ and $\mu_{d,t}$ can be used to allow for a government interest rate that is a percentage hair cut from the market rate or a government interest rate with a constant risk premium. The parameters $\beta_1$ and $\beta_2$ can be used to allow for a quadratic risk premium on government debt that is a function of the debt-to-GDP ratio.


(SecUnbalGBCcloseRule)=
Expand Down
6 changes: 3 additions & 3 deletions ogcore/SS.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ def inner_loop(outer_loop_vars, p, client):
B = aggr.get_B(bssmat, p, "SS", False)

# Find gov't debt
r_gov = fiscal.get_r_gov(r, p, "SS")
r_gov = fiscal.get_r_gov(r, p.debt_ratio_ss, p, "scalar", t=-1)
D, D_d, D_f, new_borrowing, _, new_borrowing_f = fiscal.get_D_ss(
r_gov, Y, p
)
Expand Down Expand Up @@ -495,7 +495,7 @@ def inner_loop(outer_loop_vars, p, client):
new_r = firm.get_r(Y_vec[-1], K_vec[-1], p_m, p, "SS", -1)
new_w = firm.get_w(Y_vec[-1], L_vec[-1], p_m, p, "SS")

new_r_gov = fiscal.get_r_gov(new_r, p, "SS")
new_r_gov = fiscal.get_r_gov(new_r, p.debt_ratio_ss, p, "scalar", t=-1)
# now get accurate measure of debt service cost
(
D,
Expand Down Expand Up @@ -829,7 +829,7 @@ def SS_solver(
K_vec_ss = new_K_vec
L_vec_ss = new_L_vec
Y_vec_ss = new_Y_vec
r_gov_ss = fiscal.get_r_gov(rss, p, "SS")
r_gov_ss = fiscal.get_r_gov(rss, p.debt_ratio_ss, p, "scalar", t=-1)
p_m_ss = new_p_m
p_i_ss = np.dot(p.io_matrix, p_m_ss)
p_tilde_ss = aggr.get_ptilde(p_i_ss, p.tau_c[-1, :], p.alpha_c)
Expand Down
28 changes: 17 additions & 11 deletions ogcore/TPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,8 @@ def run_TPI(p, client=None):
total_tax_revenue = np.ones(p.T + p.S) * ss_vars["total_tax_revenue"]

# Compute other interest rates
r_gov = fiscal.get_r_gov(r, p, "TPI")
r_gov = np.ones_like(r) * ss_vars["r_gov"]
r_gov[: p.T] = fiscal.get_r_gov(r[: p.T], D[: p.T] / Y[: p.T], p, "TPI")
r_p = np.ones_like(r) * ss_vars["r_p"]
MPKg = np.zeros((p.T, p.M))
for m in range(p.M):
Expand Down Expand Up @@ -1082,6 +1083,11 @@ def run_TPI(p, client=None):
"TPI",
)
total_tax_revenue[: p.T] = total_tax_rev
if not p.baseline_spending:
I_g = fiscal.get_I_g(Y[: p.T], None, p, "TPI")
if p.baseline:
K_g0 = p.initial_Kg_ratio * Y[0]
K_g = fiscal.get_K_g(K_g0, I_g, p, "TPI")
dg_fixed_values = (
Y,
total_tax_revenue,
Expand All @@ -1097,18 +1103,12 @@ def run_TPI(p, client=None):
G[: p.T],
D_d[: p.T],
D_f[: p.T],
r_gov_new,
new_borrowing,
debt_service,
new_borrowing_f,
) = fiscal.D_G_path(r_gov, dg_fixed_values, p)
K[: p.T], K_d[: p.T], K_f[: p.T] = aggr.get_K_splits(
B[: p.T], K_demand_open_vec.sum(-1), D_d[: p.T], p.zeta_K[: p.T]
)
if not p.baseline_spending:
I_g = fiscal.get_I_g(Y[: p.T], None, p, "TPI")
if p.baseline:
K_g0 = p.initial_Kg_ratio * Y[0]
K_g = fiscal.get_K_g(K_g0, I_g, p, "TPI")
) = fiscal.D_G_path(r, dg_fixed_values, p)

rnew = r.copy()
rnew[: p.T] = np.squeeze(
firm.get_r(
Expand All @@ -1117,14 +1117,20 @@ def run_TPI(p, client=None):
)
# For case where economy is small open econ
rnew[p.zeta_K == 1] = p.world_int_rate[p.zeta_K == 1]
r_gov_new = fiscal.get_r_gov(rnew, p, "TPI")
MPKg_vec = np.zeros((p.T, p.M))
for m in range(p.M):
MPKg_vec[:, m] = np.squeeze(
firm.get_MPx(
Y_vec[: p.T, m], K_g[: p.T], p.gamma_g[m], p, "TPI", m
)
)

K[: p.T], K_d[: p.T], K_f[: p.T] = aggr.get_K_splits(
B[: p.T], K_demand_open_vec.sum(-1), D_d[: p.T], p.zeta_K[: p.T]
)
r_gov_new = fiscal.get_r_gov(
rnew[: p.T], Dnew[: p.T] / Y[: p.T], p, "TPI"
)
r_p_new = aggr.get_r_p(
rnew[: p.T],
r_gov_new[: p.T],
Expand Down
2 changes: 1 addition & 1 deletion ogcore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
from ogcore.txfunc import *
from ogcore.utils import *

__version__ = "0.15.1"
__version__ = "0.15.2"
36 changes: 36 additions & 0 deletions ogcore/default_parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,42 @@
}
}
},
"r_gov_DY": {
"title": "Linear effect of debt to GDP ratio on government interest rate",
"section_1": "Fiscal Policy Parameters",
"description": "Parameter summarizing the linear effect of the debt to GDP ratio on the government interest rate.",
"notes": "",
"type": "float",
"value": [
{
"value": 0.0
}
],
"validators": {
"range": {
"min": -0.3,
"max": 0.3
}
}
},
"r_gov_DY2": {
"title": "Quadratic effect of debt to GDP ratio on government interest rate",
"section_1": "Fiscal Policy Parameters",
"description": "Parameter summarizing the quadratic effect of the debt to GDP ratio on the government interest rate.",
"notes": "",
"type": "float",
"value": [
{
"value": 0.0
}
],
"validators": {
"range": {
"min": -0.3,
"max": 0.3
}
}
},
"cit_rate": {
"title": "Corporate income tax rate",
"description": "Corporate income tax rate. Set value for base year, click '+' to add value for next year. All future years not specified are set to last value entered.",
Expand Down
33 changes: 27 additions & 6 deletions ogcore/fiscal.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""


def D_G_path(r_gov, dg_fixed_values, p):
def D_G_path(r, dg_fixed_values, p):
r"""
Calculate the time paths of debt and government spending

Expand Down Expand Up @@ -87,11 +87,14 @@ def D_G_path(r_gov, dg_fixed_values, p):
G = p.alpha_G[: p.T] * Y[: p.T]
D_f = np.zeros(p.T)
D_d = np.zeros(p.T)
r_gov = get_r_gov(r[: p.T], np.zeros(p.T), p, method="TPI")
new_borrowing = np.zeros(p.T)
debt_service = np.zeros(p.T)
new_borrowing_f = np.zeros(p.T)
else:
t = 1
r_gov = np.zeros_like(r)
r_gov[0] = get_r_gov(r[0], D[0] / Y[0], p, method="scalar", t=0)
while t < p.T - 1:
D[t] = (1 / growth[t]) * (
(1 + r_gov[t - 1]) * D[t - 1]
Expand All @@ -102,6 +105,7 @@ def D_G_path(r_gov, dg_fixed_values, p):
+ agg_pension_outlays[t - 1]
- total_tax_revenue[t - 1]
)
r_gov[t] = get_r_gov(r[t], D[t] / Y[t], p, method="scalar", t=t)
if (t >= p.tG1) and (t < p.tG2):
G[t] = (
growth[t + 1]
Expand Down Expand Up @@ -137,6 +141,7 @@ def D_G_path(r_gov, dg_fixed_values, p):
+ agg_pension_outlays[t - 1]
- total_tax_revenue[t - 1]
)
r_gov[t] = get_r_gov(r[t], D[t] / Y[t], p, method="scalar", t=t)
G[t] = (
growth[t] * (p.debt_ratio_ss * Y[t])
- (1 + r_gov[t]) * D[t]
Expand Down Expand Up @@ -182,6 +187,7 @@ def D_G_path(r_gov, dg_fixed_values, p):
G,
D_d,
D_f[: p.T],
r_gov[: p.T],
new_borrowing,
debt_service,
new_borrowing_f,
Expand Down Expand Up @@ -350,27 +356,42 @@ def get_TR(
return new_TR


def get_r_gov(r, p, method):
def get_r_gov(r, DY_ratio, p, method, t=0):
r"""
Determine the interest rate on government debt

.. math::
r_{gov,t} = \max\{(1-\tau_{d,t}r_{t} - \mu_d, 0.0\}
r_{gov,t} = \max\{(1-\tau_{d,t}r_{t} - \mu_d + \beta_1 \frac{D_t}{Y_t} + \beta_2 \left(\frac{D_t}{Y_t}\right)^2, 0.0\}

Args:
r (array_like): interest rate on private capital debt over the
time path or in the steady state
DY_ratio (array_like): ratio of government debt to GDP
p (OG-Core Specifications object): model parameters
method (str): either 'scalar' for one period or 'TPI' for transition path
t (int): time period index, used only if method is 'scalar'

Returns:
r_gov (array_like): interest rate on government debt over the
time path or in the steady-state

"""
if method == "SS":
r_gov = np.maximum(p.r_gov_scale[-1] * r - p.r_gov_shift[-1], 0.00)
if method == "scalar":
r_gov = np.maximum(
p.r_gov_scale[t] * r
- p.r_gov_shift[t]
+ p.r_gov_DY * DY_ratio
+ p.r_gov_DY2 * DY_ratio**2,
0.00,
)
else:
r_gov = np.maximum(p.r_gov_scale * r - p.r_gov_shift, 0.00)
r_gov = np.maximum(
p.r_gov_scale[: p.T] * r[: p.T]
- p.r_gov_shift[: p.T]
+ p.r_gov_DY * DY_ratio[: p.T]
+ p.r_gov_DY2 * DY_ratio[: p.T] ** 2,
0.00,
)

return r_gov

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="ogcore",
version="0.15.1",
version="0.15.2",
author="Jason DeBacker and Richard W. Evans",
license="CC0 1.0 Universal (CC0 1.0) Public Domain Dedication",
description="A general equilibrium overlapping generations model for fiscal policy analysis",
Expand Down
Loading
Loading