Skip to main content

glidepath

CI Quality Gate Coverage Python 3.14 uv Ruff Checked with mypy License: MIT + CC BY-NC-SA 4.0 data

williajm.github.io/glidepath

A desktop retirement and investment planner. UK-first, built so other regions can be added later. Every number in a plan is a fact you stated, a decision you made, or an assumption the app defaulted — always inspectable, never silently guessed. All data stays local; nothing is transmitted.

The charts tab: the Monte Carlo fan chart — nested percentile bands deepening toward the median line — beside the success-rate readout and the retirement-age and backtest cards

(All screenshots show example data, not anyone's real finances.)

What it models today (single person, UK):

  • Wrappers — workplace DC, SIPP, S&S ISA, LISA, GIA and cash, with UK contribution relief mechanics and dividend/savings taxation.
  • Defined benefit pensions — deferred entitlements or active CARE-style accrual, with revaluation, early/late factors and commutation; state pension from your official DWP forecast, including deferral.
  • Tax — rUK and Scottish income tax from verified 2026/27 data files; pension allowances (AA/taper/MPAA, lump-sum allowance).
  • Projection — deterministic or Monte Carlo runs from the app: success rate, probability of ruin, ending-pot percentiles, and a probability fan chart on its own tab, reproducible from a seed. With a de-risking glide path, tax-aware decumulation with optional go-go/slow-go/no-go retirement spending multipliers, and annuity purchases entered in the facts form. (The engine also models alternative withdrawal strategies — fixed %, guardrails, natural yield — and tax-free-cash strategies; the app currently runs the fixed-real defaults, with no strategy picker in the UI yet.)
  • "When can I retire?" — a solver for the earliest retirement age that sustains a target income (a replacement rate you choose, 66% of employment income by default), met deterministically or at a Monte Carlo success target.
  • Historical backtesting — replays the plan over every rolling window of world market history since 1900 (global equities in sterling terms, UK gilts and cash, deflated by UK inflation): the share of historical starting years the plan survives, the worst starting year, and the range of outcomes as chart bands — sequence-of-returns risk that independent Monte Carlo draws miss.
  • Scenarios — named what-ifs over your decisions and assumptions, with a side-by-side comparison; plans saved as a local JSON file.

More screenshots

Facts entry — everything on this screen is either a fact you state or a choice you make; anything estimated lives in the assumptions inspector instead:

The facts tab: the About you, Household spending, and State pension cards of the entry form, with the example plan's values filled in

Stated vs assumed — the provenance view: the facts you stated, the choices in effect, and every assumption the run used with its value, default/overridden status, source, and date:

The stated-vs-assumed tab: tables of stated facts, choices in effect, assumptions used with sources, and the plan structure

Disclaimer

Glidepath is a personal modelling tool for exploring retirement scenarios. It is not financial advice and is not regulated; its outputs depend on assumptions that will not match reality. Do not make financial decisions based solely on this tool.

Run

Requires only uv. Install the latest release from PyPI and launch it:

uv tool install glidepath
glidepath

(pipx install glidepath works too. Glidepath is a desktop app distributed through PyPI, not a library — importing glidepath modules is not a supported API.)

Or run straight from a checkout:

git clone https://github.com/williajm/glidepath.git
cd glidepath
uv run glidepath

The first run from a checkout creates a virtual environment and installs the locked dependencies automatically, then launches the desktop app. Accept the disclaimer and a fresh install opens with an example plan already projected, so every tab has something to show — replace its values with your own facts, or clear the form and start blank. Charts label each bar with the tax year and your age and switch between today's money and nominal; Help → "How to use glidepath" walks through every tab. Save your plan from the File menu as a .glidepath.json file you own, stored wherever you choose; the next launch reopens your last plan automatically.

Developing

Development additionally requires GNU Make, which drives every workflow command:

make sync          # create the platform venv from the lockfile (fails if the lock has drifted)
make hooks         # install the pre-commit hooks (required before committing)

One-time per machine: set UV_PROJECT_ENVIRONMENT user-wide (.venv-win on Windows, .venv-wsl in WSL) so bare uv commands and the git hooks use the same venv as make. See CLAUDE.md. (Skipping this only matters for a shared Windows/WSL checkout — for trying the app, uv's default .venv is fine.)

Everyday commands

make check   # all merge gates: ruff, format, mypy --strict, pytest (>=96% cov), dep age
make fix     # auto-fix lint issues and reformat
make test    # tests with coverage
make deps    # the ONLY way to add/upgrade dependencies (7-day cooldown lock)
make audit   # pip-audit the lockfile for known CVEs

Dependencies are never added with plain uv add/uv lock: run make deps so the 7-day supply-chain cooldown is applied. CI runs every make check gate plus make audit and the SonarCloud quality gate on each PR — so a clean make check locally does not quite guarantee a green pipeline. See CLAUDE.md for the full policies.

Releases

Releases are vX.Y.Z tags on main. Each one is published to PyPI as an sdist and wheel via trusted publishing with PEP 740 attestations, and as a GitHub Release carrying its notes from CHANGELOG.md with the same artifacts attached. There are no packaged binary builds (installer/exe) yet — install from PyPI as above.

Data licences

The code is MIT-licensed (see LICENSE). One data file is not: the historical return series (src/glidepath/regions/uk/data/returns_history.toml) is derived from the JST Macrohistory Database (Jordà, Schularick & Taylor; return series per Jordà, Knoll, Kuvshinov, Schularick & Taylor 2019) and is distributed under CC BY-NC-SA 4.0 — attribution required, non-commercial use only, share-alike. The package metadata declares MIT AND CC-BY-NC-SA-4.0 accordingly; LICENSE-DATA and the file's own header carry the full notice, and scripts/build_returns_history.py regenerates the file from the upstream dataset.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

glidepath-0.3.0.tar.gz (496.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

glidepath-0.3.0-py3-none-any.whl (544.7 kB view details)

Uploaded Python 3

File details

Details for the file glidepath-0.3.0.tar.gz.

File metadata

  • Download URL: glidepath-0.3.0.tar.gz
  • Upload date:
  • Size: 496.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for glidepath-0.3.0.tar.gz
Algorithm Hash digest
SHA256 03b440ee310c12a3ee414145dbd73401528ad35ba120bc00f77af262da15d7e4
MD5 f0a89ceadc9e02096c80849c55c6b16a
BLAKE2b-256 faa6e466b229dfba80c0d29409048453fda74ec2c50d4f981353212948ac30d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for glidepath-0.3.0.tar.gz:

Publisher: release.yml on williajm/glidepath

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file glidepath-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: glidepath-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 544.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for glidepath-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 226cad59b6a3e71854eeac02f117349618856565a26ff9f844fa8fcce0cae5db
MD5 5d885814c8ae562af4e7fa948d5d243a
BLAKE2b-256 e28be5e4f8313f498e13f237e666dda549f3d44f0391b332912a49167b6cebe4

See more details on using hashes here.

Provenance

The following attestation bundles were made for glidepath-0.3.0-py3-none-any.whl:

Publisher: release.yml on williajm/glidepath

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page