Skip to content

Spending guardrails

FinZot’s amortized budget already lowers spending when the portfolio falls, without a rule. This recipe is for a rule you want to state explicitly, such as “cut discretionary spending while the trailing five-year real return is under 4%”.

  1. Mark what can be cut. Every expense you would give up in a bad year is a flexible expense with a floor, and everything else is mandatory. A floor of 0% means the expense can be eliminated. Lower priorities are cut first (expenses and healthcare).
  2. Write the condition as a named formula. real_portfolio_return is the year’s return after inflation, and ROLLING_AVG over it counts only the years that have happened, so the rule is correct from the first plan year (formula language, planner variables):
    OR(ROLLING_AVG(real_portfolio_return, 5) < 4%, real_portfolio_return < -20%)
  3. Write the budget as a second named formula that reads the condition. Ceiling and floor are the totals you would spend in a good and a bad year, in today’s dollars:
    IF(cut_rule, FUTURE_DOLLARS(60_000), FUTURE_DOLLARS(100_000))
  4. Attach the budget to a spending policy. Create a policy covering the years the rule should govern, choose the Custom formula strategy, and size it from the budget formula (variable spending). Mandatory expenses always fund in full, flexible expenses compress toward their floors in priority order, and any budget left over is spent as discretionary.

In a year the rule fires, the budget drops to the floor and the flexible expenses absorb the cut. In every other year the plan spends the ceiling.

  • Drawdown from a peak. Cut while the portfolio is more than 20% below its high:
    invested_assets / ROLLING_MAX(invested_assets, 100) - 1 < -20%
    The starting balance counts as a prior high, and a large window is an all-time high. Deposits and withdrawals move this ratio, which is why the return-based rule above exists.
  • Withdrawal rate. Cut while last year’s spending was more than 6% of the portfolio:
    LAG(consumption, 1) * (1 + LAG(inflation_rate, 1)) / invested_assets > 6%
    consumption is what was spent, not the budget that was set, so this drifts from the textbook rule once floors bind. Last year’s inflation is what carries last year’s spending into this year’s dollars, because spending is indexed at the start of each year; inflation_rate alone would add this year’s instead.
  • Graded cuts. Replace the IF with a CASE that steps the budget down as the trailing return worsens.
  • Do not approximate the real return as portfolio_return - inflation_rate. The error is small in ordinary years and largest in a crash, in the direction that hides the damage, and it can delay the cut by a year.
  • Do not hand-roll a trailing average out of LAG. A lag before the plan started reads 0, so (x + LAG(x, 1) + LAG(x, 2) + LAG(x, 3) + LAG(x, 4)) / 5 divides one year by five in the first plan year and reads a fifth of the true return. A “below 4%” rule written that way stays on for four years. ROLLING_AVG(x, 5) divides by the years it actually saw.
StrategyWhere it lands
4% rule (initial percentage, inflation adjusted)A spending policy sized as a fixed amount in today’s dollars, set to 4% of the starting portfolio.
VPW, variable percentage withdrawalThe amortized budget. It is the same arithmetic with taxes built in.
Guyton-KlingerThe withdrawal-rate variation above, driving a budget that starts from last year’s spending. A formula cannot read its own prior output, so the “last year’s withdrawal” it adjusts is LAG(consumption, 1), which excludes taxes and includes debt interest.
Drawdown guardrailThe drawdown variation above.

A rule cannot read the budget it set last year. Time-series functions cannot look back at a named formula, so a ratchet that compounds off its own prior decision has to be approximated through consumption, as the Guyton-Klinger row does.