owlplanner 2025.3.15__tar.gz → 2025.3.16__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.
Files changed (108) hide show
  1. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/PKG-INFO +1 -1
  2. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/owl.pdf +0 -0
  3. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/owl.tex +28 -23
  4. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/pyproject.toml +1 -1
  5. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/rates.py +3 -0
  6. owlplanner-2025.3.16/src/owlplanner/version.py +1 -0
  7. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/requirements.txt +1 -1
  8. owlplanner-2025.3.15/src/owlplanner/version.py +0 -1
  9. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/.devcontainer/devcontainer.json +0 -0
  10. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/.flake8 +0 -0
  11. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/.gitattributes +0 -0
  12. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/.github/workflows/github-actions-runtests.yml +0 -0
  13. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/.gitignore +0 -0
  14. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/INSTALL.md +0 -0
  15. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/LICENSE +0 -0
  16. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/Papers/FE00006821-Class-VI-Injection-Permit--Salient-Features-and-Regulatory-Challenges_Final.pdf +0 -0
  17. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/Papers/Kou-OptionPricingDouble-2004.pdf +0 -0
  18. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/Papers/Multi-Period Mean Expected-Shortfall Strategies Cut Your Losses and Ride Your Gains .pdf +0 -0
  19. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/Papers/Optimal Asset Allocation for Retirement Saving Deterministic Vs. Time Consistent Adaptive Strategies.pdf +0 -0
  20. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/Papers/Rule-based_strategies_for_dynamic_life_cycle_inves.pdf +0 -0
  21. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/Papers/s10436-006-0062-y.pdf +0 -0
  22. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/README.md +0 -0
  23. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/USER_GUIDE.md +0 -0
  24. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docker/Dockerfile +0 -0
  25. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docker/README.md +0 -0
  26. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docker/docker-compose.yml +0 -0
  27. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docker/fastentrypoint.sh +0 -0
  28. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/AD-taxDef.png +0 -0
  29. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/AD-taxFree.png +0 -0
  30. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/AD-taxable.png +0 -0
  31. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/Hist_Bequest.png +0 -0
  32. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/Hist_Spending.png +0 -0
  33. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/MC-tutorial2a.png +0 -0
  34. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/MC-tutorial2b.png +0 -0
  35. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/OwlUI.png +0 -0
  36. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/allocations.png +0 -0
  37. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/owl.png +0 -0
  38. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/profile.png +0 -0
  39. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/ratesCorrelations.png +0 -0
  40. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/ratesPlot.png +0 -0
  41. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/savingsPlot.png +0 -0
  42. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/sourcesPlot.png +0 -0
  43. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/spendingPlot.png +0 -0
  44. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/taxIncomePlot.png +0 -0
  45. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/docs/images/taxesPlot.png +0 -0
  46. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/case_jack+jill.toml +0 -0
  47. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/case_joe.toml +0 -0
  48. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/case_john+sally.toml +0 -0
  49. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/case_jon+jane.toml +0 -0
  50. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/case_kim+sam-bequest.toml +0 -0
  51. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/case_kim+sam-spending.toml +0 -0
  52. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/jack+jill.xlsx +0 -0
  53. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/joe.xlsx +0 -0
  54. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/john+sally.xlsx +0 -0
  55. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/jon+jane.xlsx +0 -0
  56. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/examples/template.xlsx +0 -0
  57. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/notebooks/john+sally.ipynb +0 -0
  58. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/notebooks/kim+sam.ipynb +0 -0
  59. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/notebooks/template.ipynb +0 -0
  60. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/notebooks/tutorial_1.ipynb +0 -0
  61. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/notebooks/tutorial_2.ipynb +0 -0
  62. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/notebooks/tutorial_3.ipynb +0 -0
  63. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/owlplanner.cmd +0 -0
  64. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/owlplanner.sh +0 -0
  65. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/requirements.txt +0 -0
  66. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/__init__.py +0 -0
  67. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/abcapi.py +0 -0
  68. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/config.py +0 -0
  69. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/data/__init__.py +0 -0
  70. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/data/rates.csv +0 -0
  71. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/logging.py +0 -0
  72. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/plan.py +0 -0
  73. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/progress.py +0 -0
  74. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/tax2025.py +0 -0
  75. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/timelists.py +0 -0
  76. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/src/owlplanner/utils.py +0 -0
  77. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/tests/test_logger.py +0 -0
  78. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/tests/test_regressions.py +0 -0
  79. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/tests/test_repro.py +0 -0
  80. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/tests/test_toml_cases.py +0 -0
  81. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/tests/test_units.py +0 -0
  82. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ttt.py +0 -0
  83. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/About_Owl.py +0 -0
  84. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Asset_Allocation.py +0 -0
  85. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Create_Case.py +0 -0
  86. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Current_Assets.py +0 -0
  87. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Documentation.py +0 -0
  88. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Fixed_Income.py +0 -0
  89. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Graphs.py +0 -0
  90. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Historical_Range.py +0 -0
  91. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Logs.py +0 -0
  92. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Monte_Carlo.py +0 -0
  93. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Optimization_Parameters.py +0 -0
  94. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Output_Files.py +0 -0
  95. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Quick_Start.py +0 -0
  96. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/README.md +0 -0
  97. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Rates_Selection.py +0 -0
  98. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Settings.py +0 -0
  99. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Wages_And_Contributions.py +0 -0
  100. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/Worksheets.py +0 -0
  101. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/main+fonts.py +0 -0
  102. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/main.py +0 -0
  103. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/owlbridge.py +0 -0
  104. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/plots.py +0 -0
  105. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/progress.py +0 -0
  106. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/sskeys.py +0 -0
  107. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/style.css +0 -0
  108. {owlplanner-2025.3.15 → owlplanner-2025.3.16}/ui/tomlexamples.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: owlplanner
3
- Version: 2025.3.15
3
+ Version: 2025.3.16
4
4
  Summary: Owl: Retirement planner with great wisdom
5
5
  Project-URL: HomePage, https://github.com/mdlacasse/owl
6
6
  Project-URL: Repository, https://github.com/mdlacasse/owl
@@ -32,6 +32,7 @@
32
32
  \begin{document}
33
33
  \title{Formulation of the optimization model in Owl}
34
34
  \author{Martin-D. Lacasse}
35
+ \date{March 14, 2025}
35
36
  \maketitle
36
37
  \thispagestyle{fancy}
37
38
  \fancyfoot[R]{\copyright\ 2024 - Martin-D. Lacasse}
@@ -112,8 +113,8 @@ to take only non-negative values ($\ge 0$ inequality).
112
113
  \item [$e_{n}$]
113
114
  Standard exemption for year $n$. This is a variable as the taxable income can
114
115
  sometimes be less that the standard exemption $\bar{\sigma}_n$, leading to a
115
- negative taxable income if the inflation adjusted standard deviation is simply subtracted
116
- from gross taxable income $G_n$.
116
+ negative taxable income if the inflation-adjusted standard exemption is simply subtracted
117
+ from the gross taxable income $G_n$.
117
118
  \item [$f_{t n}$]
118
119
  Fraction of tax bracket $t$ filled, so that taxable ordinary income $G_n$ can be expressed as
119
120
  \begin{eqnarray}
@@ -141,19 +142,13 @@ For more easily distinguishing parameters from variables, all parameters will be
141
142
  or using caligraphic fonts.
142
143
  Parameter values are either set by the user, historical data, or by the tax code.
143
144
  \begin{description}[leftmargin=4em,style=multiline]
144
- \item [$\beta{ij}$]
145
+ \item [$\beta_{ij}$]
145
146
  Initial balances in savings accounts. These amounts are used to initialize $b_{ij0}$.
146
147
  \item [$\tau_{kn}$]
147
148
  Annual rate of return for asset class $k$ in year $n$.
148
149
  A time series of annual return rates for each class of asset.
149
150
  Here, inflation and the rate of return of $(k=3)$ cash are assumed to be the same.
150
- In other words, investing in cash yields constant dollars (just inflation).
151
- \item[$\mathcal{T}_{ijn}$]
152
- When the allocation ratios $\alpha_{ijkn}$ are prescribed,
153
- it is more convenient to express the return rates as
154
- \begin{equation}
155
- \mathcal{T}_{ijn} = \sum_k \alpha_{ijkn} \tau_{kn}.
156
- \end{equation}
151
+ In other words, investing in cash yields constant dollars (return just matches inflation).
157
152
  \item [$\gamma_n$]
158
153
  Cumulative inflation at the beginning of year $n$ computed as the product
159
154
  \begin{equation}
@@ -172,12 +167,12 @@ Parameter values are either set by the user, historical data, or by the tax code
172
167
  and can be modified for additional exemptions after 65 of age, for example.
173
168
  It is a simple time series
174
169
  which can include any foreseeable changes in the tax code, or change in filing status due to the
175
- passing of one spouse for $n\ge n_d$. The value of $\bar{\sigma}_n$ is an upper bound for $e_n$.
170
+ passing of one spouse for $n\ge n_d$. The value of $\bar{\sigma}_n$ is an upper bound for variable $e_n$.
176
171
  \item [$\xi_{n}$]
177
- Spending profile. This is a time series that multiplies the desired net spending amount.
172
+ Spending profile. This is a time series that multiplies a basis for the desired net spending amount.
178
173
  It is $\xi_n =1$ for
179
174
  a flat profile, or can be a {\em smile} profile allowing for more money at the start
180
- of retirement. Parameter
175
+ of retirement and modulating it over retirement. Parameter
181
176
  $\xi_n$ can also contain spending adjustments typically made at the passing of one spouse.
182
177
  The {\em smile} can be implemented using a cosine superimposed over a gentle linear increase
183
178
  such as in
@@ -186,14 +181,14 @@ Parameter values are either set by the user, historical data, or by the tax code
186
181
  \end{equation}
187
182
  and then normalized by factor $N_n/(\sum_n \xi_n )$ to be sum-neutral with respect to a flat profile.
188
183
  Values of $a_1 = 15\%$ and $a_2=12\%$ provide curves that are similar to realistic
189
- spending profiles reported in the literature. See Fig.~\ref{Fig:profile} for an example.
184
+ spending profiles reported in the literature. See Fig.~\ref{Fig:profile} for an example.
190
185
  At the passing of one spouse, both profiles are reduced by a factor $\chi$ for $n \ge n_d$,
191
186
  and the normalizing factor needs to be adjusted accordingly.
192
- \begin{figure}[t]
193
- \includegraphics{profile.png}
194
- \caption{\small Example of a spending profile with 15\% cosine factor and a 12\% linear
195
- profile. \label{Fig:profile}}
196
- \end{figure}
187
+ \begin{figure}[t]
188
+ \includegraphics{profile.png}
189
+ \caption{\small Example of a spending profile with 15\% cosine factor and a 12\% linear
190
+ profile. \label{Fig:profile}}
191
+ \end{figure}
197
192
  \item [$\chi$]
198
193
  Factor to reduce spending profile after the passing of one spouse. It is typically
199
194
  assumed to be 0.6.
@@ -230,7 +225,8 @@ Parameter values are either set by the user, historical data, or by the tax code
230
225
  individuals and accounts as $\alpha_{kn}$, for example.
231
226
  When specified by the user, allocation ratios typically involve two values, one at the
232
227
  beginning of the plan $\alpha_{ijk0}$ and the other at the end
233
- $\alpha_{ijkN_{n-1}}$. Then, intermediate values are interpolated either using
228
+ $\alpha_{ijkN_{n-1}}$, or $\alpha_{ijkn_d}$ for a spouse passing before the other.
229
+ Then, intermediate values are interpolated either using
234
230
  a linear relation,
235
231
  \begin{equation}
236
232
  \alpha_{ijkn} = a + \frac{n}{N_n - 1} (b - a),
@@ -280,6 +276,13 @@ or an s-curve as in
280
276
  \end{eqnarray}
281
277
  depending on the scheme selected.
282
278
 
279
+ \item[$\mathcal{T}_{ijn}$]
280
+ When the allocation ratios $\alpha_{ijkn}$ are prescribed,
281
+ it is more convenient to express the return rates as
282
+ \begin{equation}
283
+ \mathcal{T}_{ijn} = \sum_k \alpha_{ijkn} \tau_{kn}.
284
+ \end{equation}
285
+
283
286
  \item [$\Lambda^\pm_{in}$]
284
287
  Big-ticket item requested by individual $i$ in year $n$.
285
288
  These are large expenses or influx of money
@@ -287,8 +290,8 @@ or an s-curve as in
287
290
  (e.g., sell a house, inheritance) or negative (e.g., buy a house, large gifts).
288
291
  \item [$\pi_{in}$]
289
292
  Sum of pension benefits for individual $i$ in year $n$. These amounts are typically
290
- specified along with the ages at which these benefits begin. Pensions
291
- can optionally be indexed for inflation.
293
+ specified along with the ages at which these benefits begin.
294
+ Pensions can optionally be indexed for inflation.
292
295
  \item [$\zeta_{in}$]
293
296
  Social security benefits for individual $i$ in year $n$. Starting age and the passing
294
297
  of one individual for spouses will determine the time series. $\bar{\zeta}_{in}$ is
@@ -344,7 +347,8 @@ or an s-curve as in
344
347
  depends on the modified adjusted gross income (MAGI) from 2 years earlier. For the
345
348
  MAGI, we simply use $G_{n-2} + e_{n-2}$ (i.e., gross taxable income
346
349
  plus standard deduction (exemption) from 2 years ago) and ignore the additional IRS
347
- rules around tax-free interests which are insignificant in most cases.
350
+ rules around tax-free interests which are insignificant in most cases. If the plan
351
+ has individuals above 63 years old, values of MAGI for previous years are requested from the user.
348
352
 
349
353
  There are $q=5$ levels
350
354
  of step adjustments adjusted for inflation,
@@ -404,6 +408,7 @@ All intermediate variables are in uppercase letters.
404
408
  [(1-\delta(k, 0))(b_{i0n} - w_{i0n} + d_{in} + .5\kappa_{i0n})\alpha_{i0kn}\tau_{kn}]
405
409
  \end{eqnarray}
406
410
  Social security is indexed for inflation and is assumed to be taxed at 85\%.
411
+ Pensions can optionally be indexed for inflation.
407
412
  We use a discrete Kronecker $\delta$ function for selecting gains from non-equity assets in
408
413
  taxable accounts. These gains are all taxed as ordinary income. Here, we assumed that
409
414
  withdrawals and deposits in the taxable account are taking place at the beginning of the year, while
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "owlplanner"
7
- version = "2025.03.15"
7
+ version = "2025.03.16"
8
8
  authors = [
9
9
  { name="Martin-D. Lacasse", email="martin.d.lacasse@gmail.com" },
10
10
  ]
@@ -110,6 +110,9 @@ def getRatesDistributions(frm, to, mylog=None):
110
110
  # Build correlation matrix by dividing by the stdev for each column and row.
111
111
  corr = covar / stdev[:, None]
112
112
  corr = corr.T / stdev[:, None]
113
+ # Fold round-off errors in proper bounds.
114
+ corr[corr > 1] = 1
115
+ corr[corr < -1] = -1
113
116
  mylog.print("correlation matrix: \n\t\t%s" % str(corr).replace("\n", "\n\t\t"))
114
117
 
115
118
  return means, stdev, corr, covar
@@ -0,0 +1 @@
1
+ __version__ = "2025.03.16"
@@ -7,4 +7,4 @@ scipy
7
7
  streamlit
8
8
  toml
9
9
  # --extra-index-url https://test.pypi.org/simple
10
- owlplanner >= 2025.03.15
10
+ owlplanner >= 2025.03.16
@@ -1 +0,0 @@
1
- __version__ = "2025.03.15"
File without changes
File without changes
File without changes
File without changes