Occasionally-binding constraints by regime switching

The principle

Recast each constrained equation as a two-regime Markov-switching one: a “binding” regime in which the constraint holds with equality and a “slack” regime in which the unconstrained equation holds, with the switch governed by endogenous transition probabilities (so the regime is more likely to flip to “binding” precisely when the constraint is about to be violated). Concretely, a complementarity condition

\[\lambda _{i}\,C_{i}=0\]

(the multiplier \(\lambda_i\) is zero when the constraint \(C_i\ge 0\) is slack; \(C_i=0\) when it binds) is replaced by

\[\alpha _{i}\,\lambda _{i}+\left( 1-\alpha _{i}\right) C_{i}=0,\]

where the regime indicator \(\alpha_i\in\{0,1\}\) is 1 in the binding regime and 0 in the slack regime. Under perfect foresight \(\alpha_i\) can simply be the endogenous indicator \(1_{\{C_i=0\}}\); in a stochastic environment it follows a Markov process with endogenous probabilities.

Note

When \(\alpha_i = 0\) the equation above pins down \(C_i\) but not \(\lambda_i\) – so if \(\lambda_i\) appears nowhere else the system is structurally singular. RISE breaks the singularity by imposing an arbitrary value for \(\lambda_i\) in the slack regime.

Declaring it

For a non-optimal-policy model, write the model directly as a switching system: declare a Markov chain on the constrained equation’s switching parameter and let one regime carry the unconstrained equation and the other the binding form. For a ZLB on the policy rate, that looks like

@parameters(zlb,2,"Normal","Bound") gam
@parameters zlb_tp_1_2, zlb_tp_2_1

log(1+R) = gam*log( Taylor_rule_expression );

so gam_zlb_1=1 (Normal) recovers the Taylor rule and gam_zlb_2=0 (Bound) pins log(1+R)=0. The model equations alone do not enforce the constraint – they only state that there is a regime in which the rate is pegged. The simulator needs to be told which paths are admissible.

For an optimal-policy model with a planner objective, the constraint is declared inside the @optimization_problem block via @constraint – e.g. @constraint = gam:R>=1 – where gam is the switching parameter that is 1 when the constraint binds. The planner internalises the constraint and the same Lagrange-multiplier reformulation is applied to the planner’s complementarity conditions; see Optimal (Ramsey) policy.

Tip

Always ensure there is a feasible path by keeping the binding probabilities away from the extremes, e.g.

\[p_{ij}=p_{\min }+p_{ij}^{orig}\left( p_{\max }-p_{\min }\right)\]

Once built, solve / simulate / irf / forecast / filter run the regime-switching solution; use generalized impulse responses (the dynamics depend on the regime).

Enforcing the constraint at simulation

For non-optimal-policy switching systems, two enforcement mechanisms are available at simulate / forecast time. Pick one – they cannot be combined.

1. Formal constraints via simul_constraints. Pass inequality plus recovery pairs to set:

mc = set(m,'simul_constraints',{'log(1+R) >= 0','R = 0'});

The first column states the inequality; the second describes how the constrained variable is pinned in the binding regime. On a switching model RISE auto-compiles the constraints into a switch rule, so the simulator picks the admissible regime each period. Combine with a simplan and simul_shock_uncertainty=false for a designed deterministic scenario, or draw shocks for a stochastic run.

2. A user-supplied switch rule via simul_regime. Pass a callback that returns, for each candidate regime, whether that regime is admissible:

R_idx = locate_variables({'R'},get(m,'endo_list'));
rule  = @(y,past_regimes,past_forecasts) [y(R_idx,1) >= 0; true];
ms_r  = set(m,'simul_regime',rule);

The calling convention is ok = rule(y, past_regimes, past_forecasts, varargin) where y is n_endo x n_regimes (one forecast per regime), and ok is a logical column vector of length n_regimes. To carry extra arguments use a cell {handle, extra1, extra2, ...}. RISE zeroes the probability of any regime with ok=false and resamples from the renormalized distribution. Switch-rule simulations require simul_burn=0.

Worked example

See models/dsge/obc/worked_examples/regime_switching_zlb/ in rise-stable-tests – two sibling drivers on a shared switching NK model: howto_zlb_exogenous.m (free Markov-chain draws + a forced-regime-path scenario + IRFs) and howto_zlb_endogenous.m (both enforcement mechanisms above + GIRF). The accompanying README documents the linearisation caveat: at first order the bound regime’s policy equation linearises around the regime-1 steady state, so the realized R in the bound regime hovers near its steady value rather than collapsing to zero in level. For an exact R=0-in-level demonstration, the anticipated-shocks route is the better choice (see Occasionally-binding constraints by anticipated shocks).

Under optimal policy

When the model also has a planner objective, the planner internalises the constraint: the same \(\alpha _{i}\lambda _{i}+\left(1-\alpha_i\right)C_i=0\) reformulation is applied to the planner’s complementarity conditions, so the constrained Ramsey/discretionary policy is solved directly (see Optimal (Ramsey) policy).

Estimation

The regime-switching route provides a likelihood, so a model with regime-switching OBCs can be estimated like any Markov-switching model – give the transition-probability parameters priors (through prior.nonvar) and call estimate.