owlplanner 2025.2.6__py3-none-any.whl → 2025.2.8__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/config.py +3 -1
- owlplanner/plan.py +13 -5
- owlplanner/version.py +1 -1
- {owlplanner-2025.2.6.dist-info → owlplanner-2025.2.8.dist-info}/METADATA +1 -1
- {owlplanner-2025.2.6.dist-info → owlplanner-2025.2.8.dist-info}/RECORD +7 -7
- {owlplanner-2025.2.6.dist-info → owlplanner-2025.2.8.dist-info}/WHEEL +0 -0
- {owlplanner-2025.2.6.dist-info → owlplanner-2025.2.8.dist-info}/licenses/LICENSE +0 -0
owlplanner/config.py
CHANGED
|
@@ -52,6 +52,7 @@ def saveConfig(plan, file, mylog):
|
|
|
52
52
|
# Fixed Income.
|
|
53
53
|
diconf['Fixed Income'] = {'Pension amounts': (plan.pensionAmounts/1000).tolist(),
|
|
54
54
|
'Pension ages': plan.pensionAges.tolist(),
|
|
55
|
+
'Pension indexed': plan.pensionIndexed,
|
|
55
56
|
'Social security amounts': (plan.ssecAmounts/1000).tolist(),
|
|
56
57
|
'Social security ages': plan.ssecAges.tolist(),
|
|
57
58
|
}
|
|
@@ -213,7 +214,8 @@ def readConfig(file, *, verbose=True, logstreams=None, readContributions=True):
|
|
|
213
214
|
p.setSocialSecurity(ssecAmounts, ssecAges)
|
|
214
215
|
pensionAmounts = np.array(diconf['Fixed Income']['Pension amounts'], dtype=np.float32)
|
|
215
216
|
pensionAges = np.array(diconf['Fixed Income']['Pension ages'], dtype=np.int32)
|
|
216
|
-
|
|
217
|
+
pensionIndexed = diconf['Fixed Income']['Pension indexed']
|
|
218
|
+
p.setPension(pensionAmounts, pensionAges, pensionIndexed)
|
|
217
219
|
|
|
218
220
|
# Rate Selection.
|
|
219
221
|
p.setDividendRate(float(diconf['Rate Selection']['Dividend tax rate']))
|
owlplanner/plan.py
CHANGED
|
@@ -286,6 +286,7 @@ class Plan(object):
|
|
|
286
286
|
self.zeta_in = np.zeros((self.N_i, self.N_n))
|
|
287
287
|
self.pensionAmounts = np.zeros(self.N_i)
|
|
288
288
|
self.pensionAges = 65 * np.ones(self.N_i, dtype=np.int32)
|
|
289
|
+
self.pensionIndexed = [False, False]
|
|
289
290
|
self.ssecAmounts = np.zeros(self.N_i)
|
|
290
291
|
self.ssecAges = 67 * np.ones(self.N_i, dtype=np.int32)
|
|
291
292
|
|
|
@@ -481,13 +482,14 @@ class Plan(object):
|
|
|
481
482
|
self.nu = nu
|
|
482
483
|
self.caseStatus = 'modified'
|
|
483
484
|
|
|
484
|
-
def setPension(self, amounts, ages, units='k'):
|
|
485
|
+
def setPension(self, amounts, ages, indexed=[False, False], units='k'):
|
|
485
486
|
"""
|
|
486
487
|
Set value of pension for each individual and commencement age.
|
|
487
488
|
Units are in $k, unless specified otherwise: 'k', 'M', or '1'.
|
|
488
489
|
"""
|
|
489
490
|
assert len(amounts) == self.N_i, 'Amounts must have %d entries.' % self.N_i
|
|
490
491
|
assert len(ages) == self.N_i, 'Ages must have %d entries.' % self.N_i
|
|
492
|
+
assert len(indexed) >= self.N_i, 'Indexed list must have at least %d entries.' % self.N_i
|
|
491
493
|
|
|
492
494
|
fac = u.getUnits(units)
|
|
493
495
|
amounts = u.rescale(amounts, fac)
|
|
@@ -508,7 +510,9 @@ class Plan(object):
|
|
|
508
510
|
|
|
509
511
|
self.pensionAmounts = np.array(amounts)
|
|
510
512
|
self.pensionAges = np.array(ages, dtype=np.int32)
|
|
513
|
+
self.pensionIndexed = indexed
|
|
511
514
|
self.caseStatus = 'modified'
|
|
515
|
+
self._adjustedParameters = False
|
|
512
516
|
|
|
513
517
|
def setSocialSecurity(self, amounts, ages, units='k'):
|
|
514
518
|
"""
|
|
@@ -1001,6 +1005,10 @@ class Plan(object):
|
|
|
1001
1005
|
self.zetaBar_in = self.zeta_in * self.gamma_n[:-1]
|
|
1002
1006
|
self.sigmaBar_n = self.sigma_n * self.gamma_n[:-1]
|
|
1003
1007
|
self.xiBar_n = self.xi_n * self.gamma_n[:-1]
|
|
1008
|
+
self.piBar_in = self.pi_in
|
|
1009
|
+
for i in range(self.N_i):
|
|
1010
|
+
if self.pensionIndexed[i]:
|
|
1011
|
+
self.piBar_in[i] *= self.gamma_n[:-1]
|
|
1004
1012
|
|
|
1005
1013
|
self._adjustedParameters = True
|
|
1006
1014
|
|
|
@@ -1269,7 +1277,7 @@ class Plan(object):
|
|
|
1269
1277
|
rhs += (
|
|
1270
1278
|
self.omega_in[i, n]
|
|
1271
1279
|
+ self.zetaBar_in[i, n]
|
|
1272
|
-
+ self.
|
|
1280
|
+
+ self.piBar_in[i, n]
|
|
1273
1281
|
+ self.Lambda_in[i, n]
|
|
1274
1282
|
- 0.5 * fac * self.mu * self.kappa_ijn[i, 0, n]
|
|
1275
1283
|
)
|
|
@@ -1299,7 +1307,7 @@ class Plan(object):
|
|
|
1299
1307
|
row = A.newRow()
|
|
1300
1308
|
row.addElem(_q1(Ce, n, Nn), 1)
|
|
1301
1309
|
for i in range(Ni):
|
|
1302
|
-
rhs += self.omega_in[i, n] + 0.85 * self.zetaBar_in[i, n] + self.
|
|
1310
|
+
rhs += self.omega_in[i, n] + 0.85 * self.zetaBar_in[i, n] + self.piBar_in[i, n]
|
|
1303
1311
|
# Taxable income from tax-deferred withdrawals.
|
|
1304
1312
|
row.addElem(_q3(Cw, i, 1, n, Ni, Nj, Nn), -1)
|
|
1305
1313
|
row.addElem(_q2(Cx, i, n, Ni, Nn), -1)
|
|
@@ -2000,7 +2008,7 @@ class Plan(object):
|
|
|
2000
2008
|
sources = {}
|
|
2001
2009
|
sources['wages'] = self.omega_in
|
|
2002
2010
|
sources['ssec'] = self.zetaBar_in
|
|
2003
|
-
sources['pension'] = self.
|
|
2011
|
+
sources['pension'] = self.piBar_in
|
|
2004
2012
|
sources['txbl acc wdrwl'] = self.w_ijn[:, 0, :]
|
|
2005
2013
|
sources['RMD'] = self.rmd_in
|
|
2006
2014
|
sources['+dist'] = self.dist_in
|
|
@@ -2706,7 +2714,7 @@ class Plan(object):
|
|
|
2706
2714
|
cashFlowDic = {
|
|
2707
2715
|
'net spending': self.g_n,
|
|
2708
2716
|
'all wages': np.sum(self.omega_in, axis=0),
|
|
2709
|
-
'all pensions': np.sum(self.
|
|
2717
|
+
'all pensions': np.sum(self.piBar_in, axis=0),
|
|
2710
2718
|
'all soc sec': np.sum(self.zetaBar_in, axis=0),
|
|
2711
2719
|
"all BTI's": np.sum(self.Lambda_in, axis=0),
|
|
2712
2720
|
'all wdrwls': np.sum(self.w_ijn, axis=(0, 1)),
|
owlplanner/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2025.02.
|
|
1
|
+
__version__ = "2025.02.08"
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
owlplanner/__init__.py,sha256=QqrdT0Qks20osBTg7h0vJHAxpP9lL7DA99xb0nYbtw4,254
|
|
2
2
|
owlplanner/abcapi.py,sha256=eemIsdbtzdWCIj5VuuswgphxXMcxJ_GZfUlDi6lttFM,6658
|
|
3
|
-
owlplanner/config.py,sha256=
|
|
3
|
+
owlplanner/config.py,sha256=1gofMnUUyOy4KXSWSPEij5yUKjvPu6kiPXcS_Nii4Rg,12220
|
|
4
4
|
owlplanner/logging.py,sha256=pXg_mMgBll-kklqaDRLDNVUFo-5DAa-yqTKtiVrhNWw,2530
|
|
5
|
-
owlplanner/plan.py,sha256=
|
|
5
|
+
owlplanner/plan.py,sha256=UBmOPVfpHPUZUo8Th6sROwTsCUi6PBuv11TD2x3XK70,114255
|
|
6
6
|
owlplanner/progress.py,sha256=YZjL5_m4MMgKPlWlhhKacPLt54tVhVGF1eXxxZapMYs,386
|
|
7
7
|
owlplanner/rates.py,sha256=aKOmau8i3uqxZGi7HQJpzooT3X-yAZhga5MZJ56pBzk,15627
|
|
8
8
|
owlplanner/tax2025.py,sha256=b2RgM6TBQa8ggo6ODyh0p_J7j79UUm8z5NiENqa1l_k,7016
|
|
9
9
|
owlplanner/timelists.py,sha256=WwymsYAGWcrEzMtc-wrLbn1EVA2fhqXGN4NHLJsH3Fs,4110
|
|
10
10
|
owlplanner/utils.py,sha256=adIwqGVQFfvekke0JCxYJD3PKHbptVCj3NrQT2TQIB4,2351
|
|
11
|
-
owlplanner/version.py,sha256=
|
|
11
|
+
owlplanner/version.py,sha256=Voi7cBnkUuxoqJIUjmHB47rz-PDQTzK8NO_H0JraUMA,28
|
|
12
12
|
owlplanner/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
owlplanner/data/rates.csv,sha256=6fxg56BVVORrj9wJlUGFdGXKvOX5r7CSca8uhUbbuIU,3734
|
|
14
|
-
owlplanner-2025.2.
|
|
15
|
-
owlplanner-2025.2.
|
|
16
|
-
owlplanner-2025.2.
|
|
17
|
-
owlplanner-2025.2.
|
|
14
|
+
owlplanner-2025.2.8.dist-info/METADATA,sha256=c8WdLd8PAtMZtmRULpn-Q3BrV7edwrnpXCsRrbLbiz8,63946
|
|
15
|
+
owlplanner-2025.2.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
owlplanner-2025.2.8.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
17
|
+
owlplanner-2025.2.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|