Skip to content

Instantly share code, notes, and snippets.

@jiaaro
Last active March 16, 2016 04:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jiaaro/77372db7fc131934d765 to your computer and use it in GitHub Desktop.
Save jiaaro/77372db7fc131934d765 to your computer and use it in GitHub Desktop.
Calculate the value of your investments and savings at some point in the future
class Investment(object):
def cash_invested_by_month(self, month):
raise NotImplementedError
def value_in_month(self, month):
raise NotImplementedError
class SingleInvestment(Investment):
def __init__(self, amount, monthly_interest_rate, month=0):
self.amount = float(amount)
self.start_month = month
self.interest_rate = monthly_interest_rate
def cash_invested_by_month(self, month):
return self.amount
def value_in_month(self, month):
duration = month - self.start_month
return self.amount * (self.interest_rate ** duration)
class RecurringInvestment(Investment):
def __init__(self, contribution, monthly_interest_rate, start_month=0, contribute_every_X_months=1):
self.contribution = float(contribution)
self.interest_rate = monthly_interest_rate
self.start_month = start_month
self.contribute_every_X_months = contribute_every_X_months
def _month_range_until_month(self, end_month):
return range(0, end_month - self.start_month)[::self.contribute_every_X_months]
def cash_invested_by_month(self, month):
return sum(
self.contribution
for start_month in self._month_range_until_month(month)
)
def value_in_month(self, month):
return sum(
SingleInvestment(self.contribution, self.interest_rate, month=start_month).value_in_month(month)
for start_month in self._month_range_until_month(month)
)
class Savings(object):
def __init__(self, annual_interest=1.07):
self.annual_interest = annual_interest
self.investments = []
@property
def monthly_interest(self):
return self.annual_interest ** (1.0 / 12)
@monthly_interest.setter
def monthly_interest_setter(self, val):
self.annual_interest = val ** 12.0
def invest(self, amount, every_X_months=1, start_month=0, recurring=False):
if recurring:
investment = RecurringInvestment(amount, self.monthly_interest,
contribute_every_X_months=every_X_months,
start_month=start_month)
else:
investment = SingleInvestment(amount, self.monthly_interest, start_month)
self.investments.append(investment)
def cash_invested_by_month(self, month):
return sum(i.cash_invested_by_month(month) for i in self.investments)
def value_in_month(self, month):
return sum(i.value_in_month(month) for i in self.investments)
def print_situation_in_month(self, month):
invested = self.cash_invested_by_month(month)
value = self.value_in_month(month)
print("\nSituation after {} months:".format(month))
print(" Invested: ${: >10,.0f}".format(invested))
print(" Gain: ${: >+10,.0f} ({:+0.1%})".format(value - invested, (value/invested)-1))
print("")
print("Value: ${: >0,.0f}".format(value))
s = Savings(annual_interest=1.07)
# $10k Starting cash
s.invest(10000)
# If you save $1,000 / month
s.invest(1000, recurring=True)
# …and invest $5000 in your IRA each year
s.invest(5000, recurring=True, every_X_months=12)
# value in 10 years (month 120)
s.print_situation_in_month(120)
"""
Situation after 120 months:
Invested: $ 180,000
Gain: $ +85,608 (+47.6%)
Value: $265,608
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment