Fix a couple of bugs. Make the simulation run 100x and halt if
[retire.git] / retire.py
index 578869b402e55b04ccfec4e1e7e1e72b20cf9265..fc68655dcd63e8b1c96187090317b152472483a6 100755 (executable)
--- a/retire.py
+++ b/retire.py
@@ -1,6 +1,7 @@
 #!/usr/local/bin/python
 
 import sys
+import traceback
 
 from accounts import *
 import constants
@@ -20,6 +21,7 @@ class simulation(object):
         self.scott_age = 0
         self.alex_age = 0
         self.year = 0
+        self.max_net_worth = 0
 
     def do_rmd_withdrawals(self, taxes):
         """Determine if any account that has RMDs will require someone to
@@ -129,12 +131,20 @@ class simulation(object):
             total += x.get_balance()
             print "{:<50}: {:>14}".format(x.get_name(), x.get_balance())
         print "{:<50}: {:>14}\n".format("TOTAL", total)
+        if self.max_net_worth < total:
+            self.max_net_worth = total
 
     def dump_final_report(self, taxes):
         print "\nAGGREGATE STATS FINAL REPORT:"
+        total = money(0)
         for x in self.accounts:
             x.dump_final_report()
+            total += x.get_balance()
         taxes.dump_final_report()
+        print "    {:<50}: {:>14}".format("Max net worth achieved",
+                                          self.max_net_worth)
+        print "==> {:<50}: {:>14}".format("Final net worth of simulation",
+                                          total)
 
     def run(self):
         """Run the simulation!"""
@@ -147,6 +157,7 @@ class simulation(object):
         adjusted_lynn_annual_social_security_dollars = (
             self.params.get_initial_social_security_benefit(constants.LYNN))
 
+
         try:
             for self.year in xrange(2020, 2080):
                 self.scott_age = self.year - 1974
@@ -201,7 +212,9 @@ class simulation(object):
                         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)
+                    tax_rate = 0.0
+                    if total_income > 0:
+                        tax_rate = float(taxes_due) / float(total_income)
 
                     if (look_for_conversions and
                         tax_rate <= 0.14 and
@@ -244,16 +257,31 @@ class simulation(object):
                     adjusted_lynn_annual_social_security_dollars *= ss_multiplier
                 self.params.get_federal_ordinary_income_tax_brackets().adjust_with_multiplier(inflation_multiplier)
                 self.params.get_federal_dividends_and_long_term_gains_income_tax_brackets().adjust_with_multiplier(inflation_multiplier)
+            succeeded = True
         except Exception as e:
             print "Exception: %s" % e
+            print traceback.print_exc(e)
             print "Ran out of money!?!"
+            succeeded = False
 
         finally:
             self.dump_final_report(taxes)
+            return succeeded
 
 # main
 #params = mutable_default_parameters()
-params = mutable_dynamic_historical_parameters()
-accounts = secrets.accounts
-s = simulation(params, accounts)
-s.run()
+
+params = None
+accounts = None
+s = None
+for x in xrange(1, 100):
+    del params
+    del accounts
+    del s
+    params = mutable_dynamic_historical_parameters()
+    accounts = secrets.get_starting_account_list()
+    s = simulation(params, accounts)
+    print "====================== Simulation %d ======================" % x
+    if s.run() == False:
+        print "This simulation failed!"
+        sys.exit(0)