def mortgage_df(interest): rng = pd.date_range( start_date, periods=payments_per_year * term_remaining, freq='MS') rng.name = "Payment Date" df = pd.DataFrame(index=rng, columns=[ 'Payment', 'Principal Paid', 'Interest Paid', 'Ending Balance'], dtype='float') df.reset_index(inplace=True) df.index += 1 df.index.name = "Period" loan = Loan(principal=mortgage_remaining, interest=interest / 100, term=term_remaining, currency='£') for period in range(1, len(df)+1): schedule = loan.schedule(period) df.loc[period, 'Payment'] = round(schedule.payment, 2) df.loc[period, 'Ending Balance'] = round(schedule.balance, 2) df.loc[period, 'Interest Paid'] = round(schedule.total_interest, 2) df.loc[period, 'Principal Paid'] = round( mortgage_remaining - schedule.balance, 2) df = df.round(2) return df
def __init__(self, purchase_price, appraised_price, down_pct, interest, property_tax=6000, rent=1700, months=60, appreciation=.05, vacancy=.05, management=0.06, closing_cost=.015, insurance=100, capital_expenditure=.05, repair=.03, hoa=25, rent_increase=0.03): """ Parameters ---------- purchase_price : TODO appraised_price : TODO down_pct : TODO sell_at : TODO, optional appreciation : TODO, optional vacancy : TODO, optional management : TODO, optional property_tax : TODO, optional closing_cost : TODO, optiona insurrance : TODO, optional capital_expenditure : TODO, optional repair : TODO, optional """ if purchase_price < appraised_price: raise ValueError( 'Purchase price should be larger than bank appraised price.') self._purchase_price = purchase_price self._appraised_price = appraised_price self._down_pct = down_pct self._interest = interest self._rent = rent self._months = months self._appreciation = appreciation self._vacancy = vacancy self._management = management self._property_tax = property_tax self._closing_cost = closing_cost self._insurance = insurance self._capital_expenditure = capital_expenditure self._repair = repair self._hoa = hoa self._rent_increase = rent_increase self._loan = Loan(self.loan_amount, self._interest, term=30)
def Calculate(self): TotalPrice = float(self.lineEdit_TotalPrice.text()) DownPayment = float(self.lineEdit_DownPayment.text()) InterestRate = float(self.lineEdit_IntRate.text()) / 100 if self.comboBox_term.currentText() == "Months": Term = int(int(self.lineEdit_Term.text()) / 12) else: Term = int(self.lineEdit_Term.text()) PrincipalBal = TotalPrice - DownPayment loan = Loan(principal=PrincipalBal, interest=InterestRate, term=Term) APR = loan.apr APY = loan.apy MonthlyPayment = loan.monthly_payment TotalPrincipalPay = PrincipalBal TotalIntPay = loan.total_interest TotalPay = loan.total_paid InttoPrincipal = loan.interest_to_principle self.lineEdit_PrincipalBal.setText( str("{:,.2f}".format(TotalPrincipalPay))) self.lineEdit_APR.setText(str(APR)) self.lineEdit_APY.setText(str(APY)) self.lineEdit_MonthPay.setText(str("{:,.2f}".format(MonthlyPayment))) self.lineEdit_TotalPrinPay.setText( str("{:,.2f}".format(TotalPrincipalPay))) self.lineEdit_TotalIntPay.setText(str("{:,.2f}".format(TotalIntPay))) self.lineEdit_TotalPay.setText(str("{:,.2f}".format(TotalPay))) self.lineEdit_InttoPrincipal.setText(str(InttoPrincipal))
def filterListings(df): #remove non-va properties df = df[df.State == "VA"] #calc monthly HOA fee df.loc[df['AssociationFeeFrequency'] == "Quarterly", ['AssociationFee']] = df['AssociationFee'] / 4 df.loc[df['AssociationFeeFrequency'] == "SemiAnnually", ['AssociationFee']] = df['AssociationFee'] / 6 df.loc[df['AssociationFeeFrequency'] == "Annually", ['AssociationFee']] = df['AssociationFee'] / 12 #calc condo fee df['Condo/Coop Fee'] = df['Condo/Coop Fee'].replace( '[\$,)]', '', regex=True).replace('[(]', '-', regex=True).apply(f) df.loc[df['Condo/Coop Fee Freq'] == "Quarterly", ['Condo/Coop Fee']] = df['Condo/Coop Fee'] / 4 df.loc[df['Condo/Coop Fee Freq'] == "SemiAnnually", ['Condo/Coop Fee']] = df['Condo/Coop Fee'] / 6 df.loc[df['Condo/Coop Fee Freq'] == "Annually", ['Condo/Coop Fee']] = df['Condo/Coop Fee'] / 12 df = df.fillna(0) df['hoaTotalFee'] = df['Condo/Coop Fee'] + df['AssociationFee'] #remove high HOA fee df = df[df.hoaTotalFee < hoaFeeMax] df = df[df.hoaTotalFee > 99] #calc monthly taxes df['TaxMonthlyTotal'] = df['TaxAnnualTotal'] / 12 # monthly mortgage calculation intRate = mortgageRate / 100 df['List Price'] = df['List Price'].replace( '[\$,)]', '', regex=True).replace('[(]', '-', regex=True).apply(f) df = df[df['List Price'] > downPayment] for index, row in df.iterrows(): df.loc[index, 'MonthlyMortgage'] = Loan(principal=row['List Price'] - float(downPayment), interest=intRate, term=30).monthly_payment #monthly total costs: hoa + mortgage + tax + insurance df['TotalMonthlyCosts'] = df['hoaTotalFee'].astype( 'float') + df['MonthlyMortgage'].astype( 'float') + df['TaxMonthlyTotal'].astype('float') + 25 return (df)
def coc(df, principal, cash): #calculate loan loan = Loan(principal, interest=.04, term=30) pymt = loan.monthly_payment #calculate re figures mti = float(df['rent'].loc[0]) vr = float(mti * .05) er = float(mti * (.05 + .05)) me = float((100 + 50)) #water & trash mfc = float(pymt) mt = float(df['taxamt'].loc[0] / 12) mi = float(mt) #(3000/12) # Composite mcf = mti - vr - er - me - mfc - mt - mi # Annual acf = np.round((mcf * 12), 2) # Financial tci = cash coc = np.round(((acf / tci) * 100), 2) print( f'Your Annual Cashflow is ${acf} giving you a Cash-On-Cash return of {coc}%!' ) print(f'{mcf} = {mti} - {vr} - {er} - {me} - {mfc} - {mt} - {mi}') print( f'Cash Flow = Rent Income - Vacancy - Maint/Cap Exp - Water&Trash - Finance Exp - Tax - Insurance' ) coc_dict = { 'mti': mti, 'vr': vr, 'er': er, 'me': me, 'mfc': mfc, 'mt': mt, 'mi': mi, 'mcf': mcf, 'acf': acf, 'tci': tci, 'coc': coc } return coc_dict
def parse(self, response): pagesource = Selector(response) total_page = re.findall(r"\d+", response.xpath('//span[@class="pageText"]//text()').extract()[0])[1] current_page = re.findall(r"\d+", response.xpath('//span[@class="pageText"]//text()').extract()[0])[0] search_results = pagesource.xpath("//div[@class='MapHomeCardReact HomeCard']") # self.logger.info(u'User-Agent: {} {}'.format(request.headers.get('User-Agent'), request)) for search in search_results: entry = RedfinTestItem() entry['search_date'] = now.day entry['price'] = float(''.join( re.findall(r"\d+", search.xpath('.//span[@data-rf-test-name="homecard-price"]//text()').extract()[0]))) entry['street'] = search.xpath('.//span[@data-rf-test-id="abp-streetLine"]//text()').extract()[0] entry['citystatezip'] = search.xpath('.//span[@data-rf-test-id="abp-cityStateZip"]//text()').extract()[0] entry['zipcode'] = re.findall(r"\d+", search.xpath( './/span[@data-rf-test-id="abp-cityStateZip"]//text()').extract()[0]) entry['HOA'] = ''.join(re.findall(r"\d+", search.xpath( './/span[@data-rf-test-name="homecard-amenities-hoa"]//text()').extract()[0])) entry['Beds'] = null_handle(re.findall(r"\d+", search.xpath('.//div[@class="value"]//text()').extract()[0])) entry['Baths'] = null_handle( re.findall(r"\d+", search.xpath('.//div[@class="value"]//text()').extract()[1])) entry['SQFT'] = ''.join(re.findall(r"\d+", search.xpath('.//div[@class="value"]//text()').extract()[2])) entry['year_built'] = search.xpath( './/span[@data-rf-test-name="homecard-amenities-year-built"]//text()').extract() entry['rent'] = get_rent(str(entry['street']), str(entry['zipcode'])) entry['mortgage_pmt'] = float( Loan(entry['price'] * (1 - (dp_percentage)), interest, loan_term).monthly_payment) entry['insurance'] = get_insurance(entry['SQFT']) if entry['insurance'] == 0: entry['insurance'] == 60 entry['tax'] = entry['price'] * tax_rate / 12 entry['total_pmt'] = make_float(entry['HOA']) + entry['mortgage_pmt'] + entry['insurance'] + entry['tax'] entry['cashflow'] = get_cashflow(entry['rent'], entry['total_pmt']) # #, entry['price_estimate'] yield entry if int(total_page) > int(current_page): if int(current_page) == 1: next_page = response.url + "/page-2" else: next_page = re.sub(r"[page-][\d]+", "-" + str(int(current_page) + 1), response.url) yield Request(next_page, callback=self.parse)
def loan_amortization_schedule(home_cost, interest_rate_pct, mort_len_yr, down_payment_type, down_payment_value): """Calculates the amortization schedule given the home cost, interest rate, amortization length, and down payment info. Parameters ---------- home_cost : float or int interest_rate_pct : float or int Annual interest rate in dollars mort_len_yr : int Length of time over which the loan is repaid down_payment_type : str Units of the down_payment_value parameter ("Dollars" or "Percentage") down_payment_value : float or int Value of the down payment on the home in the units given by down_payment_type Returns ------- down_payment_dollars: down_payment amount in dollars principal: initial loan balance loan: mortgage.Loan contains the complete loan repayment information Examples -------- >>> print(loan_amortization_schedule(300_000, 3, 30, 'Dollars', 30_000)) (30000, 270000, <Loan principal=270000, interest=0.03, term=30>) >>> print(loan_amortization_schedule(300_000, 3, 30, 'Percentage', 10.0)) (30000.0, 270000.0, <Loan principal=270000, interest=0.03, term=30>) """ if down_payment_type == "Dollars": down_payment_dollars = down_payment_value elif down_payment_type == "Percentage": down_payment_dollars = down_payment_value / 100 * home_cost principal = home_cost - down_payment_dollars loan = Loan(principal, interest_rate_pct / 100, mort_len_yr) return down_payment_dollars, principal, loan
#https://www.mathsisfun.com/money/compound-interest-derivation.html # Continuous compounding # Monthly amortized loan or mortgage payments eigen_capital=0 #House Price House_Price=200000 #Total loan P=House_Price-eigen_capital #Yearly Interest year R=0.0145 #Total number of month numer_of_years=15 N=numer_of_years*12 r=R/12 monthly_payment=(r*((1+r)**N)*P)/((1+r)**N-1) estimate_monthly_payment=(P+0.5*P*N*r)/N print(monthly_payment) print(estimate_monthly_payment) from mortgage import Loan loan = Loan(principal=P, interest=R, term=numer_of_years) loan.summarize
def CollateralisedMortgageObligationWaterfall(cmo): dfCashflows = pd.DataFrame(columns=[ 'Month', 'Senior_principal', 'Mezzanine_principal', 'Junior_principal', 'Senior_interest', 'Mezzanine_interest', 'Junior_interest' ]) principal = np.array([ cmo['trancheSenior_principalowed'], cmo['trancheMezzanine_principalowed'], cmo['trancheJunior_principalowed'] ]) interestClaim = np.array([ cmo['trancheSenior_interestclaim'], cmo['trancheMezzanine_interestclaim'], cmo['trancheJunior_interestclaim'] ]) interestRate = cmo['interest_rate'] paymentYears = cmo['payment_years'] if sum(principal) != float( cmo['total_size']) or sum(interestClaim) != float( cmo['total_size']): print( "Principal / Interest Claim Tranche allocations do not equate to the total size!" ) return paymentPeriods = paymentYears * 12 principalExJunior = np.resize(principal, len(principal) - 1) principalPaidSubtotal = [0, 0, 0] principalTrancheFull = [False, False] interestClaimExJunior = np.resize(interestClaim, len(interestClaim) - 1) interestClaimSubTotal = [0, 0, 0] interestPaidSubTotal = [0, 0, 0] interestTrancheFull = [False, False] loan = Loan(principal=float(sum(principal)), interest=float(interestRate), term=int(paymentYears)) for m in range(paymentPeriods): principalInPeriod = float(loan.schedule(m + 1).principal) interestInPeriod = float(loan.schedule(m + 1).interest) #allocate the principal payments to all tranches sequentially #except Junior when these are not full principalCashflowsForPeriod = np.array([0, 0, 0]) for i in range(len(principalExJunior)): if principalPaidSubtotal[i] < principal[i]: principalPaidSubtotal[i] += principalInPeriod principalCashflowsForPeriod[i] = principalInPeriod break else: principalTrancheFull[i] = True #when full, allocate to the Junior tranche TrueList = [j for j, x in enumerate(principalTrancheFull) if x] if len(TrueList) == len(principalExJunior): i += 1 principalPaidSubtotal[i] = +principalInPeriod principalCashflowsForPeriod[len(principalCashflowsForPeriod) - 1] = principalInPeriod #allocate the interest payments to all tranches sequentially #except Junior when these are not full interestCashflowsForPeriod = np.array([0, 0, 0]) for i in range(len(interestClaimExJunior)): if interestClaimSubTotal[i] < interestClaim[i]: interestClaimSubTotal[i] += principalInPeriod interestPaidSubTotal[i] += interestInPeriod interestCashflowsForPeriod[i] = interestInPeriod break else: interestTrancheFull[i] = True #when full, allocate to the Junior tranche TrueList = [j for j, x in enumerate(interestTrancheFull) if x] if len(TrueList) == len(interestClaimExJunior): i += 1 interestPaidSubTotal[i] += interestInPeriod interestCashflowsForPeriod[len(interestCashflowsForPeriod) - 1] = interestInPeriod #add the cashflows to the dataframe row = np.append(np.append(m + 1, principalCashflowsForPeriod), interestCashflowsForPeriod) dfCashflows.loc[len(dfCashflows)] = row dfCashflows.plot.area(x='Month', y=[ 'Senior_principal', 'Mezzanine_principal', 'Junior_principal', 'Senior_interest', 'Mezzanine_interest', 'Junior_interest' ], color=[ 'navy', 'royalblue', 'slategrey', 'steelblue', 'cornflowerblue', 'aqua' ]) plt.suptitle('CMO Cashflows by Tranche Type \n Size ' + str(sum(principal) / 1000000) + 'mm, ' + str(paymentYears) + ' years, Interest Rate ' + str(interestRate)) plt.show() print(dfCashflows[[ 'Senior_principal', 'Mezzanine_principal', 'Junior_principal', 'Senior_interest', 'Mezzanine_interest', 'Junior_interest' ]].sum())
df_A = mortgage_df(options['a']['interest_rate']) df_A """ --- # Option B """ df_B = mortgage_df(options['b']['interest_rate']) df_B """ --- # Option C """ df_C = mortgage_df(options['c']['interest_rate']) df_C """ --- """ loan = Loan(principal=200000, interest=.06, term=30) loan loan.schedule(1).payment loan.schedule(2).payment loan.schedule(3).payment
def loan_200k(): return Loan(principal=200000, interest=.06, term=30)
from mortgage import Loan import locale loan = Loan(principal=300000.16, interest=6/100, term=int(120/12)) print(loan.summarize) print("Total principal payments: ", loan.total_principal) print("APR : ", loan.apr) print("APY : ", loan.apy) print("Monthly Payment: ", loan.monthly_payment) print("Total interest payments: ", loan.total_interest) print("Total payments: ", loan.total_paid) print("Interest to principal: ", loan.interest_to_principle) print("Years to pay: ", loan.years_to_pay)
import locale locale.setlocale(locale.LC_MONETARY, 'pt_br') from mortgage import Loan from helpers import juros_compostos if __name__ == '__main__': quantia_a_emprestar = float(input("Qual o valor a emprestar: ")) taxa_de_juros_anual = float(input("Qual a taxa de juro anual: ")) prazo = int(input("Qual o prazo: ")) valor_final_a_pagar = juros_compostos(quantia_a_emprestar, taxa_de_juros_anual, prazo) print( f"O montante total calculado é de {locale.currency(valor_final_a_pagar, grouping=True)}." ) print() print("Usando módulo Mortgage, classe Loan") financiamento = Loan(quantia_a_emprestar, taxa_de_juros_anual / 100, prazo, currency='R$') print(financiamento.summarize)
def get_loan(principal, interest, term): """ """ return Loan(principal=principal, interest=interest, term=term)
# Simple Mortgage Calculator import locale locale.setlocale(locale.LC_ALL, '') from mortgage import Loan purchaseAmount = 550000 downPayment = 200000 interestRate = .043 termInYears = 15 pmiPercent = .2 amountFinanced = purchaseAmount - downPayment loan = Loan(principal=amountFinanced, interest=interestRate, term=termInYears) totalCost = loan.n_periods * termInYears * loan.monthly_payment paymentAmount = loan.monthly_payment loanToValue = round(amountFinanced / purchaseAmount, 2) print() print("Purchase Amount:", locale.currency(purchaseAmount)) print("Down Payment:", locale.currency(downPayment)) print("Interest Rate:", interestRate) print("Term in Years:", termInYears) print("-----------------------------------------------") print() print("Monthly P&I Amount:", locale.currency(loan.monthly_payment)) print() print("Amount Financed:", locale.currency(amountFinanced))
def getItems(pageCount): for i in range(3, 28): #variable declerations, url contains pageCount to pull from different pages of the website. url = "https://www.loopnet.com/florida_apartment-buildings-for-sale/" + str( pageCount) + "/" infoList = [" "] price = "" units = "" grossIncome = "" capRate = "" ppu = 0 loanMonthlyPayment = 0 loanAmmount = 0 downPayment = 0 #get title title = getElement( "//*[@id='Form1']/div[2]/div[5]/div[1]/div[3]/div[" + str(i) + "]/div[2]/a/span").text infoList.append(title) #get city city = getElement("//*[@id='Form1']/div[2]/div[5]/div[1]/div[3]/div[" + str(i) + "]/div[2]/b").text infoList.append(city) #loop through listing details and append them to a list table = getElement( "//*[@id='Form1']/div[2]/div[5]/div[1]/div[3]/div[" + str(i) + "]/table") for row in table.find_elements_by_css_selector('tr'): for cell in row.find_elements_by_tag_name('td'): infoList.append(cell.text) #this block simply cleans up the data we retrieved from the main listing. for j in range(len(infoList)): currentEntry = infoList[j] if ("$" in currentEntry): price = currentEntry.replace("$", "") price = price.replace(",", "") if ("Units" in currentEntry): units = currentEntry.replace(" Units", "") if ("%" in currentEntry): capRate = currentEntry # this is the block where we navigate to the actual listing page in order to get more details on listing time.sleep(2) hrefValue = getElement( "//*[@id='Form1']/div[2]/div[5]/div[1]/div[3]/div[" + str(i) + "]/div[2]/a").get_attribute('href') driver.get(hrefValue) time.sleep(2) # this try catch is attempting to obtain the gross income from the listing, some dont have this section # hence the try catch block, so program doesnt crash if no icnome table exists in the listing. try: tableTwo = driver.find_element_by_css_selector( 'body > section > main > section > div.module.profile-wrapper > div.row.profile-content-wrapper > div > div > div.column-08.column-ex-large-09.column-large-09.column-medium-09.profile-main-info > div.re-order > section.financial-summary.include-in-page > div > div > table' ) trCount = 0 tdCount = 0 for row in tableTwo.find_elements_by_css_selector('tr'): for cell in row.find_elements_by_tag_name('td'): if (trCount == 1 and tdCount == 1): grossIncome = cell.text tdCount += 1 tdCount = 0 trCount += 1 except: grossIncome = "" # this may seem dumb, but I have noticed some listings have the table but have price upon request # this just validates that you do in fact have a dollar amount stored here and not text if ("$" in grossIncome): grossIncome = grossIncome else: grossIncome = "" # some listings dont have a number of units so hence the try catch block try: ppu = float(price) / float(units) except: ppu = 0 units = 0 # here we compute the loan and downpayment ammounts using the mortgage library # just a rough calculation you can change these numbers to make more accurate calculations try: loanAmmount = float(price) * 0.7 downPayment = float(price) * 0.3 loan = Loan(principal=loanAmmount, interest=0.058, term=25) loanMonthlyPayment = loan.monthly_payment except: loan = 0 loanMonthlyPayment = 0 # finally we clear the info list, print and then append all of our listing info to it for writing to CSV infoList = [" "] if (True): print(title) print(city) print(price) print(units) print(capRate) print("PPU:", ppu) print(grossIncome) print(loanMonthlyPayment) print(downPayment) infoList.append(title) infoList.append(city) infoList.append(price) infoList.append(units) infoList.append(ppu) infoList.append(downPayment) infoList.append(loanMonthlyPayment) infoList.append(capRate) infoList.append(grossIncome) # finally we append to a file, (doesnt need to be created b4 hand) # code will make one if it doesnt exist. with open('loopnet.csv', 'a') as f: writer = csv.writer(f) writer.writerow(infoList) # we then navigate back to the listings page to get details on next one in list driver.get(url) time.sleep(3) print("-" * 50)
class Engine(object): """Docstring for Engine. """ def __init__(self, purchase_price, appraised_price, down_pct, interest, property_tax=6000, rent=1700, months=60, appreciation=.05, vacancy=.05, management=0.06, closing_cost=.015, insurance=100, capital_expenditure=.05, repair=.03, hoa=25, rent_increase=0.03): """ Parameters ---------- purchase_price : TODO appraised_price : TODO down_pct : TODO sell_at : TODO, optional appreciation : TODO, optional vacancy : TODO, optional management : TODO, optional property_tax : TODO, optional closing_cost : TODO, optiona insurrance : TODO, optional capital_expenditure : TODO, optional repair : TODO, optional """ if purchase_price < appraised_price: raise ValueError( 'Purchase price should be larger than bank appraised price.') self._purchase_price = purchase_price self._appraised_price = appraised_price self._down_pct = down_pct self._interest = interest self._rent = rent self._months = months self._appreciation = appreciation self._vacancy = vacancy self._management = management self._property_tax = property_tax self._closing_cost = closing_cost self._insurance = insurance self._capital_expenditure = capital_expenditure self._repair = repair self._hoa = hoa self._rent_increase = rent_increase self._loan = Loan(self.loan_amount, self._interest, term=30) def monthly_cash_flow(self, year): pct_cost = self._vacancy + self._management \ + self._capital_expenditure + self._repair dollor_cost = self._hoa + float(self._loan.monthly_payment) \ + self._property_tax / 12 + self._insurance rent_multiplier = (1 + self._rent_increase)**year return self._rent * rent_multiplier * (1 - pct_cost) - dollor_cost @property def years(self): return int(self._months / 12) @property def loan_amount(self): return self._appraised_price * (1 - self._down_pct) @property def inital_investment(self): val = self._appraised_price * (self._down_pct + self._closing_cost) \ + (self._purchase_price - self._appraised_price) return val @property def resale_value(self): return self._purchase_price * (1 + self._appreciation)**self.years @property def payoff_at_sale(self): return float(self._loan.schedule(self._months).balance) @property def profit_from_sale(self): return self.resale_value * (1 - 0.06) - self.payoff_at_sale @property def net_cash_flow(self): cash_flow = 0 for i in range(self.years): cash_flow += 12 * self.monthly_cash_flow(i) return cash_flow @property def net_profit(self): return self.profit_from_sale + self.net_cash_flow - self.inital_investment def annual_return(self, type='compound'): if type == 'compound': return (self.net_profit / self.inital_investment + 1)**(1 / self.years) - 1 if type == 'average': return self.net_profit / self.inital_investment / self.years raise NotImplementedError
avg_run = list(map(lambda x: sum(x) / len(x), zip(*evolutions))) # In[10]: plt.plot(avg_run) plt.xlabel('months') plt.ylabel("Intensity") # # Mortgage computation # - What will be the monthly payment, when I borrow for the powerplant # In[11]: from mortgage import Loan loan = Loan(principal=65000000, interest=.03, term=20) loan.summarize # In[12]: loan.monthly_payment # # One step of the evolution # - This will be used in monte carlo simulation after we obtain the optimal decision strategy from the ADP optimization. # # - Price evolution of power, gas and CO2. # - Evolution of the government policy # - Evolution of project state based on actions # - Evolution of repayment of the loans based on the state. #
#!/usr/bin/env python from mortgage import Loan loan = Loan(principal=200000, interest=.03, term=15) print('{:>4} {:>10s} {:>10s} {:>10s} {:>10s}'.format('', 'payment', 'interest', 'principal', 'remaining')) print('{:>4} {:>10s} {:>10s} {:>10s} {:>10s}'.format('', '-------', '--------', '---------', '---------')) for installment in loan.schedule(): print('{:>4}: {:>10.02f} {:>10.02f} {:>10.02f} {:>10.02f}'.format( installment.number, installment.payment, installment.interest, installment.principal, installment.balance)) loan.summarize