{"id":25238685,"url":"https://github.com/mdlacasse/owl","last_synced_at":"2025-10-26T14:30:38.591Z","repository":{"id":240480846,"uuid":"802704479","full_name":"mdlacasse/Owl","owner":"mdlacasse","description":"Retirement planner with great wisdom","archived":false,"fork":false,"pushed_at":"2024-10-29T23:00:18.000Z","size":5476,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-30T00:48:21.387Z","etag":null,"topics":["jupyter-notebook","linear-programming","optimization","python","retirement","retirement-calculator","retirement-planner","retirement-planning","roth-ira"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mdlacasse.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-19T03:12:37.000Z","updated_at":"2024-10-29T23:00:00.000Z","dependencies_parsed_at":"2024-05-19T07:38:39.770Z","dependency_job_id":"a9ba56cd-fe73-437b-9c86-82910a720bf3","html_url":"https://github.com/mdlacasse/Owl","commit_stats":null,"previous_names":["mdlacasse/owl"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdlacasse%2FOwl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdlacasse%2FOwl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdlacasse%2FOwl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdlacasse%2FOwl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mdlacasse","download_url":"https://codeload.github.com/mdlacasse/Owl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238343251,"owners_count":19456202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jupyter-notebook","linear-programming","optimization","python","retirement","retirement-calculator","retirement-planner","retirement-planning","roth-ira"],"created_at":"2025-02-11T17:53:32.535Z","updated_at":"2025-10-26T14:30:38.586Z","avatar_url":"https://github.com/mdlacasse.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Owl   \n\n## A retirement exploration tool based on linear programming\n\n\u003cimg align=right src=\"https://github.com/mdlacasse/Owl/blob/main/docs/images/owl.png?raw=true\" width=\"250\"\u003e\n\n-------------------------------------------------------------------------------------\n\n### TL;DR\nOwl is a retirement financial planning tool that uses a linear programming\noptimization algorithm to provide guidance on retirement decisions\nsuch as contributions, withdrawals, Roth conversions, and more.\nUsers can select varying return rates to perform historical back testing,\nstochastic rates for performing Monte Carlo analyses,\nor fixed rates either derived from historical averages, or set by the user.\n\nThere are a few ways to run Owl:\n\n- Run Owl directly on the Streamlit Community Server at\n[owlplanner.streamlit.app](https://owlplanner.streamlit.app).\n\n- Run locally on your computer using a Docker image.\nFollow these [instructions](docker/README.md) for this option.\n\n- Run locally on your computer using Python code and libraries.\nFollow these [instructions](INSTALL.md) to install Owl from the source code and run it on your computer.\n\n-------------------------------------------------------------------------------------\n## Overview\nThis package is a modeling framework for exploring the sensitivity of retirement financial decisions.\nStrictly speaking, it is not a planning tool, but more an environment for exploring *what if* scenarios.\nIt provides different realizations of a financial strategy through the rigorous\nmathematical optimization of relevant decision variables. Two major objective goals can be set: either\nmaximize net spending, or after-tax bequest under various constraints.\nLook at the *Capabilities* section below for more detail.\n\nOne can certainly have a savings plan, but due to the volatility of financial investments,\nit is impossible to have a certain asset earnings plan. This does not mean one cannot make decisions.\nThese decisions need to be guided with an understanding of the sensitivity of the parameters.\nThis is exactly where this tool fits in. Given your savings capabilities and spending desires,\nit can generate different future realizations of\nyour strategy under different market assumptions, helping to better understand your financial situation.\n\n-------------------------------------------------------------------------------------\n## Purpose and vision\nThe goal of Owl is to create a free and open-source ecosystem that has cutting-edge optimization capabilities,\nallowing for the next generation of Python-literate retirees to experiment with their own financial future\nwhile providing a codebase where they can learn and contribute. There are and were\ngood retirement optimizers in the recent past, but the vast majority of them are either proprietary platforms\ncollecting your data, or academic papers that share the results without really sharing the details of\nthe underlying mathematical models.\nThe algorithms in Owl rely on the open-source HiGHS linear programming solver. The complete formulation and\ndetailed description of the underlying\nmathematical model can be found [here](https://github.com/mdlacasse/Owl/blob/main/docs/owl.pdf).\n\nIt is anticipated that most end users will use Owl through the graphical interface\neither at [owlplanner.streamlit.app](https://owlplanner.streamlit.app)\nor [installed](INSTALL.md) on their own computer.\nThe underlying Python package can also be used directly through Python scripts or Jupyter Notebooks\nas described [here](USER_GUIDE.md).\n\nNot every retirement decision strategy can be framed as an easy-to-solve optimization problem.\nIn particular, if one is interested in comparing different withdrawal strategies,\n[FI Calc](ficalc.app) is an elegant application that addresses this need.\nIf, however, you also want to optimize spending, bequest, and Roth conversions, with\nan approach also considering Medicare and federal income tax over the next few years,\nthen Owl is definitely a tool that can help guide your decisions.\n\n--------------------------------------------------------------------------------------\n## Capabilities\nOwl can optimize for either maximum net spending under the constraint of a given bequest (which can be zero),\nor maximize the after-tax value of a bequest under the constraint of a desired net spending profile,\nand under the assumption of a heirs marginal tax rate.\nRoth conversions are also considered, subject to an optional maximum conversion amount,\nand optimized to suit the goals of the selected objective function.\nAll calculations are indexed for inflation, which is either provided as a fixed rate,\nor through historical values, as are all other rates used for the calculations.\nThese rates can be used for backtesting different scenarios by choosing\n*historical* rates, or by choosing *historical average* rates over a historical year range,\nor what I coined \"*histochastic*\" rates which are\ngenerated using the statistical distribution of observed historical rates.\n\nPortfolios available for experimenting include assets from the S\u0026P 500, Corporate Bonds Baa, Treasury 10-y Notes,\nand cash assets assumed to just follow inflation which is represented by the Consumer Price Index.\nOther asset classes can easily be added, but would add complexity while only providing diminishing insights.\nHistorical data used are from\n[Aswath Damodaran](https://pages.stern.nyu.edu/~adamodar/) at the Stern School of Business.\nAsset allocations are selected for the duration of the plan, and these can glide linearly\nor along a configurable s-curve over the lifespan of the individual.\n\nSpending profiles are adjusted for inflation, and so are all other indexable quantities. Proflies can be\nflat or follow a *smile* curve which is also adjustable through three simple parameters.\n\nAvailable rates are from 1928 to last year and can be used to test historical performance.\nFixed rates can also be provided, as well as *histochastic* rates, which are generated using\nthe statistical characteristics (means and covariance matrix) of\na selected historical year range. Pure *stochastic* rates can also be generated\nif the user provides means, volatility (expressed as standard deviation), and optionally\nthe correlations between the different assets return rates provided as a matrix, or a list of\nthe off-diagonal elements (see documentation for details).\nAverage rates calculated over a historical data period can also be chosen.\n\nMonte Carlo simulations capabilities are included and provide a probability of success and a histogram of\noutcomes. These simulations can be used for either determining the probability distribution of the\nmaximum net spending amount under\nthe constraint of a desired bequest, or the probability distribution of the maximum\nbequest under the constraint of a desired net spending amount. Unlike discrete-event\nsimulators, Owl uses an optimization algorithm for every new scenario, which results in more\ncalculations being performed. As a result, the number of cases to be considered should be kept\nto a reasonable number. For a few hundred cases, a few minutes of calculations can provide very good estimates\nand reliable probability distributions.\n\nOptimizing each solution is more representative than event-base simulators\nin the sense that optimal solutions\nwill naturally adjust to the return scenarios being considered.\nThis is more realistic as retirees would certainly re-evaluate\ntheir expectations under severe market drops or gains.\nThis optimal approach provides a net benefit over event-based simulators,\nwhich maintain a distribution strategy either fixed, or within guardrails for capturing the\nretirees' reactions to the market.\n\nBasic input parameters can be entered through the user interface\nwhile optional additional time series can be read from\nan Excel spreadsheet that contains future wages, contributions\nto savings accounts, and planned *big-ticket items* such as the purchase of a lake house,\nthe sale of a boat, large gifts, or inheritance.\n\nThree types of savings accounts are considered: taxable, tax-deferred, and tax-free,\nwhich are all tracked separately for married individuals. Asset transition to the surviving spouse\nis done according to beneficiary fractions for each type of savings account.\nTax status covers married filing jointly and single, depending on the number of individuals reported.\n\nMaturation rules for Roth contributions and conversions are implemented as constraints\nlimiting withdrawal amounts to cover Roth account balances for 5 years after the events.\nMedicare and IRMAA calculations are performed through a self-consistent loop on cash flow constraints.\nFuture values are simple projections of current values with the assumed inflation rates.\n\n### Limitations\nOwl is work in progress. At the current time:\n- Only the US federal income tax is considered (and minimized through the optimization algorithm).\nHead of household filing status has not been added but can easily be.\n- Required minimum distributions are calculated, but tables for spouses more than 10 years apart are not included.\nThese cases are detected and will generate an error message.\n- Social security rule for surviving spouse assumes that benefits were taken at full retirement age.\n- Current version has no optimization of asset allocations between individuals and/or types of savings accounts.\nIf there is interest, that could be added in the future.\n- In the current implementation, social securiy is always taxed at 85%.\n- Medicare calculations are done through a self-consistent loop.\nThis means that the Medicare premiums are calculated after an initial solution is generated,\nand then a new solution is re-generated with these premiums as a constraint.\nIn some situations, when the income (MAGI) is near an IRMAA bracket, oscillatory solutions can arise.\nWhile the solutions generated are very close to one another, Owl will pick the smallest solution\nfor being conservative.\n- Part D is not included in the IRMAA calculations. Being considerably more significant,\nonly Part B is taken into account. \n- Future tax brackets are pure speculations derived from the little we know now and projected to the next 30 years.\nYour guesses are as good as mine.\n\nThe solution from an optimization algorithm has only two states: feasible and infeasible.\nTherefore, unlike event-driven simulators that can tell you that your distribution strategy runs\nout of money in year 20, an optimization-based solver can only tell you that a solution does or does not\nexist for the plan being considered. Examples of infeasible solutions include requesting a bequeathed\nestate value too large for the savings assets to support, even with zero net spending basis,\nor maximizing the bequest subject to a net spending basis that is already too large for the savings\nassets to support, even with no estate being left.\n\n---------------------------------------------------------------\n## Documentation\n\n- Documentation for the app user interface is available from the interface [itself](https://owlplanner.streamlit.app/Documentation).\n- Installation guide and software requirements can be found [here](INSTALL.md).\n- User guide for the underlying Python package as used in a Jupyter notebook can be found [here](USER_GUIDE.md).\n\n---------------------------------------------------------------------\n\n## Credits\n- Historical rates from [Aswath Damodaran](https://pages.stern.nyu.edu/~adamodar/)\n- Image from [freepik](https://freepik.com)\n- Optimization solver from [HiGHS](https://highs.dev)\n- Streamlit Community Cloud [Streamlit](https://streamlit.io)\n- Contributors: Josh (noimjosh@gmail.com) for Docker image code,\n Dale Seng (sengsational) for great insights and suggestions,\n Robert E. Anderson (NH-RedAnt) for bug fixes and suggestions,\n Clark Jefcoat (hubcity) for fruitful interactions,\n Benjamin Quinn (blquinn) and Gene Wood (gene1wood) for improvements and bug fixes.\n\n---------------------------------------------------------------------\n\nCopyright \u0026copy; 2024 - Martin-D. Lacasse\n\nDisclaimers: This code is for educatonal purposes only and does not constitute financial advice.\n\nCode output has been verified with analytical solutions when applicable, and comparative approaches otherwise.\nNevertheless, accuracy of results is not guaranteed.\n\n--------------------------------------------------------\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdlacasse%2Fowl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmdlacasse%2Fowl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdlacasse%2Fowl/lists"}