import utils
from tax_brackets import tax_brackets
from money import money
+from numpy import random
class parameters(object):
+ def get_initial_annual_expenses(self):
+ pass
+
+ def get_average_inflation_multiplier(self):
+ pass
+
+ def get_average_social_security_multiplier(self):
+ pass
+
+ def get_average_investment_return_multiplier(self):
+ pass
+
+ def get_initial_social_security_age(self, person):
+ pass
+
+ def get_initial_social_security_benefit(self, person):
+ pass
+
+ def get_federal_standard_deduction(self):
+ pass
+
+ def get_federal_ordinary_income_tax_brackets(self):
+ pass
+
+ def get_federal_dividends_and_long_term_gains_income_tax_brackets(self):
+ pass
+
+ def dump(self):
+ pass
+
+ def report_year(self, year):
+ pass
+
+class mutable_default_parameters(parameters):
"""A container to hold the initial states of several simulation
parameters. Play with them as you see fit and see what happens."""
constants.CURRENT_LONG_TERM_GAIN_FEDERAL_TAX_BRACKETS)
return self
- def with_initial_annual_expenses(self, expenses):
+ def set_initial_annual_expenses(self, expenses):
assert expenses >= 0, "You can't have negative expenses"
self.initial_annual_expenses = expenses
return self
def get_initial_annual_expenses(self):
return self.initial_annual_expenses
- def with_average_inflation_multiplier(self, multiplier):
+ def set_average_inflation_multiplier(self, multiplier):
self.inflation_multiplier = multiplier
return self
def get_average_inflation_multiplier(self):
return self.inflation_multiplier
- def with_average_social_security_multiplier(self, multiplier):
+ def set_average_social_security_multiplier(self, multiplier):
self.social_security_multiplier = multiplier
return self
def get_average_social_security_multiplier(self):
return self.social_security_multiplier
- def with_average_investment_return_multiplier(self, multiplier):
+ def set_average_investment_return_multiplier(self, multiplier):
self.investment_multiplier = multiplier
return self
def get_average_investment_return_multiplier(self):
return self.investment_multiplier
- def with_initial_social_security_age_and_benefits(self,
- person,
- age,
- amount):
+ def set_initial_social_security_age_and_benefits(self,
+ person,
+ age,
+ amount):
assert age >= 60 and age <= 70, "age should be between 60 and 70"
self.social_security_age[person] = age
assert amount >= 0, "Social security won't pay negative dollars"
def get_initial_social_security_benefit(self, person):
return self.initial_social_security_dollars[person]
- def with_federal_standard_deduction(self, deduction):
+ def set_federal_standard_deduction(self, deduction):
assert deduction >= 0, "Standard deduction should be non-negative"
self.federal_standard_deduction_dollars = deduction
return self
def get_federal_standard_deduction(self):
return self.federal_standard_deduction_dollars
- def with_federal_ordinary_income_tax_brackets(self, brackets):
+ def set_federal_ordinary_income_tax_brackets(self, brackets):
self.federal_ordinary_income_tax_brackets = brackets
return self
def get_federal_ordinary_income_tax_brackets(self):
return self.federal_ordinary_income_tax_brackets
- def with_federal_dividends_and_long_term_gains_income_tax_brackets(self,
- brackets):
+ def set_federal_dividends_and_long_term_gains_income_tax_brackets(self,
+ brackets):
self.federal_dividends_and_long_term_gains_brackets = brackets;
return self
self.federal_dividends_and_long_term_gains_brackets.dump()
print " ]"
print " We assume Roth money continues to be available tax-free."
+
+class mutable_dynamic_historical_parameters(mutable_default_parameters):
+ def __init__(self):
+ self.selection_index = None
+ self.selection_duration = 0
+ self.historical_tuples = [
+ # year stock infl bond
+ (2020, 3.14, 1.90, 1.54),
+ (2019, 31.49, 1.70, 2.15),
+ (2018, -4.38, 2.40, 2.33),
+ (2017, 21.83, 2.10, 1.19),
+ (2016, 11.96, 1.30, 0.61),
+ (2015, 1.38, 0.10, 0.32),
+ (2014, 13.69, 1.60, 0.12),
+ (2013, 32.39, 1.50, 0.13),
+ (2012, 16.00, 2.10, 0.17),
+ (2011, 2.11, 3.20, 0.18),
+ (2010, 15.06, 1.60, 0.32),
+ (2009, 26.46, -0.40, 0.47),
+ (2008,-37.00, 3.80, 1.83),
+ (2007, 5.49, 2.80, 4.53),
+ (2006, 15.79, 3.20, 4.94),
+ (2005, 4.91, 3.40, 3.62),
+ (2004, 10.88, 2.70, 1.89),
+ (2003, 28.68, 2.30, 1.24),
+ (2002,-22.10, 1.60, 2.00),
+ (2001,-11.89, 2.80, 3.49),
+ (2000, -9.10, 3.40, 6.11),
+ (1999, 21.04, 2.20, 5.08),
+ (1998, 28.58, 1.50, 5.05),
+ (1997, 33.36, 2.30, 5.63),
+ (1996, 22.96, 3.00, 5.52),
+ (1995, 37.58, 2.80, 5.94),
+ (1994, 1.32, 2.60, 5.32),
+ (1993, 10.08, 3.00, 3.43),
+ (1992, 7.62, 3.00, 3.89),
+ (1991, 30.47, 4.20, 5.86),
+ (1990, -3.10, 5.40, 7.89),
+ (1989, 31.69, 4.82, 8.54),
+ (1988, 16.61, 4.14, 7.65),
+ (1987, 15.25, 3.65, 6.77),
+ (1986, 18.67, 0.86, 6.45),
+ (1985, 31.73, 3.56, 8.42),
+ (1984, 6.27, 4.32, 10.91),
+ (1983, 22.56, 3.21, 9.58),
+ (1982, 21.55, 6.16, 12.27),
+ (1981, -4.91, 10.32, 14.80),
+ (1980, 32.42, 13.50, 12.00),
+ (1979, 18.44, 11.35, 10.65),
+ (1978, 6.65, 7.59, 7.00),
+ (1977, -7.18, 6.50, 6.08),
+ (1976, 23.84, 5.76, 5.88),
+ (1975, 37.20, 9.13, 6.78),
+ (1974,-26.47, 11.04, 8.20),
+ (1973,-14.66, 6.22, 7.32),
+ (1972, 18.90, 3.21, 4.95),
+ (1971, 14.31, 4.38, 4.89),
+ (1970, 14.01, 5.72, 6.90),
+ (1969, -8.50, 5.46, 7.12),
+ (1968, 11.06, 4.19, 5.69),
+ (1967, 23.98, 3.09, 4.88),
+ (1966,-10.06, 2.86, 5.20),
+ (1965, 12.45, 1.61, 4.15),
+ (1964, 16.48, 1.31, 3.85),
+ (1963, 22.80, 1.32, 3.36),
+ (1962, -8.73, 1.00, 2.90),
+ (1961, 26.89, 1.01, 2.60),
+ (1960, 0.47, 1.72, 3.24),
+ (1959, 11.96, 0.69, 3.83),
+ (1958, 43.36, 2.85, 3.5),
+ (1957,-10.78, 3.31, 3.6),
+ (1956, 6.56, 1.49, 2.9),
+ (1955, 31.56, -0.37, 2.5),
+ (1954, 52.62, 0.75, 2.37),
+ (1953, -0.99, 0.75, 2.71),
+ (1952, 18.37, 1.92, 2.19),
+ (1951, 24.02, 7.88, 2.00),
+ (1950, 31.71, 1.26, 1.98),
+ (1949, 18.79, -1.24, 2.21),
+ (1948, 5.50, 8.07, 2.40),
+ (1947, 5.71, 14.36, 2.01),
+ (1946, -8.07, 8.33, 1.64),
+ (1945, 36.44, 2.27, 1.67),
+ (1944, 19.75, 1.73, 1.86),
+ (1943, 25.90, 6.13, 2.05),
+ (1942, 20.34, 10.88, 2.36),
+ (1941,-11.59, 5.00, 2.10),
+ (1940, -9.78, 0.72, 2.76),
+ (1939, -0.41, -1.42, 2.76),
+ (1938, 31.12, -2.08, 2.94),
+ (1937,-35.03, 3.60, 2.76),
+ (1936, 33.92, 1.46, 3.39),
+ (1935, 47.67, 2.24, 2.76),
+ (1934, -1.44, 3.08, 2.76),
+ (1933, 53.99, -5.11, 4.71),
+ (1932, -8.19, -9.87, 4.71),
+ (1931,-43.34, -8.90, 3.99),
+ (1930,-24.90, -2.34, 4.71),
+ (1929, -8.42, 0.00, 4.27) ]
+ mutable_default_parameters.__init__(self)
+
+ def report_year(self, year):
+ if self.selection_index is None:
+ self.selection_index = random.randint(0,
+ len(self.historical_tuples) - 1)
+ self.selection_duration = 1
+
+ t = self.historical_tuples[self.selection_index]
+ sim_year = t[0]
+ stock_return = t[1]
+ inflation = t[2]
+ bond_return = t[3]
+ print
+ print "## REPLAY YEAR %d" % sim_year
+ inflation_multiplier = utils.convert_rate_to_multiplier(inflation)
+ self.set_average_inflation_multiplier(inflation_multiplier)
+ print "## INFLATION is %s (%f)" % (
+ utils.format_rate(inflation_multiplier),
+ inflation_multiplier)
+ ss_multiplier = inflation_multiplier
+ if ss_multiplier >= 1.0:
+ ss_multiplier -= 1.0
+ ss_multiplier *= 0.6666
+ ss_multiplier += 1.0
+ self.set_average_social_security_multiplier(ss_multiplier)
+ print "## SS is %s (%f)" % (
+ utils.format_rate(self.get_average_social_security_multiplier()),
+ ss_multiplier)
+
+ # Assumes 50/50 Stocks/Bonds portfolio
+ our_return = (stock_return * 0.5 +
+ bond_return * 0.5)
+ self.set_average_investment_return_multiplier(utils.convert_rate_to_multiplier(our_return))
+ print "## 50/50 INVESTMENTS RETURN is %s" % utils.format_rate(self.get_average_investment_return_multiplier())
+ self.selection_duration += 1
+ self.selection_index -= 1
+ if self.selection_index < 0 or random.randint(1, 100) < 20:
+ self.selection_index = None
+ self.selection_duration = None
+