Source code for cashflows.savings

"""
Savings
===============================================================================


"""
# import sys
# import os

# sys.path.insert(0, os.path.abspath('..'))

from cashflows.gtimeseries import TimeSeries, cashflow, interest_rate, verify_eq_time_range



[docs]def savings(deposits, nrate, initbal=0, noprint=True): """ Computes the final balance for a savings account with arbitrary deposits and withdrawls and variable interset rate. Args: deposits (TimeSeries): deposits to the account. nrate (TimeSeries): nominal interest rate paid by the account. initbal (float): initial balance of the account. noprint (bool): prints summary report? Return: interest, end_balance (TimeSeries, TimeSeries) **Examples** >>> cflo = cashflow(const_value=[100] * 12, pyr=4) >>> nrate = interest_rate([10] * 12, pyr=4) >>> savings(deposits=cflo, nrate=nrate, initbal=0, noprint=False) # doctest: +NORMALIZE_WHITESPACE t Beginning Deposit Earned Ending Balance Interest Balance ----------------------------------------------- (0, 0) 0.00 100.00 0.00 100.00 (0, 1) 100.00 100.00 2.50 202.50 (0, 2) 202.50 100.00 5.06 307.56 (0, 3) 307.56 100.00 7.69 415.25 (1, 0) 415.25 100.00 10.38 525.63 (1, 1) 525.63 100.00 13.14 638.77 (1, 2) 638.77 100.00 15.97 754.74 (1, 3) 754.74 100.00 18.87 873.61 (2, 0) 873.61 100.00 21.84 995.45 (2, 1) 995.45 100.00 24.89 1120.34 (2, 2) 1120.34 100.00 28.01 1248.35 (2, 3) 1248.35 100.00 31.21 1379.56 >>> cflo = cashflow(const_value=[100] * 5, spec=[(0, 0), (2, 0)]) >>> nrate = interest_rate([0, 1, 2, 3, 4]) >>> savings(deposits=cflo, nrate=nrate, initbal=1000, noprint=False) # doctest: +NORMALIZE_WHITESPACE t Beginning Deposit Earned Ending Balance Interest Balance --------------------------------------------- (0,) 1000.00 0.00 0.00 1000.00 (1,) 1000.00 100.00 10.00 1110.00 (2,) 1110.00 0.00 22.20 1132.20 (3,) 1132.20 100.00 33.97 1266.17 (4,) 1266.17 100.00 50.65 1416.81 """ verify_eq_time_range(deposits, nrate) begbal = deposits.copy() interest = deposits.copy() endbal = deposits.copy() for time, _ in enumerate(deposits): if time == 0: begbal[0] = initbal interest[0] = begbal[0] * nrate[0] / 100 / nrate.pyr endbal[0] = begbal[0] + deposits[0] + interest[0] else: begbal[time] = endbal[time - 1] interest[time] = begbal[time] * nrate[time] / 100 / nrate.pyr if deposits[time] < 0 and -deposits[time] > begbal[time] + interest[time]: deposits[time] = -(begbal[time] + interest[time]) endbal[time] = begbal[time] + deposits[time] + interest[time] if noprint is True: return (interest, endbal) len_timeid = len(deposits.end.__repr__()) len_number = max(len('{:1.2f}'.format(endbal[-1])), len('{:1.2f}'.format(begbal[0])), 9) fmt_timeid = '{:<' + '{:d}'.format(len_timeid) + 's}' fmt_number = ' {:' + '{:d}'.format(len_number) + '.2f}' fmt_header = ' {:>' + '{:d}'.format(len_number) + 's}' if deposits.pyr == 1: xmajor, = deposits.start xminor = 0 else: xmajor, xminor = deposits.start txt = [] header = fmt_timeid.format('t') header += fmt_header.format('Beginning') header += fmt_header.format('Deposit') header += fmt_header.format('Earned') header += fmt_header.format('Ending') txt.append(header) header = fmt_timeid.format('') header += fmt_header.format('Balance') header += fmt_header.format('') header += fmt_header.format('Interest') header += fmt_header.format('Balance') txt.append(header) txt.append('-' * len_timeid + '-----' + '-' * len_number * 4) for time, _ in enumerate(deposits): if deposits.pyr == 1: timeid = (xmajor,) else: timeid = (xmajor, xminor) fmt = fmt_timeid + fmt_number * 4 txt.append(fmt.format(timeid.__repr__(), begbal[time], deposits[time], interest[time], endbal[time])) if deposits.pyr == 1: xmajor += 1 else: xminor += 1 if xminor == deposits.pyr: xminor = 0 xmajor += 1 print('\n'.join(txt))
# class Savings(): # """Creates a Savings object. # # Args: # deposits (Cashflow): Deposits to the account. # rate (float, Rate): Interest rate. # initbal (float): Initial balance of the account. # # Returns: # An Savigs object. # # Member functions can be used to extract information of the object. # # # # """ # def __init__(self, deposits, rate=0, initbal=0): # """ # Args: # deposits (Cashflow): deposits to the account. # rate (float, Rate): interest rate paid by the account. # initbal (float): initial balance of the accout. # # Return: # A `Savings` object. # # """ # # if not isinstance(deposits, Cashflow): # raise ValueError('deposits must be a Cashflow instance') # # nper = len(deposits) # # if isinstance(rate, (int, float)): # rate = Rate(constValue=rate, nper=nper) # # # begbal = Cashflow(nper=nper, constValue=0) # interest = Cashflow(nper=nper, constValue=0) # endbal = Cashflow(nper=nper, constValue=0) # # ## # ## balance calculation # ## # for time in range(nper): # # if time == 0: # # # begbal[time] = initbal # interest[time] = 0 # endbal[time] = begbal[time] + deposits[time] + interest[time] # # # else: # # # begbal[time] = endbal[time - 1] # interest[time] = begbal[time] * rate[time] # # if deposits[time] < 0 and -deposits[time] > begbal[time] + interest[time]: # # # deposits[time] = -(begbal[time] + interest[time]) # # # # endbal[time] = begbal[time] + deposits[time] + interest[time] # # # # self._begbal = begbal # self._deposits = deposits # self._interest = interest # self._endbal = endbal # # # ## # ## accounts # ## # def interest(self): # """Returns the earned interest as a Cashflow object.""" # return self._interest.copy() # # # def deposits(self): # # return self._deposits.copy() # # def begbal(self): # """Returns the balance at the begining of each compounding period as a # Cashflow object.""" # return self._begbal.copy() # # def endbal(self): # """Returns the balance at the ending of each compounding period as a # Cashflow object.""" # return self._endbal.copy() # # ## # ## conversion to generic cashflow object # ## # def to_cashflow(self): # """Converts the object to a equivalent cashflow.""" # nper = len(self._interest.tolist()) # cashflow = Cashflow(nper=nper) # # # for time in range(nper): # # # cashflow[time] = -self._deposits[time] # # # cashflow[0] = -self._endbal[0] # cashflow[-1] = cashflow[-1] + self._endbal[-1] # return cashflow # # # # def __repr__(self): # # txt = [''] # txt.append('') # # txt.append(' t Beginning Deposit Earned Ending') # txt.append(' balance Interest balance') # txt.append('------------------------------------------------------------') # # for time in range(len(self._deposits)): # # fmt = ' {:<3d} {:12.2f} {:12.2f} {:12.2f} {:12.2f}' # txt.append(fmt.format(time, # self._begbal[time], # self._deposits[time], # self._interest[time], # self._endbal[time])) # # return '\n'.join(txt) if __name__ == "__main__": import doctest doctest.testmod()