Skip to content

Command-line personal-finance forecasting

A personal-finance simulator that writes a double-entry ledger.

Describe a financial plan in a small YAML file. Hforecast simulates it period by period — inflation, growth, loan amortization, real estate, and taxes — and writes a standard hledger journal you query with ordinary hledger commands.

Written in Haskell Outputs an hledger journal MIT licensed
plan.yaml yaml
age: 30
endOfPlanAge: 85

taxes:
  effectiveRate: 0.25

accounts:
  - name: assets:bank:savings
    type: savings
    balance: $50000
  - name: assets:brokerage
    type: brokerage
    balances:
      - 200000 EQUITY

income:
  - type: salary
    period: annual
    amount: 120000
    toAge: 65

expenses:
  - description: Living
    type: general
    period: monthly
    account: expenses:living
    amount: 4500
shell bash
hforecast -c plan.yaml -o forecast.journal
hledger -f forecast.journal bal assets liabilities -Y --depth 2
Net worth Age 30 57 85 Net worth Annual cash flow
Illustrative. Hforecast writes a journal; render charts from it with your own tooling (a spreadsheet, a plotting library, or hledger’s CSV export).

How it works

1 · Describe a plan

Write your accounts, income, expenses, investments, and one-off events in a YAML file. Amounts are in today’s dollars.

2 · Simulate

Hforecast steps through time period by period, applying inflation, growth, amortization, and taxes, and streams out a journal.

3 · Analyze

The output is an ordinary hledger journal. Query net worth, cash flow, holdings, and tax burden with commands you already know.

Double-entry accounting

Every flow is a balanced transaction.

The output is a real hledger journal: opening balances, paychecks, expenses, interest and dividends, and price directives that mark your holdings to market at each period’s close. There is nothing bespoke to learn on the analysis side — if you know hledger, you can query it.

forecast.journal ledger
2026-07-07 Opening Balances
              $50000.00
              EQUITY200000
    

2026-07-07 Expense: Living expenses
            $-5000.00
            $5000.00

2026-07-07 Growth: assets:bank:savings
                $-166.67
             $166.67

P 2026-08-07 EQUITY $1.01

Any horizon, any resolution

Forecast one year or fifty, day by day or year by year.

The plan runs from your age — or your birthday — to endOfPlanAge, so the horizon is a single year or five decades. Choose the step length with -g; every amount is written in today’s dollars and inflation-adjusted to the date it takes effect.

shell bash
# age → endOfPlanAge sets the horizon
#   age: 30
#   endOfPlanAge: 85   → a 55-year plan

# -g chooses the step length
hforecast -c plan.yaml -g annual   # one step per year
hforecast -c plan.yaml -g month    # month by month (default)
hforecast -c plan.yaml -g day      # daily precision

Retirement, a home, a big purchase

Model the decisions that move your net worth.

Salary and Social Security; 401(k) and HSA with employer match and required minimum distributions; a taxable brokerage; and real estate. A mortgage amortizes each period — buying a home is a single action that creates the asset, links the loan, and schedules its carrying costs.

plan.yaml yaml
actions:
  - action: buy-property
    date: 2033-06-01
    account: assets:real-estate:apartment
    description: Apartment
    purchasePrice: 400000
    downPaymentRate: 0.20
    closingCostsRate: 0.03
    liabilityAccount: liabilities:mortgage:apartment
    interestRate: 0.065
    loanTerm: 30
    growthRate: 0.03

Any currency

Set your currency and per-currency rates.

Pick the default commodity for bare amounts, and give each currency its own interest and inflation assumptions. Holdings carry their commodity and are marked to market with price directives. Plans are single-currency — there is no cross-currency conversion.

plan.yaml yaml
globals:
  currency: $          # default commodity for bare amounts
  inflationRate: 0.025

currencies:
  USD:
    interestRate: 0.04
  EUR:
    interestRate: 0.03

Scenarios

Change an assumption; see the effect on net worth and cash flow.

A config is a scenario. Run several and compare the journals with ordinary hledger — net worth by year, income against expenses, tax burden over time. Retire two years earlier, buy the apartment or keep renting, and diff the results.

shell bash
hforecast -c baseline.yaml     -o baseline.journal
hforecast -c retire-early.yaml -o retire-early.journal

# Net worth by year
hledger -f retire-early.journal bal assets liabilities -Y --depth 2

# Cash flow: income vs. expenses by year
hledger -f retire-early.journal is -Y

Install

Build it with Stack.

Querying the output uses the hledger CLI. Prebuilt binaries and a Homebrew formula are planned.

shell bash
stack install        # build and install the hforecast binary
make install-taxes   # optional: install bundled tax bracket data