owlplanner 2025.4.1__py3-none-any.whl → 2025.4.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.
- owlplanner/plan.py +30 -28
- owlplanner/version.py +1 -1
- {owlplanner-2025.4.1.dist-info → owlplanner-2025.4.2.dist-info}/METADATA +1 -1
- {owlplanner-2025.4.1.dist-info → owlplanner-2025.4.2.dist-info}/RECORD +6 -6
- {owlplanner-2025.4.1.dist-info → owlplanner-2025.4.2.dist-info}/WHEEL +0 -0
- {owlplanner-2025.4.1.dist-info → owlplanner-2025.4.2.dist-info}/licenses/LICENSE +0 -0
owlplanner/plan.py
CHANGED
|
@@ -1122,16 +1122,17 @@ class Plan(object):
|
|
|
1122
1122
|
B.set0_Ub(_q1(Ce, n, Nn), self.sigmaBar_n[n])
|
|
1123
1123
|
|
|
1124
1124
|
# Roth conversions equalities/inequalities.
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1125
|
+
# This condition supercedes everything else.
|
|
1126
|
+
if "maxRothConversion" in options and options["maxRothConversion"] == "file":
|
|
1127
|
+
# self.mylog.vprint(f"Fixing Roth conversions to those from file {self.timeListsFileName}.")
|
|
1128
|
+
for i in range(Ni):
|
|
1129
|
+
for n in range(self.horizons[i]):
|
|
1130
|
+
rhs = self.myRothX_in[i][n]
|
|
1131
|
+
B.setRange(_q2(Cx, i, n, Ni, Nn), rhs, rhs)
|
|
1132
|
+
else:
|
|
1133
|
+
if "maxRothConversion" in options:
|
|
1133
1134
|
rhsopt = options["maxRothConversion"]
|
|
1134
|
-
assert isinstance(rhsopt, (int, float)), "Specified
|
|
1135
|
+
assert isinstance(rhsopt, (int, float)), "Specified maxRothConversion is not a number."
|
|
1135
1136
|
rhsopt *= units
|
|
1136
1137
|
if rhsopt < 0:
|
|
1137
1138
|
# self.mylog.vprint('Unlimited Roth conversions (<0)')
|
|
@@ -1143,27 +1144,28 @@ class Plan(object):
|
|
|
1143
1144
|
# Should we adjust Roth conversion cap with inflation?
|
|
1144
1145
|
B.set0_Ub(_q2(Cx, i, n, Ni, Nn), rhsopt)
|
|
1145
1146
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1147
|
+
# Process startRothConversions option.
|
|
1148
|
+
if "startRothConversions" in options:
|
|
1149
|
+
rhsopt = options["startRothConversions"]
|
|
1150
|
+
assert isinstance(rhsopt, (int, float)), "Specified startRothConversions is not a number."
|
|
1151
|
+
thisyear = date.today().year
|
|
1152
|
+
yearn = max(rhsopt - thisyear, 0)
|
|
1151
1153
|
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1154
|
+
for i in range(Ni):
|
|
1155
|
+
nstart = min(yearn, self.horizons[i])
|
|
1156
|
+
for n in range(0, nstart):
|
|
1157
|
+
B.set0_Ub(_q2(Cx, i, n, Ni, Nn), zero)
|
|
1158
|
+
|
|
1159
|
+
# Process noRothConversions option. Also valid when N_i == 1, why not?
|
|
1160
|
+
if "noRothConversions" in options and options["noRothConversions"] != "None":
|
|
1161
|
+
rhsopt = options["noRothConversions"]
|
|
1162
|
+
try:
|
|
1163
|
+
i_x = self.inames.index(rhsopt)
|
|
1164
|
+
except ValueError:
|
|
1165
|
+
raise ValueError(f"Unknown individual {rhsopt} for noRothConversions:")
|
|
1164
1166
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
+
for n in range(Nn):
|
|
1168
|
+
B.set0_Ub(_q2(Cx, i_x, n, Ni, Nn), zero)
|
|
1167
1169
|
|
|
1168
1170
|
# Impose withdrawal limits on taxable and tax-exempt accounts.
|
|
1169
1171
|
for i in range(Ni):
|
owlplanner/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2025.04.
|
|
1
|
+
__version__ = "2025.04.02"
|
|
@@ -2,16 +2,16 @@ owlplanner/__init__.py,sha256=QqrdT0Qks20osBTg7h0vJHAxpP9lL7DA99xb0nYbtw4,254
|
|
|
2
2
|
owlplanner/abcapi.py,sha256=LbzW_KcNy0IeHp42MUHwGu_H67B2h_e1_vu-c2ACTkQ,6646
|
|
3
3
|
owlplanner/config.py,sha256=F6GS3n02VeFX0GCVeM4J7Ra0in4N632W6TZIXk7Yj2w,12519
|
|
4
4
|
owlplanner/logging.py,sha256=tYMw04O-XYSzjTj36fmKJGLcE1VkK6k6oJNeqtKXzuc,2530
|
|
5
|
-
owlplanner/plan.py,sha256=
|
|
5
|
+
owlplanner/plan.py,sha256=obzXmEJhtkIhmTFOR02Q6g1deigUkFnufyv54EqvD5o,117672
|
|
6
6
|
owlplanner/progress.py,sha256=8jlCvvtgDI89zXVNMBg1-lnEyhpPvKQS2X5oAIpoOVQ,384
|
|
7
7
|
owlplanner/rates.py,sha256=gJaoe-gJqWCQV5qVLlHp-Yn9TSJs-PJzeTbOwMCbqWs,15682
|
|
8
8
|
owlplanner/tax2025.py,sha256=HEXfL0HfwUvZOQRjivXO2jFeoVZ5m_yk_hoMiVi-hR0,7745
|
|
9
9
|
owlplanner/timelists.py,sha256=tYieZU67FT6TCcQQis36JaXGI7dT6NqD7RvdEjgJL4M,4026
|
|
10
10
|
owlplanner/utils.py,sha256=WpJgn79YZfH8UCkcmhd-AZlxlGuz1i1-UDBRXImsY6I,2485
|
|
11
|
-
owlplanner/version.py,sha256=
|
|
11
|
+
owlplanner/version.py,sha256=TElp9wm8J0rr4k4sU8OgxW2Rf9Zy8iAW808A6RDo1lE,28
|
|
12
12
|
owlplanner/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
owlplanner/data/rates.csv,sha256=6fxg56BVVORrj9wJlUGFdGXKvOX5r7CSca8uhUbbuIU,3734
|
|
14
|
-
owlplanner-2025.4.
|
|
15
|
-
owlplanner-2025.4.
|
|
16
|
-
owlplanner-2025.4.
|
|
17
|
-
owlplanner-2025.4.
|
|
14
|
+
owlplanner-2025.4.2.dist-info/METADATA,sha256=Ro0E2vypz99zMe7EBwOTgJRnoHnEWB9yIt004agJKrA,53800
|
|
15
|
+
owlplanner-2025.4.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
owlplanner-2025.4.2.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
17
|
+
owlplanner-2025.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|