Skip to content

Instantly share code, notes, and snippets.

@jmomort
Last active November 21, 2015 22:17
Show Gist options
  • Save jmomort/2efbdcc151a2e3e57d75 to your computer and use it in GitHub Desktop.
Save jmomort/2efbdcc151a2e3e57d75 to your computer and use it in GitHub Desktop.

Trajectory

This "blab" allows you to play with a model of a financial future. It is designed for educational use only! Below is a plot of that future and an accompaniment of levers and dials with which to adjust the prediction.

The model is a basic "Current Cash + Income - Expenses". In each simulated year, the remaining cash is invested at an adjustable interest rate. Overly conservative taxation is also applied in the simulation.

pos: 1 The plot shows your financial trajectory based on the assumptions from below. Inflation is accounted for where possible.

RED="expenses", BLUE="income", GREEN="net worth"

pos: 10

Raw Data

Below are the calculated values for reference. Same as shown in the plot.

pos: 2

Salary

Note that max salary should be specified in today's dollars. It will be inflated automatically.

pos: 8

Assets

Specify your current available somewhat liquid cash (i.e., all your savings and investments OR debts)

Then, in the table, add other assets that are more illiquid. Specify the rate at which they increase value as well as the age at which you sell that asset. pos: 3

Expenses

Place your current high-value yearly expenses in the table below. Use ARROW KEYS to navigate the table and ADD more rows. The plot will extrapolate their growth each year. You can set a specific yearly growth rate for each expense or a default will apply. Note that the growth rate should NOT include inflation.

pos: 5

Goals

Place your future financial goals in the table below. "Yearly Cost" is a calculated field. Use ARROW KEYS to navigate the table and ADD more rows.

If you want to put a recurring expense, simply multiply its yearly cost by the number of years.

If your goal involves acquiring an asset (e.g., a house), place the appreciation rate and year you plan to sell that asset. Note that costs should be in today's dollars. Inflation (and tax) will be added dynamically.

pos: 7

Retirement

Place your predicted high-value yearly retirement expenses in the table below. Use ARROW KEYS to navigate the table and ADD more rows. The plot will extrapolate their growth each year. You can set a specific yearly growth rate for each expense or a default will apply. Note that the growth rate should NOT include inflation.

pos: 4

Temporal Info

pos: 6

##Investment Info These are some basic assumptions the model uses. They are overly conservative but are a good starting point.

#setting up the layout
##income
start_salary = slider "Starting Salary"
salary_rate = slider "Salary Increase Rate"
max_salary = slider "Max Salary"
##expense
[name,current_expenses,individual_expense_rate] = table "Expenses", [],[],[]
expense_rate = slider "Expense Increase Rate"
individual_expense_rate=update_missing(individual_expense_rate,0,expense_rate)
##retirement
[name,retire_expenses,individual_retire_rate] = table "Retirement Expenses", [],[],[]
retire_rate = slider "Retire Increase Rate"
individual_retire_rate=update_missing(individual_retire_rate,0,retire_rate)
##goal
[name, s_age, e_age, goal, goal_rate, sell_goal, yearly] = table "Goals", [], [], [], [],[],[], [-> yearly]
yearly = goal / (e_age - s_age + 1)
sell_goal
##net worth info
starting_net_worth = slider "Starting Net Worth"
[name,asset,asset_rate,sell_asset] = table "Assets",[],[],[],[]
##investment info
income_tax_rate = slider "Income Tax Rate"
capital_gains_rate = slider "Capital Gains Tax Rate"
inflation_rate = slider "Inflation Rate"
interest_rate = slider "Interest Rate"
##time info
current_age = slider "Current Age"
retire_age = slider "Retirement Age"
death_age = slider "Death Age"
#calculating everything
[asset,asset_rate,sell_asset] = add_goal_asset(goal,sell_goal,goal_rate,asset,asset_rate,sell_asset)
age = [current_age .. death_age]
income = calc_income(age,start_salary,max_salary,salary_rate,income_tax_rate,retire_age,inflation_rate,asset,asset_rate,sell_asset,capital_gains_rate)
expenses = calc_expenses(age,current_expenses, individual_expense_rate,retire_expenses,individual_retire_rate,inflation_rate,s_age,e_age,yearly,retire_age)
net_worth = calc_net_worth(income,expenses,interest_rate,capital_gains_rate,starting_net_worth)
#plotting results
res = table "Trajectory", age, income, expenses, net_worth
plot "Trajectory", age, [income, expenses, net_worth]
#simple compounding function
comp = (principle,rate,freq) -> principle*Math.pow(1+rate,freq)
update_missing = (s,m,v) ->
for x in s
if x == m
v
else
x
#simple sum
sum = (x) ->
if x.length > 0
x.reduce (t,s) -> t + s
else
0
add_goal_asset = (total,sell_goal,goal_rate,asset,asset_rate,sell_asset) ->
asset = asset.concat (total[i] for i in [0 .. (total.length - 1)] when sell_goal[i]!=0)
sell_asset = sell_asset.concat (sell_goal[i] for i in [0 .. (total.length - 1)] when sell_goal[i]!=0)
asset_rate = asset_rate.concat (goal_rate[i] for i in [0 .. (total.length - 1)] when sell_goal[i]!=0)
[asset,asset_rate,sell_asset]
#currently a salary oriented income
calc_income = (age, start_salary, max_salary, salary_rate, tax_rate, retire_age,inflation,asset,asset_rate,sell_age, capital_gains_rate) ->
for x in age
res = 0
t=x-age[0]
for i in [0 .. (asset.length - 1)]
if x == sell_age[i]
sell = comp(asset[i],asset_rate[i],t)
res+= sell - Math.max(0,(sell-asset[i])*capital_gains_rate)
#after retirement age, no estimated income from salary
if x < retire_age
#estimated income from salary after taxes
salary = comp(start_salary,salary_rate,t)
res+=Math.min(comp(max_salary,inflation,t),salary) * (1 - tax_rate)
res
#determine the cost of goals for a particular age
calc_goals = (age, s_age, e_age, yearly) ->
#first find goals that start before current age
A=(i for y,i in s_age when y <= age)
#then find goals that end after current age and get cost of goal
sum(yearly[i] for i in A when e_age[i] >= age)
#currently a growing expense model that also adds goal expenses
#note that it integrates inflation to both expenses and goals
calc_expenses = (age, expenses, expense_rates, retire,retire_rates, inflation_rate, s_age,e_age,yearly,retire_age) ->
for x in age
t = x-age[0]
goal_cost = calc_goals(x,s_age,e_age,yearly)
res = 0
if x < retire_age
for i in [0 .. (expenses.length - 1)]
res+=comp(expenses[i],expense_rates[i]+inflation_rate,t)
else
for i in [0 .. (retire.length - 1)]
res+=comp(retire[i],retire_rates[i]+inflation_rate,t)
res + comp(goal_cost,inflation_rate,t)
#does basic investment
#note that the tax is only applied when return is positive
#also note that if the principle (i.e., probably net worth) is negative, interest will accure negatively
calc_invest = (principle, interest, tax) ->
principle + principle*interest - Math.max(0,principle)*tax*interest
#uses the previous net worth + income - expense of that year to determine new net worth
calc_net_worth = (income, expense, interest_rate, capital_gains_rate,starting_net_worth) ->
for i in [0 .. (income.length - 1)]
if i is 0
starting_net_worth
else
starting_net_worth = calc_invest(income[i]-expense[i]+starting_net_worth,interest_rate,capital_gains_rate)
defs {calc_income,calc_expenses,calc_net_worth,sum,update_missing,add_goal_asset}
#!vanilla
layout [1, 2, 2, 2, 2, 1]
settings
showCodeOnLoad: true
popupWidgetEditor: true
showAuthor: true
background: ""
slider "Starting Salary",
min: 0, max: 500000, step: 1000, init: 100000
prompt: "Current Salary"
unit: "dollars"
pos: 2, order: 2
slider "Salary Increase Rate",
min: 0, max: 0.25, step: 0.001, init: 0.05
prompt: "Increase Rate"
unit: ""
pos: 2, order: 4
slider "Max Salary",
min: 0, max: 500000, step: 1000, init: 150000
prompt: "Max Salary"
unit: "dollars"
pos: 2, order: 3
slider "Starting Net Worth",
min: -500000, max: 500000, step: 1000, init: 0
prompt: "Current Cash"
unit: "dollars"
pos: 8, order: 2
table "Expenses",
title: "Yearly Pre-Retirement Expenses"
headings: ["Name", "Amount", "Growth Rate"]
widths: 100 #[100, 100]
pos: 3, order: 2
slider "Expense Increase Rate",
min: 0, max: 0.25, step: 0.001, init: 0.01
prompt: "Default Rate"
unit: ""
pos: 3, order: 3
slider "Income Tax Rate",
min: 0, max: 0.4, step: 0.001, init: 0.4
prompt: "Income Tax Rate"
unit: ""
pos: 6, order: 2
slider "Capital Gains Tax Rate",
min: 0, max: 0.2, step: 0.001, init: 0.2
prompt: "Capital Gains Rate"
unit: ""
pos: 6, order: 3
slider "Inflation Rate",
min: 0, max: 0.25, step: 0.001, init: 0.03
prompt: "Inflation Rate"
unit: ""
pos: 6, order: 4
slider "Interest Rate",
min: 0, max: 0.25, step: 0.001, init: 0.07
prompt: "Interest Rate"
unit: ""
pos: 6, order: 5
slider "Current Age",
min: 0, max: 125, step: 1, init: 25
prompt: "Current Age"
unit: ""
pos: 4, order: 2
slider "Retirement Age",
min: 0, max: 125, step: 1, init: 65
prompt: "Retirement Age"
unit: ""
pos: 4, order: 3
slider "Death Age",
min: 0, max: 125, step: 1, init: 80
prompt: "Death Age"
unit: ""
pos: 4, order: 4
table "Goals",
title: "Goals"
headings: ["Name", "Start Age","End Age", "Total Cost", "Appreciation Rate", "Sell Age", "Yearly Cost"]
widths: 100 #[100, 100]
pos: 5, order: 2
table "Trajectory",
title: "Trajectory"
headings: ["Age", "Income", "Expenses", "Net Worth"]
precision: 8
widths: 200 #[100, 100]
pos: 10, order: 2
plot "Trajectory",
title: ""
width: 600, height: 400
xlabel: "Age", ylabel: "Dollars"
# xaxis: {min: 0, max: 1}
# yaxis: {min: 0, max: 1}
series: {lines: lineWidth: 1}
colors: ["blue", "red", "green"]
grid: {backgroundColor: "white"}
pos: 1, order: 2
table "Retirement Expenses",
title: "Yearly Post-Retirement Expenses"
headings: ["Name","Amount","Growth Rate"] # ["Column 1", "Column 2"]
widths: 100 #[100, 100]
pos: 7, order: 2
slider "Retire Increase Rate",
min: 0, max: 0.25, step: 0.001, init: 0.01
prompt: "Default Rate"
unit: ""
pos: 7, order: 3
table "Assets",
title: "Other Assets"
headings: ["Name","Value","Appreciation Rate","Sell Age"] # ["Column 1", "Column 2"]
widths: 100 #[100, 100]
pos: 8, order: 3
{
"Expenses": {
"0": [
"Housing",
"Food",
"Travel",
"Other",
null
],
"1": [
0,
5200,
3000,
6000,
null
],
"2": [
0.05,
0.02,
null,
0.03,
null
]
},
"Goals": {
"0": [
"House",
"Car",
"Kid",
"Apt",
"Retire Apt"
],
"1": [
35,
27,
35,
25,
75
],
"2": [
65,
37,
56,
35,
80
],
"3": [
2000000,
50000,
300000,
200000,
100000
],
"4": [
0.06,
-0.01,
null,
null,
null
],
"5": [
75,
37,
null,
null,
null
]
},
"Trajectory": {
"0": [
null
],
"1": [
null
],
"2": [
null
],
"3": [
null
]
},
"Retirement Expenses": {
"0": [
"Housing",
"Food",
"Travel",
"Healthcare"
],
"1": [
0,
4500,
4000,
2000
],
"2": [
0.05,
0.01,
null,
0.03
]
},
"Assets": {
"0": [
null,
null
],
"1": [
null,
null
],
"2": [
null,
null
],
"3": [
null,
null
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment