Port-with-Shocks Model¶
A modular lifecycle model with portfolio choice and correlated shocks.
This example demonstrates how dolo-plus stages compose into different period configurations, showing the power of modular stage-based specification.
Model Overview¶
| Feature | Description |
|---|---|
| Stages | 3 reusable stages (noport, port, cons) |
| Periods | 3 configurations from same stage library |
| Shocks | Log-normal income and return shocks |
| Solution | EGM for consumption, grid search for portfolio |
Core Idea¶
The port-with-shocks model separates three concerns:
- Shock realization (
noport_stage): Transforms assets to cash-on-hand via income shock - Portfolio allocation (
port_stage): Allocates wealth before shocks resolve - Consumption choice (
cons_stage): Optimizes consumption given cash-on-hand
By combining these stages differently, we get distinct economic models from the same building blocks.
Stages¶
| Stage | Type | Decision | Prestate → Poststate |
|---|---|---|---|
noport_stage |
Shock realization | None | k → m via m = k*R + θ |
port_stage |
Portfolio | ς (continuous) |
k → m via m = k*(ς*Ψ + (1-ς)*R) + θ |
cons_stage |
Consumption | c (continuous) |
m → a via a = m - c |
noport_stage (Shock Realization)¶
No decision—just shock realization:
| Symbol | Role |
|---|---|
k |
Investable assets (prestate) |
θ |
Transitory income shock |
m |
Cash-on-hand (poststate) |
port_stage (Portfolio Choice)¶
Portfolio decision before joint shocks:
| Symbol | Role |
|---|---|
k |
Investable assets (prestate) |
ς |
Risky share (control) |
Ψ, θ |
Return and income shocks |
m |
Cash-on-hand (poststate) |
cons_stage (Consumption)¶
Deterministic consumption (EGM-compatible):
| Symbol | Role |
|---|---|
m |
Cash-on-hand (prestate) |
c |
Consumption (control) |
a |
End-of-period assets (poststate) |
Period Configurations¶
The library defines three period YAML files, each composing stages in a different order.
Period 1: cons_period (noport → cons)¶
File: cons_period.yaml
Flow: k ──[θ shock]──▶ m ──[choose c]──▶ a
- No portfolio decision; income shock is realized via
noport_stage noport_stageoutputsm,cons_stageexpectsm— implicit identity connector (no connector needed)- Between-period link:
k_{t+1} = a_t(rename at nest/assembly level)
This is the simplest consumption-savings model with exogenous income risk.
Period 2: port_cons_period (port → cons)¶
File: port_cons_period.yaml
Flow: k ──[choose ς, then Ψ,θ shocks]──▶ m ──[choose c]──▶ a
- Portfolio allocation is made first, then joint return and income shocks are realized
port_stageoutputsm,cons_stageexpectsm— implicit identity connector- Between-period link:
k_{t+1} = a_t
This is the standard lifecycle portfolio-consumption model (e.g. Cocco, Gomes, Maenhout 2005).
Period 3: cons_port_period (cons → port)¶
File: cons_port_period.yaml
name: cons_port_period
stages:
- cons_stage
- port_stage
connectors:
- from: cons_stage
to: port_stage
rename: {a: k}
Flow: m ──[choose c]──▶ a = k ──[choose ς, then Ψ,θ shocks]──▶ m'
- Consumption is chosen first, then remaining assets are allocated across portfolio
cons_stageoutputsabutport_stageexpectsk— explicit rename connector{a: k}is required- Between-period link:
m_{t+1} = m'_t(identity, since port outputsmand cons expectsm)
This reversal illustrates the key composition feature: the same stages produce a different economic model simply by changing the order and adding a connector.
Connectors and Twisters¶
The three period files show how modular stage composition works in practice:
| Period | Stages | Connector | Between-period rename |
|---|---|---|---|
cons_period |
noport → cons | identity (omitted) | a → k |
port_cons_period |
port → cons | identity (omitted) | a → k |
cons_port_period |
cons → port | {a: k} (explicit) |
m → m (identity) |
Key observation: When stage output names match the next stage's input (m → m), the connector is identity and is omitted. When they differ (a → k), an explicit connector provides the rename. This is the twister condition from the DDSL foundations.
Nest Construction¶
A nest composes periods across time with twisters (inter-period adapters). For example, an infinite-horizon cons_period nest:
periods:
- cons_period # noport → cons, outputs a
twisters:
- rename: {a: k} # between-period: a_t → k_{t+1}
For cons_port_period, the twister would be identity since the period already outputs m and expects m at arrival.
Stage Composition Diagram¶
┌─────────────────────────────────────────┐
│ STAGE LIBRARY │
├─────────────┬─────────────┬─────────────┤
│ noport │ port │ cons │
│ k ──▶ m │ k ──▶ m │ m ──▶ a │
│ (θ) │ (ς,Ψ,θ) │ (c) │
└──────┬──────┴──────┬──────┴──────┬──────┘
│ │ │
┌──────────────┼─────────────┼─────────────┼──────────────┐
▼ ▼ ▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐
│ cons_period │ │port_cons_ │ │ cons_port_period │
│ │ │ period │ │ │
│ noport─cons │ │ port─cons │ │ cons ─{a→k}─ port │
│ k───▶a │ │ k───▶a │ │ m───▶m' │
└─────────────┘ └─────────────┘ └─────────────────────────┘
Key Concepts Illustrated¶
Post-Decision Shock Timing¶
In port_stage, the portfolio decision ς is made before shocks (Ψ, θ) resolve. This is expressed by:
- Shocks in
exogenousblock (not inarvl_to_dcsn_transition) - Bellman:
V = max_{ς}(E_{Ψ,θ}(V[>]))
EGM Compatibility¶
The cons_stage is designed for EGM solution:
- Contains
InvEulerequation:c[>] = (β*dV[>])^(-1/ρ) - Contains reverse transition:
m_d[>] = a + c[>] - No shocks within the stage (expectation handled by preceding stage)
Files¶
port-with-shocks/
├── README.md
└── library/
├── noport_stage.yaml # Shock realization stage
├── noport_stage_methods.yml # noport methodization
├── port_stage.yaml # Portfolio stage
├── cons_stage.yaml # Consumption stage
├── cons_stage_methods.yml # cons methodization
├── cons_period.yaml # noport → cons
├── port_cons_period.yaml # port → cons
├── cons_port_period.yaml # cons → port
├── calibration.yaml # Parameter values
├── settings.yaml # Grid configuration
└── methodization.yml # Global methodization
Related Documentation¶
- Stage Details: noport_stage | port_stage | cons_stage
- Theory: Modular Examples