8.6 KiB
projections.srf reference
projections.srf configures zfin projections:
the Monte-Carlo-style retirement simulation run over the Shiller
dataset (1871-present). zfin loads it from the same directory as the
portfolio. It is optional -- without it, the command runs with
sensible defaults (20/30/45-year horizons, 90/95/99% confidence,
no accumulation phase).
This page is the field reference. For how the simulation actually works see The retirement projection model; for a guided setup see Plan for retirement.
Record types
Every line starts with a type:: discriminator:
type:: |
Purpose |
|---|---|
config |
A single configuration field (allocation, horizon, retirement target, contributions, spending). |
birthdate |
A household member's birthdate (drives ages, horizon_age, retirement_age, life-event timing). |
event |
A life event: recurring income or expense (Social Security, pension, tuition, healthcare). |
#!srfv1
type::config,target_stock_pct:num:80
type::config,horizon:num:25
type::config,horizon_age:num:95
type::birthdate,date::1981-04-12
type::event,name::Social Security,start_age:num:70,amount:num:38400
config fields
| Field | Type | Description |
|---|---|---|
target_stock_pct |
num | Asset-allocation target (0-100). Sets the simulation's stock/bond blend. |
horizon |
num | Distribution-phase length in years. Repeat the line for multiple horizons. |
horizon_age |
num | Horizon expressed as an age; resolves to target_age - oldest_current_age. Repeatable. |
retirement_age |
num | Age the oldest configured person must reach to retire. |
retirement_at |
date | Absolute retirement date (YYYY-MM-DD). Wins over retirement_age if both set. |
annual_contribution |
num | Yearly accumulation-phase contribution, in today's dollars. |
contribution_inflation_adjusted |
bool | If true (default), contributions grow with CPI year over year. |
target_spending |
num | Desired retirement spending, in today's dollars. |
target_spending_inflation_adjusted |
bool | If true (default), target spending grows with CPI during distribution. |
retirement_target |
num | Annotation on a horizon/horizon_age line that overrides the earliest-retirement promotion rule. Allowed: 90, 95, 99. |
birthdate fields
| Field | Type | Description |
|---|---|---|
date |
date | Birthdate (YYYY-MM-DD). |
person |
num | Household member (1 default, 2 for a partner). |
type::birthdate,date::1981-04-12
type::birthdate,date::1983-09-08,person:num:2
event fields
Life events modify annual cash flow in both phases. Positive amounts are income (offset withdrawals); negative amounts are expenses (added to withdrawals).
| Field | Type | Description |
|---|---|---|
name |
string | Label shown in the Life Events table. |
amount |
num | Annual amount. Positive = income, negative = expense. |
start_age |
num | Age (of person) at which the event begins. |
duration |
num | Optional length in years. Omit for a permanent event. |
person |
num | Whose age start_age refers to (1 default, 2 for a partner). |
inflation_adjusted |
bool | If true (default), the amount grows with CPI. Set false for a fixed nominal amount. |
# Permanent income starting at age 70
type::event,name::Social Security,start_age:num:70,amount:num:38400
# 4-year expense starting at age 50
type::event,name::College Tuition,start_age:num:50,duration:num:4,amount:num:-55000
# A partner's pension
type::event,name::Pension,start_age:num:65,person:num:2,amount:num:24000
The two retirement-planning inputs
projections.srf answers a different question depending on which
inputs you set. This is the single most important thing to understand
about the file:
| You set... | zfin answers... | Display |
|---|---|---|
A target date (retirement_age / retirement_at) |
"Given my date, what can I spend?" | Accumulation-phase block with a dated headline. |
A target spending (target_spending) |
"Given my spending, when can I retire?" | Earliest-retirement grid; one cell is promoted to the headline. |
| Both | Both, back to back | Configured date wins the headline; grid renders below for comparison. |
| Neither | Already-retired view | "Years until possible retirement: none". |
When target_spending is set, the earliest-retirement grid shows,
for each (horizon x confidence) pair, the earliest year that sustains
the spending. The default promotion rule picks the headline cell by
walking horizons longest-to-shortest at 99% confidence, preferring the
longest horizon that keeps the oldest person under age 100. Override it
with a retirement_target annotation on one horizon line:
# use the 35yr x 95% cell as the headline
type::config,horizon:num:35,retirement_target:num:95
At most one horizon may carry the annotation; configuring more than one drops them all and falls back to the default rule. If the promoted cell is infeasible (no accumulation length <= 50 years sustains the spending), the headline reads "not feasible" and the grid still renders so you can pick a workable anchor.
The example configurations
The five bundled examples are fully-configured walkthroughs of each combination:
examples/... |
Inputs |
|---|---|
pre-retirement-age |
target date only |
pre-retirement-spending |
target spending only |
pre-retirement-spending-target |
target spending + an explicit (infeasible) anchor |
pre-retirement-both |
target date + target spending |
post-retirement |
neither (distribution-only) |
ZFIN_HOME=examples/pre-retirement-both zfin projections
See also
- Plan for retirement -- guided setup.
- The retirement projection model -- how the simulation works.
zfin projections-- command flags (--as-of,--overlay-actuals,--convergence,--return-backtest).