fundedness 0.1.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fundedness might be problematic. Click here for more details.

Files changed (97) hide show
  1. {fundedness-0.1.0 → fundedness-0.2.1}/PKG-INFO +41 -9
  2. {fundedness-0.1.0 → fundedness-0.2.1}/README.md +40 -8
  3. {fundedness-0.1.0 → fundedness-0.2.1}/docs/api/core.md +1 -1
  4. fundedness-0.2.1/docs/api/merton.md +91 -0
  5. {fundedness-0.1.0 → fundedness-0.2.1}/docs/api/models.md +11 -3
  6. fundedness-0.2.1/docs/api/viz.md +23 -0
  7. {fundedness-0.1.0 → fundedness-0.2.1}/docs/api/withdrawals.md +5 -3
  8. fundedness-0.2.1/docs/guide/utility-optimization.md +200 -0
  9. {fundedness-0.1.0 → fundedness-0.2.1}/docs/index.md +3 -1
  10. {fundedness-0.1.0 → fundedness-0.2.1}/examples/01_cefr_basics.ipynb +1 -1
  11. {fundedness-0.1.0 → fundedness-0.2.1}/examples/02_time_distribution.ipynb +1 -1
  12. {fundedness-0.1.0 → fundedness-0.2.1}/examples/03_withdrawal_comparison.ipynb +1 -1
  13. fundedness-0.2.1/fundedness/__init__.py +71 -0
  14. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/allocation/__init__.py +8 -0
  15. fundedness-0.2.1/fundedness/allocation/merton_optimal.py +220 -0
  16. fundedness-0.2.1/fundedness/merton.py +289 -0
  17. fundedness-0.2.1/fundedness/optimize.py +473 -0
  18. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/simulate.py +158 -0
  19. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/__init__.py +14 -0
  20. fundedness-0.2.1/fundedness/viz/optimal.py +542 -0
  21. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/withdrawals/__init__.py +8 -0
  22. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/withdrawals/fixed_swr.py +61 -0
  23. fundedness-0.2.1/fundedness/withdrawals/merton_optimal.py +286 -0
  24. {fundedness-0.1.0 → fundedness-0.2.1}/mkdocs.yml +2 -0
  25. {fundedness-0.1.0 → fundedness-0.2.1}/pyproject.toml +1 -1
  26. fundedness-0.2.1/streamlit_app/pages/5_Utility_Optimization.py +440 -0
  27. fundedness-0.2.1/tests/test_merton.py +311 -0
  28. fundedness-0.2.1/tests/test_optimize.py +336 -0
  29. fundedness-0.1.0/docs/api/viz.md +0 -29
  30. fundedness-0.1.0/fundedness/__init__.py +0 -38
  31. {fundedness-0.1.0 → fundedness-0.2.1}/.github/workflows/docs.yml +0 -0
  32. {fundedness-0.1.0 → fundedness-0.2.1}/.github/workflows/publish.yml +0 -0
  33. {fundedness-0.1.0 → fundedness-0.2.1}/.gitignore +0 -0
  34. {fundedness-0.1.0 → fundedness-0.2.1}/CLAUDE.md +0 -0
  35. {fundedness-0.1.0 → fundedness-0.2.1}/api/__init__.py +0 -0
  36. {fundedness-0.1.0 → fundedness-0.2.1}/api/main.py +0 -0
  37. {fundedness-0.1.0 → fundedness-0.2.1}/api/routes/__init__.py +0 -0
  38. {fundedness-0.1.0 → fundedness-0.2.1}/api/routes/cefr.py +0 -0
  39. {fundedness-0.1.0 → fundedness-0.2.1}/api/routes/compare.py +0 -0
  40. {fundedness-0.1.0 → fundedness-0.2.1}/api/routes/simulate.py +0 -0
  41. {fundedness-0.1.0 → fundedness-0.2.1}/background_information.md +0 -0
  42. {fundedness-0.1.0 → fundedness-0.2.1}/docs/examples/tutorials.md +0 -0
  43. {fundedness-0.1.0 → fundedness-0.2.1}/docs/getting-started/installation.md +0 -0
  44. {fundedness-0.1.0 → fundedness-0.2.1}/docs/getting-started/quickstart.md +0 -0
  45. {fundedness-0.1.0 → fundedness-0.2.1}/docs/guide/cefr.md +0 -0
  46. {fundedness-0.1.0 → fundedness-0.2.1}/docs/guide/simulations.md +0 -0
  47. {fundedness-0.1.0 → fundedness-0.2.1}/docs/guide/visualizations.md +0 -0
  48. {fundedness-0.1.0 → fundedness-0.2.1}/docs/guide/withdrawals.md +0 -0
  49. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/allocation/base.py +0 -0
  50. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/allocation/constant.py +0 -0
  51. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/allocation/glidepath.py +0 -0
  52. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/cefr.py +0 -0
  53. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/liabilities.py +0 -0
  54. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/liquidity.py +0 -0
  55. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/__init__.py +0 -0
  56. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/assets.py +0 -0
  57. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/household.py +0 -0
  58. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/liabilities.py +0 -0
  59. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/market.py +0 -0
  60. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/simulation.py +0 -0
  61. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/tax.py +0 -0
  62. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/models/utility.py +0 -0
  63. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/policies.py +0 -0
  64. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/risk.py +0 -0
  65. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/colors.py +0 -0
  66. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/comparison.py +0 -0
  67. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/fan_chart.py +0 -0
  68. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/histogram.py +0 -0
  69. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/survival.py +0 -0
  70. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/tornado.py +0 -0
  71. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/viz/waterfall.py +0 -0
  72. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/withdrawals/base.py +0 -0
  73. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/withdrawals/comparison.py +0 -0
  74. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/withdrawals/guardrails.py +0 -0
  75. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/withdrawals/rmd_style.py +0 -0
  76. {fundedness-0.1.0 → fundedness-0.2.1}/fundedness/withdrawals/vpw.py +0 -0
  77. {fundedness-0.1.0 → fundedness-0.2.1}/requirements.txt +0 -0
  78. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/__init__.py +0 -0
  79. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/app.py +0 -0
  80. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/components/__init__.py +0 -0
  81. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/components/asset_editor.py +0 -0
  82. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/components/liability_editor.py +0 -0
  83. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/components/metrics_display.py +0 -0
  84. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/pages/0_Inputs.py +0 -0
  85. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/pages/1_CEFR_Dashboard.py +0 -0
  86. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/pages/2_Time_Runway.py +0 -0
  87. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/pages/3_Withdrawal_Lab.py +0 -0
  88. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/pages/4_Sensitivity.py +0 -0
  89. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/utils/__init__.py +0 -0
  90. {fundedness-0.1.0 → fundedness-0.2.1}/streamlit_app/utils/session_state.py +0 -0
  91. {fundedness-0.1.0 → fundedness-0.2.1}/tests/__init__.py +0 -0
  92. {fundedness-0.1.0 → fundedness-0.2.1}/tests/conftest.py +0 -0
  93. {fundedness-0.1.0 → fundedness-0.2.1}/tests/test_api.py +0 -0
  94. {fundedness-0.1.0 → fundedness-0.2.1}/tests/test_cefr.py +0 -0
  95. {fundedness-0.1.0 → fundedness-0.2.1}/tests/test_liabilities.py +0 -0
  96. {fundedness-0.1.0 → fundedness-0.2.1}/tests/test_simulate.py +0 -0
  97. {fundedness-0.1.0 → fundedness-0.2.1}/tests/test_withdrawals.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fundedness
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: A Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful visualizations
5
5
  Project-URL: Homepage, https://github.com/engineerinvestor/financial-health-calculator
6
6
  Project-URL: Documentation, https://engineerinvestor.github.io/financial-health-calculator/
@@ -54,15 +54,22 @@ Description-Content-Type: text/markdown
54
54
 
55
55
  # Financial Health Calculator
56
56
 
57
- A comprehensive Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful Plotly visualizations.
58
-
57
+ [![PyPI version](https://img.shields.io/pypi/v/fundedness.svg)](https://pypi.org/project/fundedness/)
58
+ [![Python versions](https://img.shields.io/pypi/pyversions/fundedness.svg)](https://pypi.org/project/fundedness/)
59
+ [![CI](https://github.com/engineerinvestor/financial-health-calculator/actions/workflows/ci.yml/badge.svg)](https://github.com/engineerinvestor/financial-health-calculator/actions/workflows/ci.yml)
60
+ [![codecov](https://codecov.io/gh/engineerinvestor/financial-health-calculator/branch/main/graph/badge.svg)](https://codecov.io/gh/engineerinvestor/financial-health-calculator)
61
+ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://engineerinvestor.github.io/financial-health-calculator/)
62
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
59
63
  [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/engineerinvestor/financial-health-calculator/blob/main/examples/01_cefr_basics.ipynb)
60
64
 
65
+ A comprehensive Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful Plotly visualizations.
66
+
61
67
  ## Features
62
68
 
63
69
  - **CEFR (Certainty-Equivalent Funded Ratio)**: A fundedness metric that accounts for taxes, liquidity, and concentration risk
64
70
  - **Monte Carlo Simulations**: Project retirement outcomes with configurable market assumptions
65
- - **Withdrawal Strategy Lab**: Compare strategies including fixed SWR, guardrails, VPW, and RMD-style
71
+ - **Withdrawal Strategy Lab**: Compare strategies including fixed SWR, guardrails, VPW, RMD-style, and Merton optimal
72
+ - **Utility Optimization**: Merton optimal spending and allocation based on lifetime utility maximization
66
73
  - **Beautiful Visualizations**: Interactive Plotly charts with fan charts, waterfalls, and survival curves
67
74
  - **REST API**: FastAPI backend for programmatic access
68
75
  - **Streamlit App**: User-friendly web interface
@@ -72,12 +79,12 @@ A comprehensive Python financial planning toolkit with CEFR calculations, Monte
72
79
  ### Installation
73
80
 
74
81
  ```bash
75
- pip install git+https://github.com/engineerinvestor/financial-health-calculator.git
82
+ pip install fundedness
76
83
  ```
77
84
 
78
85
  For development with all extras:
79
86
  ```bash
80
- pip install "git+https://github.com/engineerinvestor/financial-health-calculator.git#egg=fundedness[all]"
87
+ pip install "fundedness[all]"
81
88
  ```
82
89
 
83
90
  ### Basic Usage
@@ -176,6 +183,22 @@ Where τ = tax rate, λ = liquidity factor, ρ = reliability factor
176
183
  | Guardrails | Adjustable with floor/ceiling | Balance |
177
184
  | VPW | Age-based variable percentage | Maximizing spending |
178
185
  | RMD-Style | IRS distribution table based | Tax efficiency |
186
+ | Merton Optimal | Utility-maximizing spending rate | Optimality |
187
+
188
+ ### Utility Optimization
189
+
190
+ The toolkit includes Merton's optimal consumption and portfolio choice framework, as applied in modern retirement planning research<sup>[1]</sup>:
191
+
192
+ - **Optimal Equity Allocation**: `k* = (μ - r) / (γ × σ²)`
193
+ - **Wealth-Adjusted Allocation**: Reduces equity as wealth approaches subsistence floor
194
+ - **Optimal Spending Rate**: Increases with age as horizon shortens
195
+ - **Expected Lifetime Utility**: Track utility across Monte Carlo paths
196
+
197
+ Key insights from this methodology:
198
+ 1. Optimal spending starts low (~2-3%) and rises with age
199
+ 2. Allocation should decrease as wealth approaches the floor
200
+ 3. Risk aversion (gamma) is the critical input parameter
201
+ 4. The 4% rule is suboptimal from a utility perspective
179
202
 
180
203
  ## Development
181
204
 
@@ -207,13 +230,16 @@ financial-health-calculator/
207
230
  ├── fundedness/ # Core Python package
208
231
  │ ├── models/ # Pydantic data models
209
232
  │ ├── viz/ # Plotly visualizations
210
- │ ├── withdrawals/ # Withdrawal strategies
211
- │ ├── allocation/ # Asset allocation strategies
233
+ │ ├── withdrawals/ # Withdrawal strategies (SWR, guardrails, VPW, Merton)
234
+ │ ├── allocation/ # Asset allocation strategies (constant, glidepath, Merton)
212
235
  │ ├── cefr.py # CEFR calculation
213
- │ ├── simulate.py # Monte Carlo engine
236
+ │ ├── simulate.py # Monte Carlo engine with utility tracking
237
+ │ ├── merton.py # Merton optimal formulas
238
+ │ ├── optimize.py # Policy parameter optimization
214
239
  │ └── policies.py # Spending/allocation policies
215
240
  ├── api/ # FastAPI REST API
216
241
  ├── streamlit_app/ # Streamlit web application
242
+ │ └── pages/ # Includes Utility Optimization page
217
243
  ├── examples/ # Jupyter notebooks
218
244
  └── tests/ # pytest tests
219
245
  ```
@@ -228,6 +254,12 @@ financial-health-calculator/
228
254
 
229
255
  MIT License
230
256
 
257
+ ## References
258
+
259
+ 1. Haghani, V., & White, J. (2023). *The Missing Billionaires: A Guide to Better Financial Decisions*. Wiley. See also [Elm Wealth](https://elmwealth.com/) for related research on optimal spending and allocation.
260
+
261
+ 2. Merton, R. C. (1969). Lifetime Portfolio Selection under Uncertainty: The Continuous-Time Case. *The Review of Economics and Statistics*, 51(3), 247-257.
262
+
231
263
  ## Disclaimer
232
264
 
233
265
  This tool is for educational purposes only and does not constitute financial advice. Consult a qualified financial advisor for personalized recommendations.
@@ -1,14 +1,21 @@
1
1
  # Financial Health Calculator
2
2
 
3
- A comprehensive Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful Plotly visualizations.
4
-
3
+ [![PyPI version](https://img.shields.io/pypi/v/fundedness.svg)](https://pypi.org/project/fundedness/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/fundedness.svg)](https://pypi.org/project/fundedness/)
5
+ [![CI](https://github.com/engineerinvestor/financial-health-calculator/actions/workflows/ci.yml/badge.svg)](https://github.com/engineerinvestor/financial-health-calculator/actions/workflows/ci.yml)
6
+ [![codecov](https://codecov.io/gh/engineerinvestor/financial-health-calculator/branch/main/graph/badge.svg)](https://codecov.io/gh/engineerinvestor/financial-health-calculator)
7
+ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://engineerinvestor.github.io/financial-health-calculator/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
9
  [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/engineerinvestor/financial-health-calculator/blob/main/examples/01_cefr_basics.ipynb)
6
10
 
11
+ A comprehensive Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful Plotly visualizations.
12
+
7
13
  ## Features
8
14
 
9
15
  - **CEFR (Certainty-Equivalent Funded Ratio)**: A fundedness metric that accounts for taxes, liquidity, and concentration risk
10
16
  - **Monte Carlo Simulations**: Project retirement outcomes with configurable market assumptions
11
- - **Withdrawal Strategy Lab**: Compare strategies including fixed SWR, guardrails, VPW, and RMD-style
17
+ - **Withdrawal Strategy Lab**: Compare strategies including fixed SWR, guardrails, VPW, RMD-style, and Merton optimal
18
+ - **Utility Optimization**: Merton optimal spending and allocation based on lifetime utility maximization
12
19
  - **Beautiful Visualizations**: Interactive Plotly charts with fan charts, waterfalls, and survival curves
13
20
  - **REST API**: FastAPI backend for programmatic access
14
21
  - **Streamlit App**: User-friendly web interface
@@ -18,12 +25,12 @@ A comprehensive Python financial planning toolkit with CEFR calculations, Monte
18
25
  ### Installation
19
26
 
20
27
  ```bash
21
- pip install git+https://github.com/engineerinvestor/financial-health-calculator.git
28
+ pip install fundedness
22
29
  ```
23
30
 
24
31
  For development with all extras:
25
32
  ```bash
26
- pip install "git+https://github.com/engineerinvestor/financial-health-calculator.git#egg=fundedness[all]"
33
+ pip install "fundedness[all]"
27
34
  ```
28
35
 
29
36
  ### Basic Usage
@@ -122,6 +129,22 @@ Where τ = tax rate, λ = liquidity factor, ρ = reliability factor
122
129
  | Guardrails | Adjustable with floor/ceiling | Balance |
123
130
  | VPW | Age-based variable percentage | Maximizing spending |
124
131
  | RMD-Style | IRS distribution table based | Tax efficiency |
132
+ | Merton Optimal | Utility-maximizing spending rate | Optimality |
133
+
134
+ ### Utility Optimization
135
+
136
+ The toolkit includes Merton's optimal consumption and portfolio choice framework, as applied in modern retirement planning research<sup>[1]</sup>:
137
+
138
+ - **Optimal Equity Allocation**: `k* = (μ - r) / (γ × σ²)`
139
+ - **Wealth-Adjusted Allocation**: Reduces equity as wealth approaches subsistence floor
140
+ - **Optimal Spending Rate**: Increases with age as horizon shortens
141
+ - **Expected Lifetime Utility**: Track utility across Monte Carlo paths
142
+
143
+ Key insights from this methodology:
144
+ 1. Optimal spending starts low (~2-3%) and rises with age
145
+ 2. Allocation should decrease as wealth approaches the floor
146
+ 3. Risk aversion (gamma) is the critical input parameter
147
+ 4. The 4% rule is suboptimal from a utility perspective
125
148
 
126
149
  ## Development
127
150
 
@@ -153,13 +176,16 @@ financial-health-calculator/
153
176
  ├── fundedness/ # Core Python package
154
177
  │ ├── models/ # Pydantic data models
155
178
  │ ├── viz/ # Plotly visualizations
156
- │ ├── withdrawals/ # Withdrawal strategies
157
- │ ├── allocation/ # Asset allocation strategies
179
+ │ ├── withdrawals/ # Withdrawal strategies (SWR, guardrails, VPW, Merton)
180
+ │ ├── allocation/ # Asset allocation strategies (constant, glidepath, Merton)
158
181
  │ ├── cefr.py # CEFR calculation
159
- │ ├── simulate.py # Monte Carlo engine
182
+ │ ├── simulate.py # Monte Carlo engine with utility tracking
183
+ │ ├── merton.py # Merton optimal formulas
184
+ │ ├── optimize.py # Policy parameter optimization
160
185
  │ └── policies.py # Spending/allocation policies
161
186
  ├── api/ # FastAPI REST API
162
187
  ├── streamlit_app/ # Streamlit web application
188
+ │ └── pages/ # Includes Utility Optimization page
163
189
  ├── examples/ # Jupyter notebooks
164
190
  └── tests/ # pytest tests
165
191
  ```
@@ -174,6 +200,12 @@ financial-health-calculator/
174
200
 
175
201
  MIT License
176
202
 
203
+ ## References
204
+
205
+ 1. Haghani, V., & White, J. (2023). *The Missing Billionaires: A Guide to Better Financial Decisions*. Wiley. See also [Elm Wealth](https://elmwealth.com/) for related research on optimal spending and allocation.
206
+
207
+ 2. Merton, R. C. (1969). Lifetime Portfolio Selection under Uncertainty: The Continuous-Time Case. *The Review of Economics and Statistics*, 51(3), 247-257.
208
+
177
209
  ## Disclaimer
178
210
 
179
211
  This tool is for educational purposes only and does not constitute financial advice. Consult a qualified financial advisor for personalized recommendations.
@@ -12,4 +12,4 @@ The main calculation and simulation functions.
12
12
 
13
13
  ## Strategy Comparison
14
14
 
15
- ::: fundedness.simulate.compare_strategies
15
+ ::: fundedness.withdrawals.comparison.compare_strategies
@@ -0,0 +1,91 @@
1
+ # Merton Optimal API Reference
2
+
3
+ This module provides Merton's optimal consumption and portfolio choice formulas.
4
+
5
+ ## Core Functions
6
+
7
+ ::: fundedness.merton.merton_optimal_allocation
8
+ options:
9
+ show_root_heading: true
10
+
11
+ ::: fundedness.merton.certainty_equivalent_return
12
+ options:
13
+ show_root_heading: true
14
+
15
+ ::: fundedness.merton.merton_optimal_spending_rate
16
+ options:
17
+ show_root_heading: true
18
+
19
+ ::: fundedness.merton.wealth_adjusted_optimal_allocation
20
+ options:
21
+ show_root_heading: true
22
+
23
+ ::: fundedness.merton.calculate_merton_optimal
24
+ options:
25
+ show_root_heading: true
26
+
27
+ ## Helper Functions
28
+
29
+ ::: fundedness.merton.optimal_spending_by_age
30
+ options:
31
+ show_root_heading: true
32
+
33
+ ::: fundedness.merton.optimal_allocation_by_wealth
34
+ options:
35
+ show_root_heading: true
36
+
37
+ ## Data Classes
38
+
39
+ ::: fundedness.merton.MertonOptimalResult
40
+ options:
41
+ show_root_heading: true
42
+
43
+ ## Spending Policies
44
+
45
+ ::: fundedness.withdrawals.merton_optimal.MertonOptimalSpendingPolicy
46
+ options:
47
+ show_root_heading: true
48
+
49
+ ::: fundedness.withdrawals.merton_optimal.SmoothedMertonPolicy
50
+ options:
51
+ show_root_heading: true
52
+
53
+ ::: fundedness.withdrawals.merton_optimal.FloorAdjustedMertonPolicy
54
+ options:
55
+ show_root_heading: true
56
+
57
+ ## Allocation Policies
58
+
59
+ ::: fundedness.allocation.merton_optimal.MertonOptimalAllocationPolicy
60
+ options:
61
+ show_root_heading: true
62
+
63
+ ::: fundedness.allocation.merton_optimal.WealthBasedAllocationPolicy
64
+ options:
65
+ show_root_heading: true
66
+
67
+ ::: fundedness.allocation.merton_optimal.FloorProtectionAllocationPolicy
68
+ options:
69
+ show_root_heading: true
70
+
71
+ ## Policy Optimization
72
+
73
+ ::: fundedness.optimize.PolicyParameterSpec
74
+ options:
75
+ show_root_heading: true
76
+
77
+ ::: fundedness.optimize.OptimizationResult
78
+ options:
79
+ show_root_heading: true
80
+
81
+ ::: fundedness.optimize.optimize_spending_policy
82
+ options:
83
+ show_root_heading: true
84
+
85
+ ::: fundedness.optimize.optimize_allocation_policy
86
+ options:
87
+ show_root_heading: true
88
+
89
+ ::: fundedness.optimize.optimize_combined_policy
90
+ options:
91
+ show_root_heading: true
@@ -14,7 +14,7 @@ Pydantic models for representing financial data.
14
14
 
15
15
  ## Balance Sheet
16
16
 
17
- ::: fundedness.models.balance_sheet.BalanceSheet
17
+ ::: fundedness.models.assets.BalanceSheet
18
18
 
19
19
  ## Liabilities
20
20
 
@@ -26,6 +26,14 @@ Pydantic models for representing financial data.
26
26
 
27
27
  ::: fundedness.models.household.Person
28
28
 
29
- ## Market Assumptions
29
+ ## Market Model
30
30
 
31
- ::: fundedness.models.assumptions.MarketAssumptions
31
+ ::: fundedness.models.market.MarketModel
32
+
33
+ ## Simulation Config
34
+
35
+ ::: fundedness.models.simulation.SimulationConfig
36
+
37
+ ## Tax Model
38
+
39
+ ::: fundedness.models.tax.TaxModel
@@ -0,0 +1,23 @@
1
+ # Visualization Functions
2
+
3
+ Plotly chart generation functions.
4
+
5
+ ## CEFR Charts
6
+
7
+ ::: fundedness.viz.waterfall.create_cefr_waterfall
8
+
9
+ ## Simulation Charts
10
+
11
+ ::: fundedness.viz.fan_chart.create_fan_chart
12
+
13
+ ::: fundedness.viz.survival.create_survival_curve
14
+
15
+ ::: fundedness.viz.histogram.create_time_distribution_histogram
16
+
17
+ ## Comparison Charts
18
+
19
+ ::: fundedness.viz.comparison.create_strategy_comparison_chart
20
+
21
+ ## Sensitivity Charts
22
+
23
+ ::: fundedness.viz.tornado.create_tornado_chart
@@ -6,13 +6,15 @@ Classes implementing different withdrawal strategies.
6
6
 
7
7
  ::: fundedness.withdrawals.base.WithdrawalPolicy
8
8
 
9
+ ::: fundedness.withdrawals.base.BaseWithdrawalPolicy
10
+
9
11
  ## Fixed SWR
10
12
 
11
- ::: fundedness.withdrawals.fixed_swr.FixedSWRPolicy
13
+ ::: fundedness.withdrawals.fixed_swr.FixedRealSWRPolicy
12
14
 
13
15
  ## Percentage of Portfolio
14
16
 
15
- ::: fundedness.withdrawals.percent_of_portfolio.PercentOfPortfolioPolicy
17
+ ::: fundedness.withdrawals.fixed_swr.PercentOfPortfolioPolicy
16
18
 
17
19
  ## Guardrails
18
20
 
@@ -24,4 +26,4 @@ Classes implementing different withdrawal strategies.
24
26
 
25
27
  ## RMD-Style
26
28
 
27
- ::: fundedness.withdrawals.rmd.RMDPolicy
29
+ ::: fundedness.withdrawals.rmd_style.RMDStylePolicy
@@ -0,0 +1,200 @@
1
+ # Utility Optimization
2
+
3
+ This guide covers the utility-optimal spending and allocation framework based on Merton's continuous-time portfolio optimization theory.
4
+
5
+ ## Overview
6
+
7
+ Traditional retirement planning often uses rules of thumb like the "4% rule." While simple, these approaches don't account for individual preferences about risk and the trade-off between spending now versus later.
8
+
9
+ Utility optimization provides a rigorous framework for finding the **optimal** spending rate and asset allocation based on:
10
+
11
+ - **Risk aversion (gamma)**: How much you dislike uncertainty
12
+ - **Time preference**: How much you prefer spending now vs. later
13
+ - **Subsistence floor**: Minimum spending you need to survive
14
+
15
+ ## Key Formulas
16
+
17
+ ### Optimal Equity Allocation
18
+
19
+ The Merton formula gives the optimal fraction to invest in risky assets:
20
+
21
+ $$k^* = \frac{\mu - r}{\gamma \times \sigma^2}$$
22
+
23
+ Where:
24
+
25
+ - $\mu$ = expected stock return
26
+ - $r$ = bond/risk-free return
27
+ - $\gamma$ = risk aversion coefficient
28
+ - $\sigma$ = stock volatility
29
+
30
+ ### Certainty Equivalent Return
31
+
32
+ The guaranteed return that provides the same utility as the risky portfolio:
33
+
34
+ $$r_{CE} = r + k^*(\mu - r) - \frac{\gamma \times k^{*2} \times \sigma^2}{2}$$
35
+
36
+ ### Optimal Spending Rate
37
+
38
+ For an infinite horizon:
39
+
40
+ $$c^* = r_{CE} - \frac{r_{CE} - \rho}{\gamma}$$
41
+
42
+ Where $\rho$ is your time preference (discount rate).
43
+
44
+ ## Quick Start
45
+
46
+ ```python
47
+ from fundedness import (
48
+ calculate_merton_optimal,
49
+ MarketModel,
50
+ UtilityModel,
51
+ )
52
+
53
+ # Define market assumptions
54
+ market = MarketModel(
55
+ stock_return=0.05, # 5% expected real return
56
+ bond_return=0.015, # 1.5% risk-free rate
57
+ stock_volatility=0.16, # 16% annual volatility
58
+ )
59
+
60
+ # Define your preferences
61
+ utility = UtilityModel(
62
+ gamma=3.0, # Risk aversion (typical: 2-5)
63
+ subsistence_floor=30000, # Minimum annual spending
64
+ time_preference=0.02, # 2% discount rate
65
+ )
66
+
67
+ # Calculate optimal policy
68
+ result = calculate_merton_optimal(
69
+ wealth=1_000_000,
70
+ market_model=market,
71
+ utility_model=utility,
72
+ remaining_years=30,
73
+ )
74
+
75
+ print(f"Optimal equity allocation: {result.optimal_equity_allocation:.1%}")
76
+ print(f"Wealth-adjusted allocation: {result.wealth_adjusted_allocation:.1%}")
77
+ print(f"Optimal spending rate: {result.optimal_spending_rate:.1%}")
78
+ print(f"Year 1 spending: ${1_000_000 * result.optimal_spending_rate:,.0f}")
79
+ ```
80
+
81
+ ## Wealth-Adjusted Allocation
82
+
83
+ Near the subsistence floor, you can't afford to take risk. The wealth-adjusted allocation accounts for this:
84
+
85
+ $$k_{adj} = k^* \times \frac{W - F}{W}$$
86
+
87
+ Where $W$ is wealth and $F$ is the subsistence floor.
88
+
89
+ As wealth approaches the floor, allocation approaches zero. As wealth rises far above the floor, allocation approaches the unconstrained optimal.
90
+
91
+ ```python
92
+ from fundedness import wealth_adjusted_optimal_allocation
93
+
94
+ # Near the floor: low allocation
95
+ k_low = wealth_adjusted_optimal_allocation(
96
+ wealth=50_000, # Just above $30k floor
97
+ market_model=market,
98
+ utility_model=utility,
99
+ )
100
+ print(f"Allocation at $50k: {k_low:.1%}") # ~18%
101
+
102
+ # Well above floor: approaches optimal
103
+ k_high = wealth_adjusted_optimal_allocation(
104
+ wealth=2_000_000,
105
+ market_model=market,
106
+ utility_model=utility,
107
+ )
108
+ print(f"Allocation at $2M: {k_high:.1%}") # ~44%
109
+ ```
110
+
111
+ ## Spending Rate by Age
112
+
113
+ Optimal spending rate increases with age as the remaining horizon shortens:
114
+
115
+ ```python
116
+ from fundedness import optimal_spending_by_age
117
+
118
+ rates = optimal_spending_by_age(
119
+ market_model=market,
120
+ utility_model=utility,
121
+ starting_age=65,
122
+ end_age=95,
123
+ )
124
+
125
+ for age in [65, 75, 85, 95]:
126
+ print(f"Age {age}: {rates[age]:.1%}")
127
+ ```
128
+
129
+ Example output:
130
+ ```
131
+ Age 65: 3.8%
132
+ Age 75: 5.2%
133
+ Age 85: 7.8%
134
+ Age 95: 100.0%
135
+ ```
136
+
137
+ ## Using Merton Policies in Simulation
138
+
139
+ ### Merton Spending Policy
140
+
141
+ ```python
142
+ from fundedness.withdrawals import MertonOptimalSpendingPolicy
143
+ from fundedness.allocation import MertonOptimalAllocationPolicy
144
+ from fundedness import run_simulation_with_utility, SimulationConfig
145
+
146
+ # Create policies
147
+ spending_policy = MertonOptimalSpendingPolicy(
148
+ market_model=market,
149
+ utility_model=utility,
150
+ starting_age=65,
151
+ end_age=95,
152
+ )
153
+
154
+ allocation_policy = MertonOptimalAllocationPolicy(
155
+ market_model=market,
156
+ utility_model=utility,
157
+ )
158
+
159
+ # Run simulation with utility tracking
160
+ config = SimulationConfig(
161
+ n_simulations=5000,
162
+ n_years=30,
163
+ market_model=market,
164
+ )
165
+
166
+ result = run_simulation_with_utility(
167
+ initial_wealth=1_000_000,
168
+ spending_policy=spending_policy,
169
+ allocation_policy=allocation_policy,
170
+ config=config,
171
+ utility_model=utility,
172
+ )
173
+
174
+ print(f"Expected lifetime utility: {result.expected_lifetime_utility:.2e}")
175
+ print(f"Certainty equivalent: ${result.certainty_equivalent_consumption:,.0f}/year")
176
+ print(f"Success rate: {result.success_rate:.1%}")
177
+ ```
178
+
179
+ ## Key Insights
180
+
181
+ 1. **Spending rate increases with age** - As the horizon shortens, you should spend more
182
+ 2. **Allocation decreases near the floor** - You can't afford risk when close to subsistence
183
+ 3. **Risk aversion (gamma) is critical** - Higher gamma means lower allocation and spending
184
+ 4. **The 4% rule is often suboptimal** - Merton optimal typically starts lower and ends higher
185
+
186
+ ## Choosing Your Risk Aversion
187
+
188
+ Risk aversion (gamma) is the most important input. Guidelines:
189
+
190
+ | Gamma | Risk Tolerance | Profile |
191
+ |-------|----------------|---------|
192
+ | 1-2 | High | Comfortable with volatility |
193
+ | 2-3 | Moderate | Typical investor |
194
+ | 3-5 | Low | Prefers stability |
195
+ | 5+ | Very low | Strong loss aversion |
196
+
197
+ ## References
198
+
199
+ - Merton, R. C. (1969). Lifetime Portfolio Selection under Uncertainty: The Continuous-Time Case. *The Review of Economics and Statistics*, 51(3), 247-257.
200
+ - Haghani, V., & White, J. (2023). *The Missing Billionaires: A Guide to Better Financial Decisions*. Wiley.
@@ -8,7 +8,8 @@ A comprehensive Python financial planning toolkit with CEFR calculations, Monte
8
8
 
9
9
  - **CEFR (Certainty-Equivalent Funded Ratio)**: A fundedness metric that accounts for taxes, liquidity, and concentration risk
10
10
  - **Monte Carlo Simulations**: Project retirement outcomes with configurable market assumptions
11
- - **Withdrawal Strategy Lab**: Compare strategies including fixed SWR, guardrails, VPW, and RMD-style
11
+ - **Withdrawal Strategy Lab**: Compare strategies including fixed SWR, guardrails, VPW, RMD-style, and Merton optimal
12
+ - **Utility Optimization**: Merton optimal spending and allocation based on lifetime utility maximization
12
13
  - **Beautiful Visualizations**: Interactive Plotly charts with fan charts, waterfalls, and survival curves
13
14
  - **REST API**: FastAPI backend for programmatic access
14
15
  - **Streamlit App**: User-friendly web interface
@@ -55,6 +56,7 @@ print(f"CEFR: {result.cefr:.2f}")
55
56
  - [CEFR Explained](guide/cefr.md) - Understanding the CEFR metric
56
57
  - [Monte Carlo Simulations](guide/simulations.md) - Running projections
57
58
  - [Withdrawal Strategies](guide/withdrawals.md) - Comparing approaches
59
+ - [Utility Optimization](guide/utility-optimization.md) - Merton optimal spending and allocation
58
60
  - [Visualizations](guide/visualizations.md) - Creating charts
59
61
 
60
62
  ## API Reference
@@ -10,7 +10,7 @@
10
10
  "execution_count": null,
11
11
  "metadata": {},
12
12
  "outputs": [],
13
- "source": "# Install the fundedness package from GitHub\n!pip install git+https://github.com/engineerinvestor/financial-health-calculator.git -q"
13
+ "source": "# Install the fundedness package\n!pip install fundedness -q"
14
14
  },
15
15
  {
16
16
  "cell_type": "code",
@@ -10,7 +10,7 @@
10
10
  "execution_count": null,
11
11
  "metadata": {},
12
12
  "outputs": [],
13
- "source": "# Install the fundedness package from GitHub\n!pip install git+https://github.com/engineerinvestor/financial-health-calculator.git -q"
13
+ "source": "# Install the fundedness package\n!pip install fundedness -q"
14
14
  },
15
15
  {
16
16
  "cell_type": "code",
@@ -10,7 +10,7 @@
10
10
  "execution_count": null,
11
11
  "metadata": {},
12
12
  "outputs": [],
13
- "source": "# Install the fundedness package from GitHub\n!pip install git+https://github.com/engineerinvestor/financial-health-calculator.git -q"
13
+ "source": "# Install the fundedness package\n!pip install fundedness -q"
14
14
  },
15
15
  {
16
16
  "cell_type": "code",