import sys
from collections import namedtuple
DivsBeforeProfit = True #False # NOTE: this changes the dividend calculation order
years=30
StartVal = 10000
TotalProfit = 7/100
Dividend = 2/100
Profit = TotalProfit-Dividend
YEAR = namedtuple( 'year_result', 'year value after_tax' )
OST = YEAR
AO = YEAR
DIV = namedtuple( 'DIVyear', 'year reinvest' )
ETF = YEAR
OST_years = []
AO_years = []
DIV_years = []
DIV_vals = list();
ETF_years = []
OST_years.append(OST(year=0, value=StartVal, after_tax=StartVal))
AO_years.append(AO(year=0, value=StartVal, after_tax=StartVal))
DIV_years.append(DIV(year=0, reinvest = 0)) # div cannot use same tuple since it appends value each year
DIV_vals.append(0) # current values after each year profit update
ETF_years.append(ETF(year = 0, value = StartVal, after_tax=StartVal))
def div( value ):
return value*Dividend
def print_year( name, year_tuple ):
print( "{0}: year {1.year}, val {1.value:.2f}, net {1.after_tax:.2f}".format(name, year_tuple) )
def tax( profit ):
if profit < 0:
return 0
if profit > 30000:
tax = 0.34
else:
tax = 0.3
return profit*tax
def hankintameno(year, meno, newVal):
coeff = 0.4
if year < 10:
coeff = 0.2
if newVal*coeff > meno:
meno = newVal*coeff
profit = newVal-meno
after_tax = newVal-tax(profit)
return after_tax
def add_year( years, use_hankintameno, profit, name ):
temp = years[-1] # last item
year = temp.year+1
newVal = temp.value*(1+profit)
if use_hankintameno:
after_tax = hankintameno( year, years[0].value, newVal )
else:
profit = newVal-years[0].value
after_tax = newVal-tax(profit)
row = YEAR(year=year, value=newVal, after_tax=after_tax)
years.append(row)
#print_year( name, row )
return row
def netDiv( grossdiv ):
return grossdiv-tax(grossdiv*0.85) # 85% is taxable
def reinvestDIVs(div_vals):
reinvest = 0
for i in div_vals:
reinvest = reinvest + netDiv(div(i))
return reinvest
def updateDIVvals(div_vals):
for idx, val in enumerate(div_vals):
div_vals[idx] = val * (1+Profit)
def DIVvalue(div_vals):
value = 0
for i in div_vals:
value = value + i
return value
def DIVafterTax(divs):
thisyear = divs[-1].year
afterTax = 0
for i in divs:
elapsed_years = thisyear-i.year
afterTax = afterTax + hankintameno(elapsed_years, i.reinvest, DIV_vals[i.year])
return afterTax
def AO_year(years):
temp = years[-1] # last item - before profit calculations
row = add_year(years, True, Profit, "AO ")
this_year = years[-1].year # last item
# dividend handling
if DivsBeforeProfit:
value = temp.value # calc this year divs before yearly profit increase????
else:
value = years[-1].value # calc this year divs after profit increase
reinvest = netDiv(div(value))
if not DivsBeforeProfit:
updateDIVvals( DIV_vals ) # add profit to old re-invests, here or line later????
divofdivs = reinvestDIVs( DIV_vals ) # calc total amount of all re-invested dividends
if DivsBeforeProfit:
updateDIVvals( DIV_vals ) # add profit to old re-invests
reinvest = reinvest + divofdivs # sum into base invest dividends
div_invest=DIV(year=this_year, reinvest = reinvest ) # all this year divs
# add this year to dividents lists
DIV_vals.append(reinvest) # profit calculated for this in next years
DIV_years.append(div_invest)
div_row = AO(year=this_year, value=DIVvalue(DIV_vals), after_tax=DIVafterTax(DIV_years))
total_row = AO(year=this_year, value=row.value + div_row.value, after_tax=row.after_tax+div_row.after_tax)
#print_year( " INI", row )
#print_year( " DIV", div_row )
return total_row
def OST_year(years):
return add_year(years, False, TotalProfit, "OST")
def ETF_year(years):
return add_year(years, True, TotalProfit, "ETF")
print( "year\tost_net\tao_net\teft_net\twinner\tost_d\tao_d\tetf_d")
def winner( highest_val, highest_name, year_result, name ):
if year_result.after_tax > highest_val:
highest_name = name
highest_val = year_result.after_tax
return highest_val, highest_name
def diffs(highest, year_result):
diff = highest-year_result.after_tax
percentage = 100*diff/year_result.after_tax
if diff != 0:
diff = -diff
return (diff, percentage)
while years:
years=years-1
etf = ETF_year( ETF_years )
ost = OST_year( OST_years )
ao = AO_year( AO_years )
if etf.year != ost.year or etf.year != ao.year:
raise Exception("years not matching")
year = etf.year
highest = 0
name = "none"
highest, name = winner( highest, name, ost, "OST")
highest, name = winner( highest, name, etf, "ETF")
highest, name = winner( highest, name, ao, "AO")
ost_d = diffs(highest, ost)
ao_d = diffs(highest, ao)
etf_d = diffs(highest, etf)
print( "{0}\t{1:.2f}\t{2:.2f}\t{3:.2f}\t{4}\t{5[0]:.2f}/{5[1]:.2f}%\t{6[0]:.2f}/{6[1]:.2f}%\t{7[0]:.2f}/{7[1]:.2f}%".format(year, ost.after_tax, ao.after_tax, etf.after_tax, name,
ost_d, ao_d, etf_d ))