owlplanner 2025.1.28__py3-none-any.whl → 2025.1.29__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 +14 -31
- owlplanner/tax2025.py +5 -5
- owlplanner/version.py +1 -1
- {owlplanner-2025.1.28.dist-info → owlplanner-2025.1.29.dist-info}/METADATA +1 -1
- {owlplanner-2025.1.28.dist-info → owlplanner-2025.1.29.dist-info}/RECORD +7 -7
- {owlplanner-2025.1.28.dist-info → owlplanner-2025.1.29.dist-info}/WHEEL +0 -0
- {owlplanner-2025.1.28.dist-info → owlplanner-2025.1.29.dist-info}/licenses/LICENSE +0 -0
owlplanner/plan.py
CHANGED
|
@@ -295,6 +295,9 @@ class Plan(object):
|
|
|
295
295
|
self.myRothX_in = np.zeros((self.N_i, self.N_n))
|
|
296
296
|
self.kappa_ijn = np.zeros((self.N_i, self.N_j, self.N_n))
|
|
297
297
|
|
|
298
|
+
# Previous 2 years for Medicare.
|
|
299
|
+
self.prevMAGI = np.zeros((2))
|
|
300
|
+
|
|
298
301
|
# Scenario starts at the beginning of this year and ends at the end of the last year.
|
|
299
302
|
self.mylog.vprint('Preparing scenario of %d years for %d individual%s.'
|
|
300
303
|
% (self.N_n, self.N_i, ['', 's'][self.N_i - 1]))
|
|
@@ -394,6 +397,16 @@ class Plan(object):
|
|
|
394
397
|
|
|
395
398
|
return None
|
|
396
399
|
|
|
400
|
+
def setPreviousMAGI(self, magi, units='k'):
|
|
401
|
+
"""
|
|
402
|
+
Set MAGI for two previous years to the plan. Values are in nominal $k.
|
|
403
|
+
"""
|
|
404
|
+
assert len(magi) == 2, "MAGI must have two values."
|
|
405
|
+
fac = u.getUnits(units)
|
|
406
|
+
u.rescale(magi, fac)
|
|
407
|
+
self.mylog.vprint('Setting previous years MAGI to:', [u.d(magi[i]) for i in range(2)])
|
|
408
|
+
self.prevMAGI = np.array(magi)
|
|
409
|
+
|
|
397
410
|
def rename(self, newname):
|
|
398
411
|
"""
|
|
399
412
|
Override name of the plan. Plan name is used
|
|
@@ -403,8 +416,6 @@ class Plan(object):
|
|
|
403
416
|
self.mylog.vprint('Renaming plan %s -> %s.' % (self._name, newname))
|
|
404
417
|
self._name = newname
|
|
405
418
|
|
|
406
|
-
return None
|
|
407
|
-
|
|
408
419
|
def setSpousalDepositFraction(self, eta):
|
|
409
420
|
"""
|
|
410
421
|
Set spousal deposit and withdrawal fraction. Default 0.5.
|
|
@@ -424,8 +435,6 @@ class Plan(object):
|
|
|
424
435
|
self.mylog.vprint('\t%s: %.1f, %s: %.1f' % (self.inames[0], (1 - eta), self.inames[1], eta))
|
|
425
436
|
self.eta = eta
|
|
426
437
|
|
|
427
|
-
return None
|
|
428
|
-
|
|
429
438
|
def setDefaultPlots(self, value):
|
|
430
439
|
"""
|
|
431
440
|
Set plots between nominal values or today's $.
|
|
@@ -434,8 +443,6 @@ class Plan(object):
|
|
|
434
443
|
self.defaultPlots = self._checkValue(value)
|
|
435
444
|
self.mylog.vprint('Setting plots default value to %s.' % value)
|
|
436
445
|
|
|
437
|
-
return None
|
|
438
|
-
|
|
439
446
|
def setDividendRate(self, mu):
|
|
440
447
|
"""
|
|
441
448
|
Set dividend rate on equities. Rate is in percent. Default 2%.
|
|
@@ -446,8 +453,6 @@ class Plan(object):
|
|
|
446
453
|
self.mu = mu
|
|
447
454
|
self.caseStatus = 'modified'
|
|
448
455
|
|
|
449
|
-
return None
|
|
450
|
-
|
|
451
456
|
def setLongTermCapitalTaxRate(self, psi):
|
|
452
457
|
"""
|
|
453
458
|
Set long-term income tax rate. Rate is in percent. Default 15%.
|
|
@@ -458,8 +463,6 @@ class Plan(object):
|
|
|
458
463
|
self.psi = psi
|
|
459
464
|
self.caseStatus = 'modified'
|
|
460
465
|
|
|
461
|
-
return None
|
|
462
|
-
|
|
463
466
|
def setBeneficiaryFractions(self, phi):
|
|
464
467
|
"""
|
|
465
468
|
Set fractions of savings accounts that is left to surviving spouse.
|
|
@@ -477,8 +480,6 @@ class Plan(object):
|
|
|
477
480
|
self.mylog.vprint('Consider changing spousal deposit fraction for better convergence.')
|
|
478
481
|
self.mylog.vprint('\tRecommended: setSpousalDepositFraction(%d)' % self.i_d)
|
|
479
482
|
|
|
480
|
-
return None
|
|
481
|
-
|
|
482
483
|
def setHeirsTaxRate(self, nu):
|
|
483
484
|
"""
|
|
484
485
|
Set the heirs tax rate on the tax-deferred portion of the estate.
|
|
@@ -490,8 +491,6 @@ class Plan(object):
|
|
|
490
491
|
self.nu = nu
|
|
491
492
|
self.caseStatus = 'modified'
|
|
492
493
|
|
|
493
|
-
return None
|
|
494
|
-
|
|
495
494
|
def setPension(self, amounts, ages, units='k'):
|
|
496
495
|
"""
|
|
497
496
|
Set value of pension for each individual and commencement age.
|
|
@@ -521,8 +520,6 @@ class Plan(object):
|
|
|
521
520
|
self.pensionAges = np.array(ages, dtype=np.int32)
|
|
522
521
|
self.caseStatus = 'modified'
|
|
523
522
|
|
|
524
|
-
return None
|
|
525
|
-
|
|
526
523
|
def setSocialSecurity(self, amounts, ages, units='k'):
|
|
527
524
|
"""
|
|
528
525
|
Set value of social security for each individual and commencement age.
|
|
@@ -560,8 +557,6 @@ class Plan(object):
|
|
|
560
557
|
self.caseStatus = 'modified'
|
|
561
558
|
self._adjustedParameters = False
|
|
562
559
|
|
|
563
|
-
return None
|
|
564
|
-
|
|
565
560
|
def setSpendingProfile(self, profile, percent=60, dip=15, increase=12, delay=0):
|
|
566
561
|
"""
|
|
567
562
|
Generate time series for spending profile. Surviving spouse fraction can be specified
|
|
@@ -589,8 +584,6 @@ class Plan(object):
|
|
|
589
584
|
self.smileDelay = delay
|
|
590
585
|
self.caseStatus = 'modified'
|
|
591
586
|
|
|
592
|
-
return None
|
|
593
|
-
|
|
594
587
|
def setRates(self, method, frm=None, to=None, values=None, stdev=None, corr=None):
|
|
595
588
|
"""
|
|
596
589
|
Generate rates for return and inflation based on the method and
|
|
@@ -632,8 +625,6 @@ class Plan(object):
|
|
|
632
625
|
self._adjustedParameters = False
|
|
633
626
|
self.caseStatus = 'modified'
|
|
634
627
|
|
|
635
|
-
return None
|
|
636
|
-
|
|
637
628
|
def regenRates(self):
|
|
638
629
|
"""
|
|
639
630
|
Regenerate the rates using the arguments specified during last setRates() call.
|
|
@@ -648,8 +639,6 @@ class Plan(object):
|
|
|
648
639
|
corr=self.rateCorr,
|
|
649
640
|
)
|
|
650
641
|
|
|
651
|
-
return None
|
|
652
|
-
|
|
653
642
|
def value(self, amount, year):
|
|
654
643
|
"""
|
|
655
644
|
Return value of amount deflated or inflated at the beginning
|
|
@@ -711,8 +700,6 @@ class Plan(object):
|
|
|
711
700
|
u.d(np.sum(taxable) + 0.7 * np.sum(taxDeferred) + np.sum(taxFree)),
|
|
712
701
|
)
|
|
713
702
|
|
|
714
|
-
return None
|
|
715
|
-
|
|
716
703
|
def setInterpolationMethod(self, method, center=15, width=5):
|
|
717
704
|
"""
|
|
718
705
|
Interpolate assets allocation ratios from initial value (today) to
|
|
@@ -739,8 +726,6 @@ class Plan(object):
|
|
|
739
726
|
|
|
740
727
|
self.mylog.vprint('Asset allocation interpolation method set to %s.' % method)
|
|
741
728
|
|
|
742
|
-
return None
|
|
743
|
-
|
|
744
729
|
def setAllocationRatios(self, allocType, taxable=None, taxDeferred=None, taxFree=None, generic=None):
|
|
745
730
|
"""
|
|
746
731
|
Single function for setting all types of asset allocations.
|
|
@@ -874,8 +859,6 @@ class Plan(object):
|
|
|
874
859
|
|
|
875
860
|
self.mylog.vprint('Interpolating assets allocation ratios using', self.interpMethod, 'method.')
|
|
876
861
|
|
|
877
|
-
return None
|
|
878
|
-
|
|
879
862
|
def readContributions(self, filename):
|
|
880
863
|
"""
|
|
881
864
|
Provide the name of the file containing the financial events
|
|
@@ -1897,7 +1880,7 @@ class Plan(object):
|
|
|
1897
1880
|
self.F_tn = self.F_tn.reshape((self.N_t, self.N_n))
|
|
1898
1881
|
MAGI_n = np.sum(self.F_tn, axis=0) + np.array(x[self.C['e']:self.C['F']])
|
|
1899
1882
|
|
|
1900
|
-
self.M_n = tx.mediCosts(self.yobs, self.horizons, MAGI_n, self.gamma_n[:-1], self.N_n)
|
|
1883
|
+
self.M_n = tx.mediCosts(self.yobs, self.horizons, MAGI_n, self.prevMAGI, self.gamma_n[:-1], self.N_n)
|
|
1901
1884
|
|
|
1902
1885
|
return None
|
|
1903
1886
|
|
owlplanner/tax2025.py
CHANGED
|
@@ -69,7 +69,7 @@ extra65Deduction_2025 = np.array([2000, 1600])
|
|
|
69
69
|
##############################################################################
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def mediCosts(yobs, horizons, magi, gamma_n, Nn):
|
|
72
|
+
def mediCosts(yobs, horizons, magi, prevmagi, gamma_n, Nn):
|
|
73
73
|
"""
|
|
74
74
|
Compute Medicare costs directly.
|
|
75
75
|
"""
|
|
@@ -79,14 +79,14 @@ def mediCosts(yobs, horizons, magi, gamma_n, Nn):
|
|
|
79
79
|
for n in range(Nn):
|
|
80
80
|
for i in range(Ni):
|
|
81
81
|
if thisyear + n - yobs[i] >= 65 and n < horizons[i]:
|
|
82
|
-
#
|
|
82
|
+
# Start with the (indexed) basic Medicare part B premium.
|
|
83
83
|
costs[n] += gamma_n[n] * irmaaFees_2025[0]
|
|
84
84
|
if n < 2:
|
|
85
|
-
|
|
85
|
+
mymagi = prevmagi[n]
|
|
86
86
|
else:
|
|
87
|
-
|
|
87
|
+
mymagi = magi[n - 2]
|
|
88
88
|
for q in range(1, 6):
|
|
89
|
-
if
|
|
89
|
+
if mymagi > gamma_n[n] * irmaaBrackets_2025[Ni - 1][q]:
|
|
90
90
|
costs[n] += gamma_n[n] * irmaaFees_2025[q]
|
|
91
91
|
|
|
92
92
|
return costs
|
owlplanner/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2025.1.
|
|
1
|
+
__version__ = "2025.1.29"
|
|
@@ -2,16 +2,16 @@ owlplanner/__init__.py,sha256=QqrdT0Qks20osBTg7h0vJHAxpP9lL7DA99xb0nYbtw4,254
|
|
|
2
2
|
owlplanner/abcapi.py,sha256=eemIsdbtzdWCIj5VuuswgphxXMcxJ_GZfUlDi6lttFM,6658
|
|
3
3
|
owlplanner/config.py,sha256=ouADb6YES5Zgv0UwnEK9Axwvs8drp-ahboQjI4WTrr0,12069
|
|
4
4
|
owlplanner/logging.py,sha256=pXg_mMgBll-kklqaDRLDNVUFo-5DAa-yqTKtiVrhNWw,2530
|
|
5
|
-
owlplanner/plan.py,sha256=
|
|
5
|
+
owlplanner/plan.py,sha256=4Kuulsp3uUAt9w0sLKPPGPry2tPnY74SMNSOTcVIs40,115575
|
|
6
6
|
owlplanner/progress.py,sha256=YZjL5_m4MMgKPlWlhhKacPLt54tVhVGF1eXxxZapMYs,386
|
|
7
7
|
owlplanner/rates.py,sha256=aKOmau8i3uqxZGi7HQJpzooT3X-yAZhga5MZJ56pBzk,15627
|
|
8
|
-
owlplanner/tax2025.py,sha256=
|
|
8
|
+
owlplanner/tax2025.py,sha256=b2RgM6TBQa8ggo6ODyh0p_J7j79UUm8z5NiENqa1l_k,7016
|
|
9
9
|
owlplanner/timelists.py,sha256=ifxbyMlRW3IMwsiu8zsoodA1CKJQthgk3iPq50vQIds,4104
|
|
10
10
|
owlplanner/utils.py,sha256=adIwqGVQFfvekke0JCxYJD3PKHbptVCj3NrQT2TQIB4,2351
|
|
11
|
-
owlplanner/version.py,sha256=
|
|
11
|
+
owlplanner/version.py,sha256=31a542RcfLaOTSP2qZRfQPdngqGSa6FlROIHXM1qDdc,27
|
|
12
12
|
owlplanner/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
owlplanner/data/rates.csv,sha256=6fxg56BVVORrj9wJlUGFdGXKvOX5r7CSca8uhUbbuIU,3734
|
|
14
|
-
owlplanner-2025.1.
|
|
15
|
-
owlplanner-2025.1.
|
|
16
|
-
owlplanner-2025.1.
|
|
17
|
-
owlplanner-2025.1.
|
|
14
|
+
owlplanner-2025.1.29.dist-info/METADATA,sha256=EreFCtwuHeBO7xbqqQrLBET1Gdy5e-o9VsOeMvLN_rQ,64515
|
|
15
|
+
owlplanner-2025.1.29.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
owlplanner-2025.1.29.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
17
|
+
owlplanner-2025.1.29.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|