owlplanner 2025.2.2__tar.gz → 2025.2.4__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.
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/PKG-INFO +1 -1
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/notebooks/template.ipynb +2 -2
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/notebooks/tutorial_1.ipynb +2 -2
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/pyproject.toml +1 -1
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/plan.py +2 -4
- owlplanner-2025.2.4/src/owlplanner/version.py +1 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Case_Results.py +1 -1
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Documentation.py +21 -21
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Optimization_Parameters.py +2 -2
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Quick_Start.py +2 -1
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Wages_And_Contributions.py +1 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/requirements.txt +1 -1
- owlplanner-2025.2.2/src/owlplanner/version.py +0 -1
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/.devcontainer/devcontainer.json +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/.flake8 +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/.github/workflows/github-actions-runtests.yml +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/.gitignore +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/INSTALL.md +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/LICENSE +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/README.md +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/AD-taxDef.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/AD-taxFree.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/AD-taxable.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/Hist_Bequest.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/Hist_Spending.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/MC-tutorial2a.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/MC-tutorial2b.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/OwlUI.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/allocations.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/owl.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/profile.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/ratesCorrelations.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/ratesPlot.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/savingsPlot.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/sourcesPlot.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/spendingPlot.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/taxIncomePlot.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/images/taxesPlot.png +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/owl.pdf +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/docs/owl.tex +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/case_jack+jill.toml +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/case_joe.toml +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/case_john+sally.toml +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/case_kim+sam-bequest.toml +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/case_kim+sam-spending.toml +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/jack+jill.xlsx +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/joe.xlsx +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/john+sally.xlsx +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/examples/template.xlsx +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/notebooks/john+sally.ipynb +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/notebooks/kim+sam.ipynb +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/notebooks/tutorial_2.ipynb +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/notebooks/tutorial_3.ipynb +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/owlplanner.cmd +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/requirements.txt +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/__init__.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/abcapi.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/config.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/data/__init__.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/data/rates.csv +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/logging.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/progress.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/rates.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/tax2025.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/timelists.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/src/owlplanner/utils.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/tests/test_logger.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/tests/test_regressions.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/tests/test_repro.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/tests/test_toml_cases.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/tests/test_units.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/About_Owl.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Asset_Allocation.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Assets.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Basic_Info.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Case_Summary.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Case_Worksheets.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Fixed_Income.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Historical_Range.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Logs.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Monte_Carlo.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/README.md +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Rates_Selection.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/Settings.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/main.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/owlbridge.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/plots.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/progress.py +0 -0
- {owlplanner-2025.2.2 → owlplanner-2025.2.4}/ui/sskeys.py +0 -0
|
@@ -211,7 +211,7 @@
|
|
|
211
211
|
"The most manageable part of retirement planning is the control one has over work income, contributions to savings accounts, Roth conversions, and other big spending items in the near- and mid-term future.\n",
|
|
212
212
|
"In order to execute a realization, one must provide an earning, saving, and Roth conversion plan. This is done through providing an Excel workbook with one spreadsheet (tab) per spouse with the following information:\n",
|
|
213
213
|
"\n",
|
|
214
|
-
"|year|anticipated wages|
|
|
214
|
+
"|year|anticipated wages|taxable ctrb| 401k ctrb | Roth 401k ctrb | IRA ctrb | Roth IRA ctrb | Roth conv | big-ticket items|\n",
|
|
215
215
|
"|--|--|--|--|--|--|--|--|--|\n",
|
|
216
216
|
"|2024 | | | | | | | | |\n",
|
|
217
217
|
"|2025 | | | | | | | | |\n",
|
|
@@ -224,7 +224,7 @@
|
|
|
224
224
|
"\n",
|
|
225
225
|
"Contributions to your savings accounts are marked as *ctrb*. Contributions to your 401k must also include your employer's contributions, if any. As this file is in Excel, one can use the native calculator to enter a percentage of the anticipated wages for contributions as this can sometimes be easier. Considering a specific example, assume that Jack earns 100k\\\\$ and contributes 5% to his 401k which his employer matches at up to 4%, then Jack's anticipated wages will be $(1-.05)*100000 = 95000$ and his 401k contributions will be $.09/(1 - .05) * 95000 = 9000 $. \n",
|
|
226
226
|
"\n",
|
|
227
|
-
"Roth conversion are specified in the column marked *Roth
|
|
227
|
+
"Roth conversion are specified in the column marked *Roth conv*. Roth conversion are typically performed in the years when the income is lower (and therefore lower tax rates), typically in the bridge years between having a full-time regular salary and collecting social security. This column is provided to override the Roth conversion optimization in Owl. When the solver is given the option `maxConversion='file'`, then these values will be used and no optimization over Roth conversions will be performed. This column is provided for flexibility and allowing comparisons.\n",
|
|
228
228
|
"\n",
|
|
229
229
|
"Finally, *big-ticket items* are used for accounting for the sale or purchase of a house, or any other major expense or money that you would give or receive (e.g., inheritance, or large gifts to or from you). Therefore, the sign (+/-) of entries in this column is important. Positive numbers will be considered in the cash flow for the year and surplus will be deposited in taxable savings accounts. Negative numbers will generate withdrawals and distributions from retirement accounts. This is the only column that can contain negative numbers: all other column entries should be positive.\n",
|
|
230
230
|
"\n",
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
"The most manageable part of retirement planning is the control one has over work income, contributions to savings accounts, Roth conversions, and other big spending items in the near- and mid-term future.\n",
|
|
209
209
|
"In order to execute a realization, one must provide an earning, saving, and optionally a Roth conversion plan for overriding the optimizer. This is done through providing an Excel workbook with one spreadsheet (tab) per spouse with the following information:\n",
|
|
210
210
|
"\n",
|
|
211
|
-
"|year|anticipated wages|ctrb
|
|
211
|
+
"|year|anticipated wages|taxable ctrb | 401k ctrb | Roth 401k ctrb | IRA ctrb | Roth IRA ctrb | Roth conv | big-ticket items|\n",
|
|
212
212
|
"|--|--|--|--|--|--|--|--|--|\n",
|
|
213
213
|
"|2024 | | | | | | | | |\n",
|
|
214
214
|
"|2025 | | | | | | | | |\n",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
"\n",
|
|
222
222
|
"Contributions to your savings accounts are marked as *ctrb*. We use 401k as a term which includes contributions to 403b as well. Contributions to your 401k/403b must also include your employer's contributions, if any. As this file is in Excel, one can use the native calculator to enter a percentage of the anticipated wages for contributions as this can sometimes be easier. Considering a specific example, assume that Jack earns 100k\\\\$ and contributes 5% to his 401k which his employer matches at up to 4%, then Jack's anticipated wages will be $(1-.05)*100000 = 95000$ and his 401k contributions will be $.09/(1 - .05) * 95000 = 9000 $. The reason for using $95000$ in the last equation allows for making cross-reference between the cells, as the number 100k\\\\$ will not appear directly. Another approach could be to use an additional column with for the total salary and derive numbers from there.\n",
|
|
223
223
|
"\n",
|
|
224
|
-
"Roth conversion are specified in the column marked *Roth
|
|
224
|
+
"Roth conversion are specified in the column marked *Roth conv*. Roth conversion are typically performed in the years when the income is lower (and therefore lower tax rates), typically in the bridge years between having a full-time regular salary and collecting social security. This column is provided to override the Roth conversion optimization in Owl. When the solver is given the option `maxConversion='file'`, then these values will be used and no optimization over Roth conversions will be performed. This column is provided for flexibility and allowing comparisons between an optimized solution and your best guess.\n",
|
|
225
225
|
"\n",
|
|
226
226
|
"Finally, *big-ticket items* are used for accounting for the sale or purchase of a house, or any other major expense or money that you would give or receive (e.g., inheritance, or large gifts to or from you). Therefore, the sign (+/-) of entries in this column is important. Positive numbers will be considered in the cash flow for the year and surplus, if any, will be deposited in the taxable savings accounts. Negative numbers will potentially generate additional withdrawals and distributions from retirement accounts. This is the only column that can contain negative numbers: all other column entries should be positive.\n",
|
|
227
227
|
"\n",
|
|
@@ -898,12 +898,9 @@ class Plan(object):
|
|
|
898
898
|
self.myRothX_in[i, :h] = self.timeLists[iname]['Roth conv'].iloc[:h]
|
|
899
899
|
self.Lambda_in[i, :h] = self.timeLists[iname]['big-ticket items'].iloc[:h]
|
|
900
900
|
|
|
901
|
-
# In 1st year, reduce wages and
|
|
901
|
+
# In 1st year, reduce wages and contributions depending on starting date.
|
|
902
902
|
self.omega_in[:, 0] *= self.yearFracLeft
|
|
903
903
|
self.kappa_ijn[:, :, 0] *= self.yearFracLeft
|
|
904
|
-
if self.yearFracLeft != 1:
|
|
905
|
-
self.Lambda_in[:, 0] = 0
|
|
906
|
-
self.myRothX_in[:, 0] = 0
|
|
907
904
|
|
|
908
905
|
self.caseStatus = 'modified'
|
|
909
906
|
|
|
@@ -2781,6 +2778,7 @@ class Plan(object):
|
|
|
2781
2778
|
self.b_ijn[i][2][-1],
|
|
2782
2779
|
0,
|
|
2783
2780
|
0,
|
|
2781
|
+
0,
|
|
2784
2782
|
]
|
|
2785
2783
|
ws.append(lastRow)
|
|
2786
2784
|
_formatSpreadsheet(ws, 'currency')
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2025.02.04"
|
|
@@ -10,7 +10,7 @@ kz.caseHeader("Case Results")
|
|
|
10
10
|
if ret is None or kz.caseHasNoPlan():
|
|
11
11
|
st.info('Case(s) must be first created before running this page.')
|
|
12
12
|
else:
|
|
13
|
-
st.write("Optimize a single scenario based on the parameters selected in the
|
|
13
|
+
st.write("Optimize a single scenario based on the parameters selected in the **Case setup** section.")
|
|
14
14
|
col1, col2 = st.columns(2, gap='large', vertical_alignment='bottom')
|
|
15
15
|
with col1:
|
|
16
16
|
choices = ['nominal', 'today']
|
|
@@ -21,7 +21,7 @@ It provides different realizations of a financial strategy through the rigorous
|
|
|
21
21
|
mathematical optimization of relevant decision variables. Using a linear programming approach,
|
|
22
22
|
two different objectives can currently be optimized: either
|
|
23
23
|
maximize the net spending amount under the constraint of a desired bequest,
|
|
24
|
-
or maximize an after-tax bequest under the
|
|
24
|
+
or maximize an after-tax bequest under the constraint of a desired net spending amount.
|
|
25
25
|
In each case, Roth conversions are optimized to reduce the tax burden,
|
|
26
26
|
while federal income tax and Medicare premiums (including IRMAA) are calculated.
|
|
27
27
|
A full description of the package can be found on the GitHub
|
|
@@ -36,11 +36,11 @@ Typically, pages would be accessed in order, starting from the top.
|
|
|
36
36
|
The `Select case` selection box at the bottom of the margin allows to select an existing case
|
|
37
37
|
or create a new one from scratch, or from a *case* parameter file, which
|
|
38
38
|
would then populate all parameter values.
|
|
39
|
-
This box is present in all pages except those in the
|
|
39
|
+
This box is present in all pages except those in the **Resources** section
|
|
40
40
|
and allows to compare different scenarios.
|
|
41
41
|
|
|
42
42
|
There are four sections in the user interface:
|
|
43
|
-
|
|
43
|
+
**Case Setup**, **Single Scenario**, **Multiple Scenarios**, and **Resources**.
|
|
44
44
|
|
|
45
45
|
-------------------------------------------------
|
|
46
46
|
### :orange[Case Setup]
|
|
@@ -58,7 +58,7 @@ and life expectancies are required. A starting date for the plan determines when
|
|
|
58
58
|
starts in the first year. Plan still ends at the end of the year when all individuals
|
|
59
59
|
have passed according to the specified life expectancies.
|
|
60
60
|
|
|
61
|
-
When duplicating a scenario, make sure to visit all pages in the
|
|
61
|
+
When duplicating a scenario, make sure to visit all pages in the **Case Setup** section
|
|
62
62
|
and verify that all parameters are as intended.
|
|
63
63
|
|
|
64
64
|
##### Initializing the life parameters for the realization
|
|
@@ -111,9 +111,9 @@ of binary variables which involve more complex algorithms.
|
|
|
111
111
|
In some situations, transfers from tax-deferred savings accounts to taxable
|
|
112
112
|
savings accounts, through surpluses and deposits, can be part of the optimal solution.
|
|
113
113
|
|
|
114
|
-
Setting a surplus fraction that deposits all surpluses in the survivor's account
|
|
115
|
-
can lead to slow convergence. This is especially noticeable when solving with
|
|
116
|
-
varying rates
|
|
114
|
+
Setting a surplus fraction that deposits some or all surpluses in the survivor's account
|
|
115
|
+
can sometimes lead to slow convergence. This is especially noticeable when solving with
|
|
116
|
+
varying rates and not so common when using fixed rates.
|
|
117
117
|
This is due to the triggering of binary variables which add
|
|
118
118
|
considerable computing effort in solving the problem.
|
|
119
119
|
When using varying rates, it is recommended to set surpluses to be
|
|
@@ -178,7 +178,7 @@ withdrawals and distributions from retirement accounts. This is the only column
|
|
|
178
178
|
negative numbers: all other column entries should be positive.
|
|
179
179
|
|
|
180
180
|
When loading an Excel workbook, each individual in the plan must have an associated sheet
|
|
181
|
-
for reporting yearly
|
|
181
|
+
for reporting yearly transactions affecting the plan. The association is made by having
|
|
182
182
|
the individual's name as the sheet name in the workbook.
|
|
183
183
|
Therefore, if preparing your own case using a template, you will need to rename the tabs in the file to
|
|
184
184
|
match the names used when creating the plan
|
|
@@ -207,7 +207,7 @@ There are two major types of rates:
|
|
|
207
207
|
- *user* - rates are provided by the user
|
|
208
208
|
- *Varying rates* - changing from year to year
|
|
209
209
|
- *historical* - using a rate sequence which happened in the past
|
|
210
|
-
- *histochastic* - using stochastic rates derived from statistics of historical rates
|
|
210
|
+
- *histochastic* - using stochastic rates derived from statistics over a time range of historical rates
|
|
211
211
|
- *stochastic* - using stochastic rates created from statistical parameters specified by the user.
|
|
212
212
|
|
|
213
213
|
These rates are the annual rates of return for each of the assets considered. The types of asset are described
|
|
@@ -231,24 +231,24 @@ to a *final* allocation ratio at the passing of the individual.
|
|
|
231
231
|
It is assumed that the accounts are regularly
|
|
232
232
|
rebalanced to maintain the prescribed allocation ratios.
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
A gliding function (either *linear* or an *s-curve*) interpolates the values
|
|
235
235
|
of the allocation ratios from the *initial* values to the *final* values as the plan progresses in time.
|
|
236
236
|
When an *s-curve* is selected, two additional parameters controlling the shape of the transition
|
|
237
237
|
will appear, one for the timing of the inflection point measured in years from now,
|
|
238
238
|
and the other for the width of the transition, measured in +/- years from the inflection point.
|
|
239
239
|
|
|
240
240
|
### Optimization Parameters
|
|
241
|
-
This page allows you to select the
|
|
241
|
+
This page allows you to select the objective to optimize.
|
|
242
242
|
One can choose between maximizing the net spending amount subject to the constraint
|
|
243
243
|
of a desired bequest, or maximizing a bequest, subject to the constraint of providing
|
|
244
244
|
a desired net spending amount.
|
|
245
245
|
As one of the two choices (net spending or bequest) is selected as the value to maximize,
|
|
246
246
|
the other becomes a constraint to obey.
|
|
247
247
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
is toggled, Roth conversions will not be optimized, but will rather be performed according to
|
|
251
|
-
the
|
|
248
|
+
The maximum amount for Roth conversions and who can execute them is configurable.
|
|
249
|
+
If a *Wages and Contributions* file has been uploaded and the `Convert from contributions file`
|
|
250
|
+
button is toggled, Roth conversions will not be optimized, but will rather be performed according to
|
|
251
|
+
the `Roth conv` column on the
|
|
252
252
|
[Wages and Contributions](#wages-and-contributions) page.
|
|
253
253
|
|
|
254
254
|
Calculations of Medicare and IRMAA can be turned on or off. This will typically speed up
|
|
@@ -257,7 +257,7 @@ If the age of individuals makes them eligible for Medicare within the next two y
|
|
|
257
257
|
additional cells will appear for entering the Modified Adjusted Gross Income (MAGI) for past years.
|
|
258
258
|
These numbers are needed to calculate the Income-Related Monthly Adjusted Amounts (IRMAA).
|
|
259
259
|
|
|
260
|
-
The time profile
|
|
260
|
+
The time profile modulating the net spending amount
|
|
261
261
|
can be selected to either be *flat* or follow a *smile* shape.
|
|
262
262
|
The smile shape has three configurable parameters: a *dip* percentage
|
|
263
263
|
a linear *increase*, or *decrease if negative, over the time period (apart from inflation),
|
|
@@ -265,9 +265,9 @@ and a time delay, in years from today, before the non-flat behavior starts to ac
|
|
|
265
265
|
Values default to 15%, 12%, and 0 year respectively, but they are fully configurable
|
|
266
266
|
for experimentation and to fit your anticipated lifestyle.
|
|
267
267
|
|
|
268
|
-
For married couples,
|
|
268
|
+
For married couples, the survivor's
|
|
269
269
|
net spending percentage is also configurable. A value of 60% is typically used.
|
|
270
|
-
The selected profile
|
|
270
|
+
The selected profile multiplies
|
|
271
271
|
the net spending *basis* which sets the resulting spending
|
|
272
272
|
amounts over the duration of the plan.
|
|
273
273
|
Notice that *smile* curves are re-scaled to have the same total spending as flat curves:
|
|
@@ -282,16 +282,16 @@ than on January 1$^{st}$, the value of the first year will be reduced accordingl
|
|
|
282
282
|
This page allows to run a single scenario based on the selections made
|
|
283
283
|
in the [Case Setup](#case-setup) section.
|
|
284
284
|
This simulation uses a single instance of a series of rates, either fixed or varying,
|
|
285
|
-
as
|
|
285
|
+
as selected in the **Case Setup** section.
|
|
286
286
|
The outcome is optimized according to the chosen parameters: either maximize the
|
|
287
287
|
net spending, of maximize the bequest under the constraint of a net spending amount.
|
|
288
288
|
If `Convert from contributions file` is not toggled on,
|
|
289
|
-
Roth conversions are optimized for maximizing the selected objective function.
|
|
289
|
+
Roth conversions are optimized for reducing taxes and maximizing the selected objective function.
|
|
290
290
|
Various plots show the results, which can be displayed in today's \\$ or
|
|
291
291
|
in nominal value.
|
|
292
292
|
|
|
293
293
|
When a case has run successfully, different graphs will show the time evolution
|
|
294
|
-
of different
|
|
294
|
+
of different quantities over the duration of the plan. Below
|
|
295
295
|
these graphs, two additional buttons will appear. The
|
|
296
296
|
`Download case file...` button allows to save all the parameters used to generate the
|
|
297
297
|
outcome of this case to a *case* file.
|
|
@@ -4,8 +4,8 @@ import sskeys as kz
|
|
|
4
4
|
import owlbridge as owb
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
profileChoices = ['
|
|
8
|
-
kz.initKey('spendingProfile', profileChoices[
|
|
7
|
+
profileChoices = ['flat', 'smile']
|
|
8
|
+
kz.initKey('spendingProfile', profileChoices[1])
|
|
9
9
|
kz.initKey('survivor', 60)
|
|
10
10
|
kz.initKey('smileDip', 15)
|
|
11
11
|
kz.initKey('smileIncrease', 12)
|
|
@@ -25,7 +25,8 @@ This file is in Excel or LibreOffice format, and has one tab per individual in t
|
|
|
25
25
|
|
|
26
26
|
With these two files, a scenario can be created and solved in only a few steps. We will use the case
|
|
27
27
|
of Jack and Jill provided here as an example:
|
|
28
|
-
1) Download these two files from the GitHub repository
|
|
28
|
+
1) Download these two files from the GitHub repository
|
|
29
|
+
(right-click on the link and select `Save link as...`):
|
|
29
30
|
- Case parameter file named
|
|
30
31
|
[case_jack+jill.toml](https://raw.github.com/mdlacasse/Owl/main/examples/case_jack+jill.toml)
|
|
31
32
|
in editable *toml* format.
|
|
@@ -51,6 +51,7 @@ else:
|
|
|
51
51
|
newdf = st.data_editor(kz.getKey('timeList'+str(i)), column_config=colfor,
|
|
52
52
|
hide_index=True, key=kz.currentCaseName()+'_wages'+str(i))
|
|
53
53
|
st.caption('Values are in nominal $.')
|
|
54
|
+
newdf.fillna(0, inplace=True)
|
|
54
55
|
kz.storeKey('_timeList'+str(i), newdf)
|
|
55
56
|
|
|
56
57
|
st.button('Reset to zero', help='Reset all values to zero.', on_click=resetTimeLists)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2025.02.02"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|