self.total_roth_withdrawals += roth_part
print "## Satisfying %s from %s with Roth money." % (utils.format_money(roth_part), self.name)
taxes.record_roth_income(roth_part)
-
- self.pretax -= pretax_part
- self.total_pretax_withdrawals += pretax_part
- print "## Satisfying %s from %s with pre-tax money." % (utils.format_money(pretax_part), self.name)
- taxes.record_ordinary_income(pretax_part)
+ if pretax_part > 0:
+ self.pretax -= pretax_part
+ self.total_pretax_withdrawals += pretax_part
+ print "## Satisfying %s from %s with pre-tax money." % (utils.format_money(pretax_part), self.name)
+ taxes.record_ordinary_income(pretax_part)
def deposit(self, amount):
self.pretax_part += amount
def has_roth(self):
return True
- def do_roth_conversion(self, amount):
- if amount <= 0:
- return 0
- if self.pretax >= amount:
- self.roth += amount
- self.pretax -= amount
- self.total_roth_conversions += amount
- print "## Executed pre-tax --> Roth conversion of %s in %s" % (
- utils.format_money(amount),
- self.get_name())
- return amount
- elif self.pretax > 0:
- actual_amount = self.pretax
- self.roth += actual_amount
- self.pretax = 0
- self.total_roth_conversions += actual_amount
- print "## Executed pre-tax --> Roth conversion of %s in %s" % (
- utils.format_money(actual_amount),
- self.get_name())
- return actual_amount
- return 0
+ def do_roth_conversion(self, amount, taxes):
+ if amount <= 0: return 0
+ amount = min(amount, self.pretax)
+ self.roth += amount
+ self.pretax -= amount
+ self.total_roth_conversions += amount
+ taxes.record_ordinary_income(amount)
+ print "## Executed pre-tax --> Roth conversion of %s in %s" % (
+ utils.format_money(amount),
+ self.get_name())
+ return amount
def dump_final_report(self):
super(age_restricted_tax_deferred_account, self).dump_final_report()
free. It keeps this pile separate from the pretax pile and
tries to estimate taxes."""
age_restricted_tax_deferred_account.__init__(
- self, total_balance, 0, name, owner)
+ self, total_balance, total_balance, name, owner)
# Override
def has_rmd(self):
raise Exception("This account has no RMDs")
# Override
- def do_roth_conversion(self, amount):
+ def do_roth_conversion(self, amount, taxes):
return 0
class brokerage_account(account):
def has_roth(self):
return False
- def do_roth_conversion(self, amount):
+ def do_roth_conversion(self, amount, taxes):
return 0
def dump_final_report(self):
money_converted = 0
for x in self.accounts:
if x.has_roth():
- amount = x.do_roth_conversion(desired_conversion_amount)
+ amount = x.do_roth_conversion(desired_conversion_amount, taxes)
money_converted += amount
desired_conversion_amount -= amount
+ if money_converted > 0:
+ return True
+ return False
def dump_report_header(self):
self.params.dump()
total_income += money_needed
money_needed = 0
- # Maybe do some opportunistic Roth conversions.
- taxes_due = taxes.approximate_taxes(
- self.params.get_federal_standard_deduction(),
- self.params.get_federal_ordinary_income_tax_brackets(),
- self.params.get_federal_dividends_and_long_term_gains_income_tax_brackets())
- total_income = taxes.get_total_income()
- tax_rate = float(taxes_due) / float(total_income)
-
- if tax_rate <= 0.14 and self.year <= 2035:
- self.do_opportunistic_roth_conversions(taxes)
-
- # These conversions will affect taxes due. Recompute
- # them now.
+ look_for_conversions = True
+ while True:
+ # Maybe do some opportunistic Roth conversions.
taxes_due = taxes.approximate_taxes(
self.params.get_federal_standard_deduction(),
self.params.get_federal_ordinary_income_tax_brackets(),
self.params.get_federal_dividends_and_long_term_gains_income_tax_brackets())
total_income = taxes.get_total_income()
tax_rate = float(taxes_due) / float(total_income)
+ print "INCOME: %s, TAXES: %s\n" % (utils.format_money(total_income), utils.format_money(taxes_due))
+
+ if (look_for_conversions and
+ tax_rate <= 0.14 and
+ taxes_due < 20000 and
+ self.year <= 2035):
+
+ look_for_conversions = self.do_opportunistic_roth_conversions(taxes)
+ # because these conversions affect taxes, spin
+ # once more in the loop and recompute taxes
+ # due and tax rate.
+ else:
+ break
# Pay taxes_due by going to find more money. This is a
# bit hacky since withdrawing more money to cover taxes