Modify the roth conversion logic and simplify the code around that.
[retire.git] / parameters.py
1 import constants
2 import utils
3 from tax_brackets import tax_brackets
4
5 class parameters(object):
6     """A container to hold the initial states of several simulation
7        parameters.  Play with them as you see fit and see what happens."""
8
9     def __init__(self):
10         self.with_default_values()
11
12     def with_default_values(self):
13         # Annual expenses in USD at the start of the simulation.  This
14         # will be adjusted upwards with inflation_multiplier every year.
15         self.initial_annual_expenses = 144300
16
17         # The average US inflation rate during the simulation.  The
18         # Fed's target rate is 2.0% as of 2020.  The long term observed
19         # average historical inflation rate in the US is 2.1%.
20         #
21         # Note this is a multiplier... so 1.0 would be no inflation,
22         # 1.21 is 2.1% inflation, 0.9 is deflation, etc...
23         self.inflation_multiplier = 1.03
24
25         # We want to be able to model social security payments not
26         # keeping pace with inflation.  Like the inflation_multiplier
27         # above, this is a multiplier.  It affect the magnitide of
28         # social security payments year over year.
29         self.social_security_multiplier = 1.02
30
31         # This is the average investment return rate.  Asset allocation has
32         # a large effect on this as does the overall economy.  That said,
33         # the US stock market has returned 10%/year over a large enough
34         # time window.  Our investments at Fidelity have returned 6.91%
35         # in the lifetime they have been there.  The expected return of a
36         # 50/50 stock/bond investment mix based on historical data is 8.3%.
37         self.investment_multiplier = 1.04
38
39         # The age at which each person will take social security
40         # benefits in this simulation and how much she will get the
41         # first year.  Note, this benefit size increases year over
42         # year at social_security_multiplier.  This is what the social
43         # security website estimates if we both earn $0 from 2020 on:
44         #
45         #     Lynn's benefits:              Scott's benefits:
46         #      age 62 - $21,120              age 62 - $21,420
47         #      age 67 - $30,000              age 67 - $30,420
48         #      age 70 - $37,200              age 70 - $37,728
49         #
50         self.social_security_age = [ 0, 62, 70 ]
51         self.initial_social_security_dollars = [ 0, 15000, 25000 ]
52
53         # Tax details... the standard deduction amount and tax
54         # brackets for ordinary income and long term capital gains.
55         self.federal_standard_deduction_dollars = 24800
56         self.federal_ordinary_income_tax_brackets = tax_brackets(
57             constants.PESSIMISTIC_FEDERAL_INCOME_TAX_BRACKETS)
58         self.federal_dividends_and_long_term_gains_brackets = tax_brackets(
59             constants.CURRENT_LONG_TERM_GAIN_FEDERAL_TAX_BRACKETS)
60         return self
61
62     def with_initial_annual_expenses(self, expenses):
63         self.initial_annual_expenses = expenses
64         return self
65
66     def get_initial_annual_expenses(self):
67         return self.initial_annual_expenses
68
69     def with_average_inflation_multiplier(self, multiplier):
70         self.inflation_multiplier = multiplier
71         return self
72
73     def get_average_inflation_multiplier(self):
74         return self.inflation_multiplier
75
76     def with_average_social_security_multiplier(self, multiplier):
77         self.social_security_multiplier = multiplier
78         return self
79
80     def get_average_social_security_multiplier(self):
81         return self.social_security_multiplier
82
83     def with_average_investment_return_multiplier(self, multiplier):
84         self.investment_multiplier = multiplier
85         return self
86
87     def get_average_investment_return_multiplier(self):
88         return self.investment_multiplier
89
90     def with_initial_social_security_age_and_benefits(self,
91                                                       person,
92                                                       age,
93                                                       amount):
94         self.social_security_age[person] = age
95         self.initial_social_security_dollars[person] = amount
96         return self
97
98     def get_initial_social_security_age(self, person):
99         return self.social_security_age[person]
100
101     def get_initial_social_security_benefit(self, person):
102         return self.initial_social_security_dollars[person]
103
104     def with_federal_standard_deduction(self, deduction):
105         self.federal_standard_deduction_dollars = deduction
106         return self
107
108     def get_federal_standard_deduction(self):
109         return self.federal_standard_deduction_dollars
110
111     def with_federal_ordinary_income_tax_brackets(self, brackets):
112         self.federal_ordinary_income_tax_brackets = brackets
113         return self
114
115     def get_federal_ordinary_income_tax_brackets(self):
116         return self.federal_ordinary_income_tax_brackets
117
118     def with_federal_dividends_and_long_term_gains_income_tax_brackets(self,
119                                                                        brackets):
120         self.federal_dividends_and_long_term_gains_brackets = brackets;
121         return self
122
123     def get_federal_dividends_and_long_term_gains_income_tax_brackets(self):
124         return self.federal_dividends_and_long_term_gains_brackets
125
126     def dump(self):
127         print "SIMULATION PARAMETERS"
128         print "  {:<50}: {:>14}".format("Initial year annual expenses",
129                                         utils.format_money(self.initial_annual_expenses))
130         print "  {:<50}: {:>14}".format("Annual inflation rate",
131                                         utils.format_rate(self.inflation_multiplier))
132         print "  {:<50}: {:>14}".format("Average annual investment return rate",
133                                         utils.format_rate(self.investment_multiplier))
134         print "  {:<50}: {:>14}".format("Annual social security benefit increase rate",
135                                         utils.format_rate(self.social_security_multiplier))
136         print "  {:<50}: {:>14}".format("Age at which Lynn takes social security",
137                                         self.social_security_age[constants.LYNN])
138         print "  {:<50}: {:>14}".format("Lynn's first year social security benefit",
139                                         utils.format_money(self.initial_social_security_dollars[constants.LYNN]))
140         print "  {:<50}: {:>14}".format("Age at which Scott takes social security",
141                                         self.social_security_age[constants.SCOTT])
142         print "  {:<50}: {:>14}".format("Scott's first year social security benefit",
143                                         utils.format_money(self.initial_social_security_dollars[constants.SCOTT]))
144         print "  Federal tax brackets ["
145         self.federal_ordinary_income_tax_brackets.dump()
146         print "  ]"
147
148         print "  Federal dividend and long term gain brackets ["
149         self.federal_dividends_and_long_term_gains_brackets.dump()
150         print "  ]"
151         print "  We assume Roth money continues to be available tax-free."