Improvements

  • compute tax rate - dividends and cap gains not paid until end for roth 401k
  • save 30% more because taxes not taken out? (only traditional IRA)
    • this will be in a personal savings. OR just look at
  • contribute more with inflation

Notes

  • Because of how much we earn, we cannot deduct taxes from traditional IRA contributions (>70k) or contribute to Roth IRA (>120k). Therefore. Only compare 401k and personal savings.

Roth 401k vs. savings account:

- Roth: don't pay taxes on any dividends or gains
- Savings account: pay yearly taxes on dividends and pay taxes on gains when withdraw

In [5]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from collections import defaultdict
%matplotlib inline

In [29]:
starting_balance = 0
max_contrib_401k = 19000
roth_fraction = 1
annual_401k_fee = .007

tax_rate_now = .3
tax_rate_old = .2

annual_roi = .06
annual_dividend = .02
inflation = .03

In [40]:
# Compute balance over time for roth 401k
balance_dict = defaultdict(list)
N_years = 30
for y in np.arange(N_years+1):
    if y == 0:
        money_added, gains_savings, gains_401k, new_balance_savings, new_balance_401k, fees, dividend_tax = 0, 0, 0, 0, 0, 0, 0
    else:
        if y <= 2:
            money_added = max_contrib_401k
        else:
            money_added = 0
        
        gains_savings = balance_dict['y_balance_savings'][-1] * annual_roi
        dividend_tax = balance_dict['y_balance_savings'][-1] * annual_dividend * tax_rate_now
        new_balance_savings = balance_dict['y_balance_savings'][-1] + gains_savings + money_added - dividend_tax
        
        gains_401k = balance_dict['y_balance_401k'][-1] * annual_roi
        new_balance_401k = balance_dict['y_balance_401k'][-1] + gains_401k + money_added
        fees = new_balance_401k * annual_401k_fee
    
    balance_dict['y_added'].append(money_added)
    balance_dict['y_gains_savings'].append(gains_savings)
    balance_dict['y_gains_401k'].append(gains_401k)
    balance_dict['y_balance_savings'].append(new_balance_savings)
    balance_dict['y_balance_401k'].append(new_balance_401k - fees)
    balance_dict['y_fees'].append(fees)
    balance_dict['y_dividend_tax'].append(dividend_tax)
    balance_dict['years'].append(y)
df = pd.DataFrame(balance_dict)

In [41]:
df


Out[41]:
y_added y_gains_savings y_gains_401k y_balance_savings y_balance_401k y_fees y_dividend_tax years
0 0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0
1 19000 0.000000 0.000000 19000.000000 18867.000000 133.000000 0.000000 1
2 19000 1140.000000 1132.020000 39026.000000 38726.026860 272.993140 114.000000 2
3 0 2341.560000 2323.561612 41133.404000 40762.241352 287.347119 234.156000 3
4 0 2468.004240 2445.734481 43354.607816 42905.520003 302.455831 246.800424 4
5 0 2601.276469 2574.331200 45695.756638 45161.492244 318.358958 260.127647 5
6 0 2741.745398 2709.689535 48163.327497 47536.083507 335.098272 274.174540 6
7 0 2889.799650 2852.165010 50764.147181 50035.530777 352.717740 288.979965 7
8 0 3045.848831 3002.131847 53505.411129 52666.398986 371.263638 304.584883 8
9 0 3210.324668 3159.983939 56394.703330 55435.598244 390.784680 321.032467 9
10 0 3383.682200 3326.135895 59440.017310 58350.402000 411.332139 338.368220 10
11 0 3566.401039 3501.024120 62649.778245 61418.466137 432.959983 356.640104 11
12 0 3758.986695 3685.107968 66032.866270 64647.849087 455.725019 375.898669 12
13 0 3961.971976 3878.870945 69598.641048 68047.032992 479.687040 396.197198 13
14 0 4175.918463 4082.821979 73356.967665 71624.945986 504.908985 417.591846 14
15 0 4401.418060 4297.496759 77318.243919 75390.985646 531.457099 440.141806 15
16 0 4639.094635 4523.459139 81493.429091 79355.043671 559.401113 463.909464 16
17 0 4889.605745 4761.302620 85894.074261 83527.531868 588.814424 488.960575 17
18 0 5153.644456 5011.651912 90532.354272 87919.409493 619.774286 515.364446 18
19 0 5431.941256 5275.164570 95421.101402 92542.212044 652.362018 543.194126 19
20 0 5725.266084 5552.532723 100573.840878 97408.081554 686.663213 572.526608 20
21 0 6034.430453 5844.484893 106004.828285 102529.798482 722.767965 603.443045 21
22 0 6360.289697 6151.787909 111729.089013 107920.815286 760.771105 636.028970 22
23 0 6703.745341 6475.248917 117762.459820 113595.291754 800.772449 670.374534 23
24 0 7065.747589 6815.717505 124121.632650 119568.132194 842.877065 706.574759 24
25 0 7447.297959 7174.087932 130824.200813 125855.024585 887.195541 744.729796 25
26 0 7849.452049 7551.301475 137888.707657 132472.481778 933.844282 784.945205 26
27 0 8273.322459 7948.348907 145334.697870 139437.884870 982.945815 827.332246 27
28 0 8720.081872 8366.273092 153182.771555 146769.528856 1034.629106 872.008187 28
29 0 9190.966293 8806.171731 161454.641219 154486.670683 1089.029904 919.096629 29
30 0 9687.278473 9269.200241 170173.191845 162609.579828 1146.291096 968.727847 30

In [42]:
# TODO: Compute tax on gains at end of period
final_balance_savings = df['y_balance_savings'].values[-1]
final_balance_401k = df['y_balance_401k'].values[-1]
money_input = df['y_added'].sum()
dividends_earned = df['y_dividend_tax'].sum() / tax_rate_now
balance_tax_paid = final_balance - money_input - dividends_earned
tax_owed_on = final_balance - balance_tax_paid
tax_owed = tax_owed_on * tax_rate_old
print('tax owed:', tax_owed)
print('difference between fees and dividends paid:', final_balance_savings - final_balance_401k)


tax owed: 17390.60680333488
difference between fees and dividends paid: 7563.61201725062

In [ ]:
# TODO: incorporate tax on dividends into savings