fundedness 0.2.2__py3-none-any.whl

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 (43) hide show
  1. fundedness/__init__.py +71 -0
  2. fundedness/allocation/__init__.py +20 -0
  3. fundedness/allocation/base.py +32 -0
  4. fundedness/allocation/constant.py +25 -0
  5. fundedness/allocation/glidepath.py +111 -0
  6. fundedness/allocation/merton_optimal.py +220 -0
  7. fundedness/cefr.py +241 -0
  8. fundedness/liabilities.py +221 -0
  9. fundedness/liquidity.py +49 -0
  10. fundedness/merton.py +289 -0
  11. fundedness/models/__init__.py +35 -0
  12. fundedness/models/assets.py +148 -0
  13. fundedness/models/household.py +153 -0
  14. fundedness/models/liabilities.py +99 -0
  15. fundedness/models/market.py +188 -0
  16. fundedness/models/simulation.py +80 -0
  17. fundedness/models/tax.py +125 -0
  18. fundedness/models/utility.py +154 -0
  19. fundedness/optimize.py +473 -0
  20. fundedness/policies.py +204 -0
  21. fundedness/risk.py +72 -0
  22. fundedness/simulate.py +559 -0
  23. fundedness/viz/__init__.py +33 -0
  24. fundedness/viz/colors.py +110 -0
  25. fundedness/viz/comparison.py +294 -0
  26. fundedness/viz/fan_chart.py +193 -0
  27. fundedness/viz/histogram.py +225 -0
  28. fundedness/viz/optimal.py +542 -0
  29. fundedness/viz/survival.py +230 -0
  30. fundedness/viz/tornado.py +236 -0
  31. fundedness/viz/waterfall.py +203 -0
  32. fundedness/withdrawals/__init__.py +27 -0
  33. fundedness/withdrawals/base.py +116 -0
  34. fundedness/withdrawals/comparison.py +230 -0
  35. fundedness/withdrawals/fixed_swr.py +174 -0
  36. fundedness/withdrawals/guardrails.py +136 -0
  37. fundedness/withdrawals/merton_optimal.py +286 -0
  38. fundedness/withdrawals/rmd_style.py +203 -0
  39. fundedness/withdrawals/vpw.py +136 -0
  40. fundedness-0.2.2.dist-info/METADATA +299 -0
  41. fundedness-0.2.2.dist-info/RECORD +43 -0
  42. fundedness-0.2.2.dist-info/WHEEL +4 -0
  43. fundedness-0.2.2.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,299 @@
1
+ Metadata-Version: 2.4
2
+ Name: fundedness
3
+ Version: 0.2.2
4
+ Summary: A Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful visualizations
5
+ Project-URL: Homepage, https://github.com/engineerinvestor/financial-health-calculator
6
+ Project-URL: Documentation, https://engineerinvestor.github.io/financial-health-calculator/
7
+ Project-URL: Repository, https://github.com/engineerinvestor/financial-health-calculator
8
+ Author-email: Engineer Investor <egr.investor@gmail.com>
9
+ License-Expression: MIT
10
+ Keywords: CEFR,Monte Carlo,finance,planning,retirement,withdrawal
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: Intended Audience :: Financial and Insurance Industry
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Office/Business :: Financial :: Investment
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: numpy>=1.24.0
22
+ Requires-Dist: pandas>=2.0.0
23
+ Requires-Dist: plotly>=5.18.0
24
+ Requires-Dist: pydantic>=2.0.0
25
+ Requires-Dist: scipy>=1.11.0
26
+ Provides-Extra: all
27
+ Requires-Dist: fastapi>=0.108.0; extra == 'all'
28
+ Requires-Dist: hypothesis>=6.92.0; extra == 'all'
29
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'all'
30
+ Requires-Dist: mkdocs>=1.5.0; extra == 'all'
31
+ Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'all'
32
+ Requires-Dist: mypy>=1.8.0; extra == 'all'
33
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'all'
34
+ Requires-Dist: pytest>=7.4.0; extra == 'all'
35
+ Requires-Dist: ruff>=0.1.9; extra == 'all'
36
+ Requires-Dist: streamlit>=1.29.0; extra == 'all'
37
+ Requires-Dist: uvicorn[standard]>=0.25.0; extra == 'all'
38
+ Provides-Extra: api
39
+ Requires-Dist: fastapi>=0.108.0; extra == 'api'
40
+ Requires-Dist: uvicorn[standard]>=0.25.0; extra == 'api'
41
+ Provides-Extra: dev
42
+ Requires-Dist: hypothesis>=6.92.0; extra == 'dev'
43
+ Requires-Dist: mypy>=1.8.0; extra == 'dev'
44
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
45
+ Requires-Dist: pytest>=7.4.0; extra == 'dev'
46
+ Requires-Dist: ruff>=0.1.9; extra == 'dev'
47
+ Provides-Extra: docs
48
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
49
+ Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
50
+ Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
51
+ Provides-Extra: streamlit
52
+ Requires-Dist: streamlit>=1.29.0; extra == 'streamlit'
53
+ Description-Content-Type: text/markdown
54
+
55
+ # Financial Health Calculator
56
+
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
+ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://engineerinvestor.github.io/financial-health-calculator/)
60
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
61
+ [![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)
62
+
63
+ A comprehensive Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful Plotly visualizations.
64
+
65
+ ## Features
66
+
67
+ - **CEFR (Certainty-Equivalent Funded Ratio)**: A fundedness metric that accounts for taxes, liquidity, and concentration risk
68
+ - **Monte Carlo Simulations**: Project retirement outcomes with configurable market assumptions
69
+ - **Withdrawal Strategy Lab**: Compare strategies including fixed SWR, guardrails, VPW, RMD-style, and Merton optimal
70
+ - **Utility Optimization**: Merton optimal spending and allocation based on lifetime utility maximization
71
+ - **Beautiful Visualizations**: Interactive Plotly charts with fan charts, waterfalls, and survival curves
72
+ - **REST API**: FastAPI backend for programmatic access
73
+ - **Streamlit App**: User-friendly web interface
74
+
75
+ ## Quick Start
76
+
77
+ ### Installation
78
+
79
+ ```bash
80
+ pip install fundedness
81
+ ```
82
+
83
+ For development with all extras:
84
+ ```bash
85
+ pip install "fundedness[all]"
86
+ ```
87
+
88
+ ### Basic Usage
89
+
90
+ ```python
91
+ from fundedness import Asset, BalanceSheet, Liability, compute_cefr
92
+ from fundedness.models.assets import AccountType, LiquidityClass, ConcentrationLevel
93
+
94
+ # Define your assets
95
+ assets = [
96
+ Asset(
97
+ name="401(k)",
98
+ value=500_000,
99
+ account_type=AccountType.TAX_DEFERRED,
100
+ liquidity_class=LiquidityClass.RETIREMENT,
101
+ concentration_level=ConcentrationLevel.DIVERSIFIED,
102
+ ),
103
+ Asset(
104
+ name="Roth IRA",
105
+ value=200_000,
106
+ account_type=AccountType.TAX_EXEMPT,
107
+ liquidity_class=LiquidityClass.RETIREMENT,
108
+ concentration_level=ConcentrationLevel.DIVERSIFIED,
109
+ ),
110
+ ]
111
+
112
+ # Define your spending
113
+ liabilities = [
114
+ Liability(name="Living Expenses", annual_amount=50_000, is_essential=True),
115
+ Liability(name="Travel", annual_amount=20_000, is_essential=False),
116
+ ]
117
+
118
+ # Calculate CEFR
119
+ result = compute_cefr(
120
+ balance_sheet=BalanceSheet(assets=assets),
121
+ liabilities=liabilities,
122
+ planning_horizon=30,
123
+ )
124
+
125
+ print(f"CEFR: {result.cefr:.2f}")
126
+ print(f"Funded: {result.is_funded}")
127
+ print(result.get_interpretation())
128
+ ```
129
+
130
+ ## Tutorials
131
+
132
+ - [CEFR Basics](https://colab.research.google.com/github/engineerinvestor/financial-health-calculator/blob/main/examples/01_cefr_basics.ipynb) - Introduction to the CEFR metric
133
+ - [Time Distribution Analysis](https://colab.research.google.com/github/engineerinvestor/financial-health-calculator/blob/main/examples/02_time_distribution.ipynb) - Monte Carlo simulations
134
+ - [Withdrawal Strategy Comparison](https://colab.research.google.com/github/engineerinvestor/financial-health-calculator/blob/main/examples/03_withdrawal_comparison.ipynb) - Compare different approaches
135
+
136
+ ## Running the Apps
137
+
138
+ ### Streamlit Web App
139
+
140
+ ```bash
141
+ streamlit run streamlit_app/app.py
142
+ ```
143
+
144
+ ### FastAPI REST API
145
+
146
+ ```bash
147
+ uvicorn api.main:app --reload
148
+ ```
149
+
150
+ API documentation available at `http://localhost:8000/docs`
151
+
152
+ ## Key Concepts
153
+
154
+ ### CEFR (Certainty-Equivalent Funded Ratio)
155
+
156
+ CEFR measures how well-funded your retirement is after accounting for:
157
+
158
+ - **Tax Haircuts**: What you'll owe when withdrawing from different account types
159
+ - **Liquidity Haircuts**: How easily you can access your assets
160
+ - **Reliability Haircuts**: Risk from concentrated positions
161
+
162
+ **Formula:**
163
+ ```
164
+ CEFR = Σ(Asset × (1-τ) × λ × ρ) / PV(Liabilities)
165
+ ```
166
+
167
+ Where τ = tax rate, λ = liquidity factor, ρ = reliability factor
168
+
169
+ **Interpretation:**
170
+ - CEFR ≥ 2.0: Excellent - Very well-funded
171
+ - CEFR 1.5-2.0: Strong - Well-funded with margin
172
+ - CEFR 1.0-1.5: Adequate - Fully funded
173
+ - CEFR < 1.0: Underfunded - Action needed
174
+
175
+ ### Withdrawal Strategies
176
+
177
+ | Strategy | Description | Best For |
178
+ |----------|-------------|----------|
179
+ | Fixed SWR | 4% of initial portfolio, adjusted for inflation | Predictability |
180
+ | % of Portfolio | Fixed % of current value | Market adaptation |
181
+ | Guardrails | Adjustable with floor/ceiling | Balance |
182
+ | VPW | Age-based variable percentage | Maximizing spending |
183
+ | RMD-Style | IRS distribution table based | Tax efficiency |
184
+ | Merton Optimal | Utility-maximizing spending rate | Optimality |
185
+
186
+ ### Utility Optimization
187
+
188
+ The toolkit includes Merton's optimal consumption and portfolio choice framework, as applied in modern retirement planning research<sup>[1]</sup>:
189
+
190
+ - **Optimal Equity Allocation**: `k* = (μ - r) / (γ × σ²)`
191
+ - **Wealth-Adjusted Allocation**: Reduces equity as wealth approaches subsistence floor
192
+ - **Optimal Spending Rate**: Increases with age as horizon shortens
193
+ - **Expected Lifetime Utility**: Track utility across Monte Carlo paths
194
+
195
+ Key insights from this methodology:
196
+ 1. Optimal spending starts low (~2-3%) and rises with age
197
+ 2. Allocation should decrease as wealth approaches the floor
198
+ 3. Risk aversion (gamma) is the critical input parameter
199
+ 4. The 4% rule is suboptimal from a utility perspective
200
+
201
+ ## Development
202
+
203
+ ### Setup
204
+
205
+ ```bash
206
+ git clone https://github.com/engineerinvestor/financial-health-calculator.git
207
+ cd financial-health-calculator
208
+ pip install -e ".[dev]"
209
+ ```
210
+
211
+ ### Running Tests
212
+
213
+ ```bash
214
+ pytest
215
+ ```
216
+
217
+ ### Code Quality
218
+
219
+ ```bash
220
+ ruff check .
221
+ mypy fundedness
222
+ ```
223
+
224
+ ## Project Structure
225
+
226
+ ```
227
+ financial-health-calculator/
228
+ ├── fundedness/ # Core Python package
229
+ │ ├── models/ # Pydantic data models
230
+ │ ├── viz/ # Plotly visualizations
231
+ │ ├── withdrawals/ # Withdrawal strategies (SWR, guardrails, VPW, Merton)
232
+ │ ├── allocation/ # Asset allocation strategies (constant, glidepath, Merton)
233
+ │ ├── cefr.py # CEFR calculation
234
+ │ ├── simulate.py # Monte Carlo engine with utility tracking
235
+ │ ├── merton.py # Merton optimal formulas
236
+ │ ├── optimize.py # Policy parameter optimization
237
+ │ └── policies.py # Spending/allocation policies
238
+ ├── api/ # FastAPI REST API
239
+ ├── streamlit_app/ # Streamlit web application
240
+ │ └── pages/ # Includes Utility Optimization page
241
+ ├── examples/ # Jupyter notebooks
242
+ └── tests/ # pytest tests
243
+ ```
244
+
245
+ ## Contact
246
+
247
+ - Twitter: [@egr_investor](https://x.com/egr_investor)
248
+ - GitHub: [engineerinvestor](https://github.com/engineerinvestor)
249
+ - Email: egr.investor@gmail.com
250
+
251
+ ## License
252
+
253
+ MIT License
254
+
255
+ ## References
256
+
257
+ 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.
258
+
259
+ 2. Merton, R. C. (1969). Lifetime Portfolio Selection under Uncertainty: The Continuous-Time Case. *The Review of Economics and Statistics*, 51(3), 247-257.
260
+
261
+ ## Citation
262
+
263
+ If you use this package in academic work, please cite:
264
+
265
+ ```bibtex
266
+ @software{fundedness,
267
+ title = {Fundedness: A Python Financial Planning Toolkit},
268
+ author = {Engineer Investor},
269
+ year = {2024},
270
+ url = {https://github.com/engineerinvestor/financial-health-calculator},
271
+ version = {0.2.1}
272
+ }
273
+ ```
274
+
275
+ For the underlying methodology, please also cite:
276
+
277
+ ```bibtex
278
+ @article{merton1969lifetime,
279
+ title = {Lifetime Portfolio Selection under Uncertainty: The Continuous-Time Case},
280
+ author = {Merton, Robert C.},
281
+ journal = {The Review of Economics and Statistics},
282
+ volume = {51},
283
+ number = {3},
284
+ pages = {247--257},
285
+ year = {1969},
286
+ publisher = {MIT Press}
287
+ }
288
+
289
+ @book{haghani2023missing,
290
+ title = {The Missing Billionaires: A Guide to Better Financial Decisions},
291
+ author = {Haghani, Victor and White, James},
292
+ year = {2023},
293
+ publisher = {Wiley}
294
+ }
295
+ ```
296
+
297
+ ## Disclaimer
298
+
299
+ This tool is for educational purposes only and does not constitute financial advice. Consult a qualified financial advisor for personalized recommendations.
@@ -0,0 +1,43 @@
1
+ fundedness/__init__.py,sha256=5rATL7-dfOIzb43-c3oDYImGu70ezYv2ALfbadhyR20,1678
2
+ fundedness/cefr.py,sha256=hCImRrjz-DCPJsuF3HShDZK5tw1vslakh-DrNBHsh2k,7728
3
+ fundedness/liabilities.py,sha256=uKvEV6JQnQdrd7b6VsCc2qf9S2DJdK0XhEX9qwca2Ws,6662
4
+ fundedness/liquidity.py,sha256=ncZF70AfgoVoYZnozpA_CHemfaHmI4KKCe3vITp5ljM,1713
5
+ fundedness/merton.py,sha256=VUKVxkNimoI0gsQJROb1wrO-SW4ubiNvcYDL2aH69AU,9218
6
+ fundedness/optimize.py,sha256=21ksSkNgtDY_UGTub0KRlIvfaFA363csfSfHnLJrmJs,15567
7
+ fundedness/policies.py,sha256=pyIYz86Z3sMYAW2rNhPLnXQ3PQCDCa-oxf9NhWyawy8,5854
8
+ fundedness/risk.py,sha256=Lpls6Q2wVq5SX4p9ZQwCtTM73AcqrGCm3hE2QcgKuq0,2750
9
+ fundedness/simulate.py,sha256=A0_ZScMTF8YJcjVHys_nmxMG4x-c81sU_W8iMApscNE,19678
10
+ fundedness/allocation/__init__.py,sha256=5p85uRFltSfEwXjengr56FNY1s4KvcMMxuH05I_Omfs,677
11
+ fundedness/allocation/base.py,sha256=kDypu2t86fsn2DyL5an1fPjbPbQWNmqydz3axWUgjLI,763
12
+ fundedness/allocation/constant.py,sha256=6QcUJ0aBQcJcRJtOMhs7uUu13wJtgcPU7ToQzQZhcgw,531
13
+ fundedness/allocation/glidepath.py,sha256=-q6Jb5WpRuZjJ68akT5WgeRIx3QSIDtlNih0_Iz-_cc,3440
14
+ fundedness/allocation/merton_optimal.py,sha256=krRd7sKbvXXxfewLJuF9RWbMLYUHbehvdbdYSjwnczk,7702
15
+ fundedness/models/__init__.py,sha256=EyW6tGUI9T6QMbIfzsG3igqg5--DtZHSTAuMX6foOiA,874
16
+ fundedness/models/assets.py,sha256=ZKgxl4YaqdRVfDErL9weRhh4St_azo8ruN4g15T3IsQ,5013
17
+ fundedness/models/household.py,sha256=t64FjvO0uQJemddLtCPpK3NNYdZCXU6KjA1VZshaqEk,4671
18
+ fundedness/models/liabilities.py,sha256=iqGl5RU841k1clGOwnFParUvxzCJclq2JzNJoNPywuo,3416
19
+ fundedness/models/market.py,sha256=c3jskREsB7m_mjzuBwJ7oo6hlvLmR423t0JT8_a50eg,5551
20
+ fundedness/models/simulation.py,sha256=0jtIJWISDL-TlKVjr6KxcRfAj5Mrbp-VNyA4Bu7IUfU,2224
21
+ fundedness/models/tax.py,sha256=0XhoBNZqfRqF1_acakrkYgMS5L6Pknq-TloQQBrFw1U,3859
22
+ fundedness/models/utility.py,sha256=0AoJdccTb2hKBrTz5LExm8SrSsaWhhBf7y2NNaUzWQ0,4678
23
+ fundedness/viz/__init__.py,sha256=Om8qlI13w13MfDmyB_xeR6hgr7LpWX1tjAf_x3eDbEQ,1168
24
+ fundedness/viz/colors.py,sha256=kbYyCLvLARoIAMztHjnJZDxMGF9-an5z4obORa6JFEU,3204
25
+ fundedness/viz/comparison.py,sha256=DoQW6xr0r2ko55qyli4ue8ndj__opun97brbbHSnKVA,8530
26
+ fundedness/viz/fan_chart.py,sha256=GqdrOKdW12K7Y8sFQJ853QbYG3ASxvEzfY9cC-EKK70,6102
27
+ fundedness/viz/histogram.py,sha256=i56g330-S84WxUU8GGya40yNUQbnAI2D0vzUbFy51DI,6784
28
+ fundedness/viz/optimal.py,sha256=w5vI2O-4O6F1Dobsfg55pznlfD100SRnSgZqLIpcT9c,16056
29
+ fundedness/viz/survival.py,sha256=xtaAHkJ3jlTUCYnLrTvwWlOlfLao6NC5cRxT5XKWrxM,6515
30
+ fundedness/viz/tornado.py,sha256=1dZzAfKTDCcyyfbDUBE39f44e6k48yviF8kTRee-pwQ,6684
31
+ fundedness/viz/waterfall.py,sha256=6LD0SbZDUzJrA0Zh1Y1qDx0I4BM5ZN_f2eVCXNK5HRc,5586
32
+ fundedness/withdrawals/__init__.py,sha256=FiXfK7QBzUp4Iwf25VK0jbZyguF8bLlZAWWMjg8tFPo,886
33
+ fundedness/withdrawals/base.py,sha256=WXBuo-tJtp4V2Ottp2PC2YtyK3mGVJ9Cgq21zGUWObg,3472
34
+ fundedness/withdrawals/comparison.py,sha256=eiobGMHmeQpGnr0_HcY_EKrv5_Nu7EaVf5Y9DdDNAyg,7833
35
+ fundedness/withdrawals/fixed_swr.py,sha256=2ZgkQ_xZakpcdZQIop46TAFML7ESz7nyTVdVfI-1Z18,5469
36
+ fundedness/withdrawals/guardrails.py,sha256=rZKVojKbl9LLJLi9LlK1I2JXb537MN_AbZfn4hIU8is,5468
37
+ fundedness/withdrawals/merton_optimal.py,sha256=mSxRAKGx8sr_YdlhQMtIvnojqfuG0MiYtBp18xboLHs,9269
38
+ fundedness/withdrawals/rmd_style.py,sha256=E5FfrUYxFJwULKxzxbtZFLoLspLzUUomTQRUWLGLDpg,6373
39
+ fundedness/withdrawals/vpw.py,sha256=aajHLAkHfsxh33uGRgzv0ozVuZREG-EmARJgWOU6mis,4389
40
+ fundedness-0.2.2.dist-info/METADATA,sha256=Ed_jtXtLDw3oezja6dsiajlQEcG1UjJodESowZcr0Qk,10878
41
+ fundedness-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
42
+ fundedness-0.2.2.dist-info/entry_points.txt,sha256=Oh-Hg08i044YHuSHViCdfoD8CenIGcKrVuUVysvN9sY,51
43
+ fundedness-0.2.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fundedness = fundedness.cli:main