owlplanner 2025.3.14__py3-none-any.whl → 2025.3.16__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 CHANGED
@@ -1284,19 +1284,15 @@ class Plan(object):
1284
1284
  # Minus capital gains on taxable withdrawals using last year's rate if >=0.
1285
1285
  # Plus taxable account withdrawals, and all other withdrawals.
1286
1286
  row.addElem(_q3(Cw, i, 0, n, Ni, Nj, Nn), fac * (tau_0prev[n] - self.mu) - 1)
1287
- row.addElem(_q3(Cw, i, 1, n, Ni, Nj, Nn), -1)
1288
- row.addElem(_q3(Cw, i, 2, n, Ni, Nj, Nn), -1)
1287
+ penalty = 0.1 if n < self.n59[i] else 0
1288
+ row.addElem(_q3(Cw, i, 1, n, Ni, Nj, Nn), -1 + penalty)
1289
+ row.addElem(_q3(Cw, i, 2, n, Ni, Nj, Nn), -1 + penalty)
1289
1290
  row.addElem(_q2(Cd, i, n, Ni, Nn), fac * self.mu)
1290
1291
 
1291
1292
  # Minus tax on ordinary income, T_n.
1292
1293
  for t in range(Nt):
1293
1294
  row.addElem(_q2(CF, t, n, Nt, Nn), self.theta_tn[t, n])
1294
1295
 
1295
- # Minus 10% penalty on early withdrawals.
1296
- if n < self.n59[i]:
1297
- row.addElem(_q3(Cw, i, 1, n, Ni, Nj, Nn), 0.1)
1298
- row.addElem(_q3(Cw, i, 2, n, Ni, Nj, Nn), 0.1)
1299
-
1300
1296
  A.addRow(row, rhs, rhs)
1301
1297
 
1302
1298
  # Impose income profile.
@@ -1978,12 +1974,12 @@ class Plan(object):
1978
1974
  self.G_n = np.sum(self.F_tn, axis=0)
1979
1975
  self.T_tn = self.F_tn * self.theta_tn
1980
1976
  self.T_n = np.sum(self.T_tn, axis=0)
1981
- self.penalty_n = np.zeros(Nn)
1982
- # Add early withdrawal penalties if any.
1977
+ self.P_n = np.zeros(Nn)
1978
+ # Add early withdrawal penalty if any.
1983
1979
  for i in range(Ni):
1984
- self.penalty_n[0:self.n59[i]] += 0.1*(self.w_ijn[i, 1, 0:self.n59[i]] + self.w_ijn[i, 2, 0:self.n59[i]])
1980
+ self.P_n[0:self.n59[i]] += 0.1*(self.w_ijn[i, 1, 0:self.n59[i]] + self.w_ijn[i, 2, 0:self.n59[i]])
1985
1981
 
1986
- self.T_n += self.penalty_n
1982
+ self.T_n += self.P_n
1987
1983
 
1988
1984
  tau_0 = np.array(self.tau_kn[0, :])
1989
1985
  tau_0[tau_0 < 0] = 0
@@ -2126,8 +2122,8 @@ class Plan(object):
2126
2122
  dic[f"-- Subtotal in tax bracket {tname}"] = f"{u.d(taxPaidNow)}"
2127
2123
  dic[f"-- [Subtotal in tax bracket {tname}]"] = f"{u.d(taxPaid)}"
2128
2124
 
2129
- penaltyPaid = np.sum(self.penalty_n, axis=0)
2130
- penaltyPaidNow = np.sum(self.penalty_n / self.gamma_n[:-1], axis=0)
2125
+ penaltyPaid = np.sum(self.P_n, axis=0)
2126
+ penaltyPaidNow = np.sum(self.P_n / self.gamma_n[:-1], axis=0)
2131
2127
  dic["-- Subtotal in early withdrawal penalty"] = f"{u.d(penaltyPaidNow)}"
2132
2128
  dic["-- [Subtotal in early withdrawal penalty]"] = f"{u.d(penaltyPaid)}"
2133
2129
 
owlplanner/rates.py CHANGED
@@ -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
owlplanner/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2025.03.14"
1
+ __version__ = "2025.03.16"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: owlplanner
3
- Version: 2025.3.14
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
@@ -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=uJ6jZ9Rx2CB2P5cFRscsUCXOW6uml7I4pta2ozjW0uo,12263
4
4
  owlplanner/logging.py,sha256=tYMw04O-XYSzjTj36fmKJGLcE1VkK6k6oJNeqtKXzuc,2530
5
- owlplanner/plan.py,sha256=2uS_N121p-fPhCboVSAthdt_uVw109ltLTvCLeGouuo,116263
5
+ owlplanner/plan.py,sha256=SWTqNMC0Mk2BUO3CBeeyBaz_cCbLddlSgPJaIj2Cc-I,116090
6
6
  owlplanner/progress.py,sha256=8jlCvvtgDI89zXVNMBg1-lnEyhpPvKQS2X5oAIpoOVQ,384
7
- owlplanner/rates.py,sha256=TN407qU4n-bac1oymkQ_n2QKEPwFQxy6JZVGwgIkLQU,15585
7
+ owlplanner/rates.py,sha256=gJaoe-gJqWCQV5qVLlHp-Yn9TSJs-PJzeTbOwMCbqWs,15682
8
8
  owlplanner/tax2025.py,sha256=B-A5eU3wxdcAaxRCbT3qI-JEKoD_ZeNbg_86XhNdQEI,7745
9
9
  owlplanner/timelists.py,sha256=tYieZU67FT6TCcQQis36JaXGI7dT6NqD7RvdEjgJL4M,4026
10
10
  owlplanner/utils.py,sha256=WpJgn79YZfH8UCkcmhd-AZlxlGuz1i1-UDBRXImsY6I,2485
11
- owlplanner/version.py,sha256=gPOv802nGWM84uQsfLVWHJKlgbpuozzBAjyW-OgDkzE,28
11
+ owlplanner/version.py,sha256=Jcl8LadUqoYB6SO4YGpB9C3ZbDxgmTQBNGqCWqKkUzE,28
12
12
  owlplanner/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  owlplanner/data/rates.csv,sha256=6fxg56BVVORrj9wJlUGFdGXKvOX5r7CSca8uhUbbuIU,3734
14
- owlplanner-2025.3.14.dist-info/METADATA,sha256=C5BlpAPu2CwtVQmuBUPDTYi7mXg86T3b0dYR5anPUak,53801
15
- owlplanner-2025.3.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- owlplanner-2025.3.14.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
17
- owlplanner-2025.3.14.dist-info/RECORD,,
14
+ owlplanner-2025.3.16.dist-info/METADATA,sha256=C1iW41089-MQsqEn1cp1-L7kTcwQWnSKGgGOLiZdt-g,53801
15
+ owlplanner-2025.3.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ owlplanner-2025.3.16.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
17
+ owlplanner-2025.3.16.dist-info/RECORD,,