Skip to content

Sovereign interest rate is clipped at zero, so a negative real rate cannot be modelled #1202

Description

@marcelolafleur

get_r_gov clips the sovereign interest rate at zero:

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,
)

There is no way to switch it off, so a country whose government genuinely pays a negative real rate cannot be represented.

Japan is that country. General government net interest is about 0.43% of GDP on net debt of 114.8%, roughly 0.375% nominal, which against realised inflation is −0.6% real. Calibrating the wedge to that works — it returns −0.6023% — and the floor then discards it and reports 0.0000.

Why it matters. The debt-stabilising primary balance is pb* = (r_gov − g)/(1 + g) · D/Y. Clipping the rate from −0.60% to 0.00% raises the primary balance the country must run by 0.68 percentage points of GDP. For Japan that is the difference between a model whose fiscal stance matches the actual accounts and one that demands a primary surplus Japan has never run. On the transition path the clipped version has debt rising where Japan's is falling; with the true rate it tracks the published projection to within half a percentage point over three years.

Negative values are safe. r_gov enters the model linearly everywhere — no division by it, no powers, no logs. It has two consumers:

debt_service = r_gov * D                        # fiscal.get_D_ss / get_D_t
r_p = (r_gov*D + r_K*K) / (D + K)               # aggregates.get_r_p

Both are linear and the r_p denominator is strictly positive. A negative r_gov simply means the government is a net receiver on its debt position, and the household portfolio return blends a negative debt leg with a positive capital leg. I have been running Japan this way against v0.19.0 with a local patch: the steady state solves, the transition converges, and the resource constraint holds in 318 of 320 periods.

Suggested fix. Make the floor a parameter rather than a constant — r_gov_floor, default 0.0. Existing calibrations are unaffected, since np.maximum(x, 0.0) is exactly what happens today, and a country with a negative sovereign rate can lower it. Happy to open a PR.

cc @jdebacker @rickecon

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions