def test_when_is_end_decimal(self, when): # Computed using Google Sheet's IPMT desired = Decimal('-16.666667') args = (Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'), Decimal('0')) result = npf.ipmt(*args) if when is None else npf.ipmt(*args, when) assert_almost_equal(result, desired, decimal=5)
def test_0d_inputs(self): args = (0.1 / 12, 1, 24, 2000) # Scalar inputs should return a scalar. assert numpy.isscalar(npf.ipmt(*args)) args = (numpy.array(args[0]), ) + args[1:] # 0d array inputs should return a scalar. assert numpy.isscalar(npf.ipmt(*args))
def amortization_schedule(input_intrate, mortgage, years, down_paymnt): ##### PARAMETERS ##### # CONVERT MORTGAGE AMOUNT TO NEGATIVE BECAUSE MONEY IS GOING OUT down = down_payment(mortgage, down_paymnt) loan = mortgage - down mortgage_amount = -(loan) interest_rate = (input_intrate / 100) / 12 periods = years * 12 # CREATE ARRAY n_periods = np.arange(years * 12) + 1 ##### BUILD AMORTIZATION SCHEDULE ##### # INTEREST PAYMENT interest_monthly = npf.ipmt(interest_rate, n_periods, periods, mortgage_amount) # PRINCIPAL PAYMENT principal_monthly = npf.ppmt(interest_rate, n_periods, periods, mortgage_amount) # JOIN DATA df_initialize = list(zip(n_periods, interest_monthly, principal_monthly)) df = pd.DataFrame(df_initialize, columns=['Period', 'Interest', 'Principal']) # MONTHLY MORTGAGE PAYMENT df['Monthly Payment'] = df['Interest'] + df['Principal'] # CALCULATE CUMULATIVE SUM OF MORTAGE PAYMENTS df['Balance'] = df['Monthly Payment'].cumsum() # REVERSE VALUES SINCE WE ARE PAYING DOWN THE BALANCE df.Balance = df.Balance.values[::-1] return df
def mortgage_monthly(price, years, percent, down_paymnt): # THIS IMPLEMENTS AN APPROACH TO FINDING A MONTHLY MORTGAGE AMOUNT FROM THE PURCHASE PRICE, # YEARS, INTEREST RATE AND DOWN PAYMENT ##### PARAMETERS ##### down = down_payment(price, down_paymnt) loan = price - down mortgage_amount = -loan interest_rate = (percent / 100) / 12 periods = years * 12 # CREATE ARRAY n_periods = np.arange(years * 12) + 1 ##### BUILD AMORTIZATION SCHEDULE ##### # INTEREST PAYMENT interest_monthly = npf.ipmt(interest_rate, n_periods, periods, mortgage_amount) # PRINCIPAL PAYMENT principal_monthly = npf.ppmt(interest_rate, n_periods, periods, mortgage_amount) # JOIN DATA df_initialize = list(zip(n_periods, interest_monthly, principal_monthly)) df = pd.DataFrame(df_initialize, columns=['Period', 'Interest', 'Principal']) # MONTHLY MORTGAGE PAYMENT df['Monthly Payment'] = df['Interest'] + df['Principal'] payment = df['Monthly Payment'].mean() return payment
def test_gh_17(self, per, desired): # All desired results computed using Google Sheet's IPMT rate = 0.001988079518355057 result = npf.ipmt(rate, per, 360, 300000, when="begin") if numpy.isnan(desired): assert numpy.isnan(result) else: assert_allclose(result, desired, rtol=1e-6)
def test_broadcasting(self): desired = [ numpy.nan, -16.66666667, -16.03647345, -15.40102862, -14.76028842 ] assert_allclose( npf.ipmt(0.1 / 12, numpy.arange(5), 24, 2000), desired, rtol=1e-6, )
def test_when_is_begin_decimal(self, when): result = npf.ipmt( Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'), Decimal('0'), when, ) assert result == 0
def index(): principal = float(request.args.get('principal', 2500)) per = np.arange(1 * 12) + 1 ipmt: np.ndarray = npf.ipmt(0.0824 / 12, per, 1 * 12, principal).tolist() return_dict = (json.dumps(ipmt), 200, {"Content-Type": "application/json"}) return return_dict
def get_interest_portion_at(self, date): if before(self.date, date): return 0.0 num_intervals = get_interval_in_months(self.date, date) total_interest = 0 for p in range(num_intervals): total_interest += npf.ipmt(self.rate, p + 1, self.periods, self.amount) return total_interest
def test_decimal_broadcasting(self): desired = [ Decimal('-16.66666667'), Decimal('-16.03647345'), Decimal('-15.40102862'), Decimal('-14.76028842') ] result = npf.ipmt( Decimal('0.1') / Decimal('12'), list(range(1, 5)), Decimal('24'), Decimal('2000')) assert_almost_equal(result, desired, decimal=4)
def compute_interest(self): if self.loan_type == "fixed-annuity-begin": return -numpy_financial.ipmt( self.loan_id.loan_rate() / 100, 2, self.loan_id.periods - self.sequence + 1, self.pending_principal_amount, -self.loan_id.residual_amount, when="begin", ) return self.pending_principal_amount * self.loan_id.loan_rate() / 100
def calcLoan(self, loan=0.6, interest=0.04, years=10): quantity = loan * self.CAPEX assert quantity > 0 assert interest >= 0 and interest <= 1 assert years > 1 self.loan_payment = pmt(interest, years, quantity) self.loan_interest = ipmt(interest, np.arange(years) + 1, years, quantity) self.loan_principal = ppmt(interest, np.arange(years) + 1, years, quantity)
def loan(self, prestamo, interest, years): """Compute annual payment of a loan. Inputs: quantity [monetary units] == investment which will be funded interest [as fraction of unity] == annual interest years == number of yeras to return the loan.""" quantity = prestamo * self.capex() assert quantity > 0 assert interest >= 0 and interest <= 1 assert years > 1 loan_payment = pmt(interest, years, quantity) loan_interest = ipmt(interest, np.arange(years) + 1, years, quantity) loan_principal = ppmt(interest, np.arange(years) + 1, years, quantity) return loan_payment, loan_interest, loan_principal
def calculate_loan(self): """Compute annual payment of a loan. Inputs: quantity [monetary units] == investment which will be funded interest [as fraction of unity] == annual interest years == number of yeras to return the loan.""" assert type(self) is Loan self.res_payment = pmt(self.interest, self.years, self.quantity) self.res_interest = ipmt(self.interest, np.arange(self.years) + 1, self.years, self.quantity) self.res_principal = ppmt(self.interest, np.arange(self.years) + 1, self.years, self.quantity)
def test_broadcast(self): assert_almost_equal(npf.nper(0.075, -2000, 0, 100000., [0, 1]), [21.5449442, 20.76156441], 4) assert_almost_equal(npf.ipmt(0.1 / 12, list(range(5)), 24, 2000), [ -17.29165168, -16.66666667, -16.03647345, -15.40102862, -14.76028842 ], 4) assert_almost_equal(npf.ppmt(0.1 / 12, list(range(5)), 24, 2000), [ -74.998201, -75.62318601, -76.25337923, -76.88882405, -77.52956425 ], 4) assert_almost_equal( npf.ppmt(0.1 / 12, list(range(5)), 24, 2000, 0, [0, 0, 1, 'end', 'begin']), [ -74.998201, -75.62318601, -75.62318601, -76.88882405, -76.88882405 ], 4)
def test_broadcast_decimal(self): # Use almost equal because precision is tested in the explicit tests, # this test is to ensure broadcast with Decimal is not broken. assert_almost_equal( npf.ipmt( Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')), [ Decimal('-17.29165168'), Decimal('-16.66666667'), Decimal('-16.03647345'), Decimal('-15.40102862'), Decimal('-14.76028842') ], 4) assert_almost_equal( npf.ppmt( Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000')), [ Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-76.25337923'), Decimal('-76.88882405'), Decimal('-77.52956425') ], 4) assert_almost_equal( npf.ppmt( Decimal('0.1') / Decimal('12'), list(range(5)), Decimal('24'), Decimal('2000'), Decimal('0'), [Decimal('0'), Decimal('0'), Decimal('1'), 'end', 'begin']), [ Decimal('-74.998201'), Decimal('-75.62318601'), Decimal('-75.62318601'), Decimal('-76.88882405'), Decimal('-76.88882405') ], 4)
def test_decimal(self): result = npf.ipmt(Decimal('0.1') / Decimal('12'), 1, 24, 2000) assert result == Decimal('-16.66666666666666666666666667')
def amortization_table(interest_rate, years, payments_year, principal, addl_principal=0, start_date=date.today()): """ Calculate the amortization schedule given the loan details Args: interest_rate: The annual interest rate for this loan years: Number of years for the loan payments_year: Number of payments in a year principal: Amount borrowed addl_principal (optional): Additional payments to be made each period. Assume 0 if nothing provided. must be a value less then 0, the function will convert a positive value to negative start_date (optional): Start date. Will start on first of next month if none provided Returns: schedule: Amortization schedule as a pandas dataframe summary: Pandas dataframe that summarizes the payoff information """ # Ensure the additional payments are negative if addl_principal > 0: addl_principal = -addl_principal # Create an index of the payment dates rng = pd.date_range(start_date, periods=years * payments_year, freq='MS') rng.name = "Payment_Date" # Build up the Amortization schedule as a DataFrame df = pd.DataFrame(index=rng, columns=[ 'Payment', 'Principal', 'Interest', 'Addl_Principal', 'Curr_Balance' ], dtype='float') # Add index by period (start at 1 not 0) df.reset_index(inplace=True) df.index += 1 df.index.name = "Period" # Calculate the payment, principal and interests amounts using built in Numpy functions per_payment = npf.pmt(interest_rate / payments_year, years * payments_year, principal) df["Payment"] = per_payment df["Principal"] = npf.ppmt(interest_rate / payments_year, df.index, years * payments_year, principal) df["Interest"] = npf.ipmt(interest_rate / payments_year, df.index, years * payments_year, principal) # Round the values df = df.round(2) # Add in the additional principal payments df["Addl_Principal"] = addl_principal # Store the Cumulative Principal Payments and ensure it never gets larger than the original principal df["Cumulative_Principal"] = (df["Principal"] + df["Addl_Principal"]).cumsum() df["Cumulative_Principal"] = df["Cumulative_Principal"].clip( lower=-principal) # Calculate the current balance for each period df["Curr_Balance"] = principal + df["Cumulative_Principal"] # Determine the last payment date try: last_payment = df.query("Curr_Balance <= 0")["Curr_Balance"].idxmax( axis=1, skipna=True) except ValueError: last_payment = df.last_valid_index() last_payment_date = "{:%m-%d-%Y}".format(df.loc[last_payment, "Payment_Date"]) # Truncate the data frame if we have additional principal payments: if addl_principal != 0: # Remove the extra payment periods df = df.loc[0:last_payment].copy() # Calculate the principal for the last row df.loc[last_payment, "Principal"] = -(df.loc[last_payment - 1, "Curr_Balance"]) # Calculate the total payment for the last row df.loc[last_payment, "Payment"] = df.loc[last_payment, ["Principal", "Interest"]].sum() # Zero out the additional principal df.loc[last_payment, "Addl_Principal"] = 0 # Get the payment info into a DataFrame in column order payment_info = (df[["Payment", "Principal", "Addl_Principal", "Interest"]].sum().to_frame().T) # Format the Date DataFrame payment_details = pd.DataFrame.from_dict( dict([('payoff_date', [last_payment_date]), ('Interest Rate', [interest_rate]), ('Number of years', [years])])) # Add a column showing how much we pay each period. # Combine addl principal with principal for total payment payment_details["Period_Payment"] = round(per_payment, 2) + addl_principal payment_summary = pd.concat([payment_details, payment_info], axis=1) return df, payment_summary #df, payment_summary = amortization_table(interest_rate, years, payments_year, principal) #print(payment_summary)
def loan_interest(self): assert self.quantity > 0 assert self.interest >= 0 and self.interest <= 1 assert self.years > 1 return ipmt(self.interest, np.arange(self.years) + 1, self.years, self.quantity)
arr_15 = np.array([[1, 2], [3, 4]]) np.save('randarray', arr_15) arr_16 = np.load('randarray.npy') arr_16 np.savetxt('randcsv.csv', arr_15) arr_17 = np.loadtxt('randcsv.csv') print(arr_17) print( "#**********************#FINANCIAL FUNCTIONS#**************************#") #FINANCIAL FUNCTIONS import numpy_financial as npf npf.fv(8 / 12, 10 * 12, -400, 400) period = np.arange(1 * 12) + 1 principle = 3000.00 ipmt = npf.ipmt(0.0925 / 12, period, 1 * 12, principle) ppmt = npf.ipmt(0.0925 / 12, period, 1 * 12, principle) for payment in period: index = payment - 1 principle = principle + ppmt[index] print( f"{payment} {np.round(ppmt[index],2)} {np.round(ipmt[index],2)} {np.round(principle,2)}" ) np.round(npf.nper(0.0925 / 12, -150, 3000.00), 2) npf.npv(0.08, [-1500, 4000, 5000, 6000, 7000]) print( "#**********************#COMPARISON FUNCTIONS#**************************#") #COMPARISON FUNCTIONS
'''pmt:计算每期支付金额''' rate = 0.075 nper = 20 pv = 1000000 fv = 0 per = 240 pmt = npf.pmt(rate=rate / 12, nper=nper * 12, pv=pv, fv=fv) # rate:年化投资回报率 # nper:投资年数 # pv:现值(正值) # fv:预期达到的资产总值(正值) # per:还款的第几期 '''ppmt:每期支付金额之本金''' ppmt = npf.ppmt(rate=rate / 12, per=per, nper=nper * 12, pv=pv, fv=fv) '''ipmt:每期支付金额之利息''' ipmt = npf.ipmt(rate=rate / 12, per=per, nper=nper * 12, pv=pv, fv=fv) print( f'年利率{rate * 100}%,贷款总额¥{abs(pv)}元,{nper}年还清,每月还款¥{abs(pmt):.2f}元,第{per}期本金:¥{abs(ppmt):.2f}元,第{per}期利息:¥{abs(ipmt):.2f}元。' ) '''nper:分期数''' rate = 0.075 pmt = -8055.93 pv = 1000000 fv = 0 # rate:年利率 # pmt:每期还款金额(负值) # pv:贷款总额(正值) # fv:期末剩余贷款金额(正值) nper = npf.nper(rate=rate / 12, pmt=pmt, pv=pv, fv=fv) print( f'年利率{rate * 100}%,贷款总额¥{abs(pv)}元,每月还款¥{abs(pmt)},需要还款{nper / 12:.2f}年,共{nper:.2f}期。还款总金额:¥{-pmt * nper:.2f}元。'
df_mortgage.reset_index(inplace=True) df_mortgage.index += 1 df_mortgage.index.name = "Period" df_mortgage = df_mortgage.merge(df_rate[['Date', 'Interest_Rate_Discounted']], left_on='Date', right_on='Date', how='left') mortgage = purchase_price - initial_cap df_mortgage.loc[0, 'Payment'] = -1 * npf.pmt( df_mortgage.loc[0, 'Interest_Rate_Discounted'] / 100 / 12, mortgage_term * 12, mortgage) df_mortgage.loc[0, 'Principal Paid'] = -1 * npf.ppmt( df_mortgage.loc[0, 'Interest_Rate_Discounted'] / 100 / 12, 1, mortgage_term * 12, mortgage) df_mortgage.loc[0, 'Interest Paid'] = -1 * npf.ipmt( df_mortgage.loc[0, 'Interest_Rate_Discounted'] / 100 / 12, 1, mortgage_term * 12, mortgage) df_mortgage.loc[ 0, 'Ending Balance'] = mortgage - df_mortgage.loc[0, 'Principal Paid'] df_mortgage.loc[0, 'Accumulative Interest'] = df_mortgage.loc[0, 'Interest Paid'] for indx in df_mortgage.index[1:]: df_mortgage.loc[indx, 'Payment'] = -1 * npf.pmt( df_mortgage.loc[indx, 'Interest_Rate_Discounted'] / 100 / 12, mortgage_term * 12, df_mortgage.loc[indx - 1, 'Ending Balance']) df_mortgage.loc[indx, 'Principal Paid'] = -1 * npf.ppmt( df_mortgage.loc[indx, 'Interest_Rate_Discounted'] / 100 / 12, 1, mortgage_term * 12, df_mortgage.loc[indx - 1, 'Ending Balance']) df_mortgage.loc[indx, 'Interest Paid'] = -1 * npf.ipmt( df_mortgage.loc[indx, 'Interest_Rate_Discounted'] / 100 / 12, 1, mortgage_term * 12, df_mortgage.loc[indx - 1, 'Ending Balance'])
def calculate_loan(): amount = float(entry1.get()) months = float(entry2.get()) interest = float(entry3.get()) start_date = (entry4.get()) interest = interest / 100 interest_monthly = interest / 12 numerator = interest_monthly * ((1 + interest_monthly)**months) denominator = (1 + interest_monthly)**months - 1 payment = amount * numerator / denominator total_cost = months * payment total_interest = total_cost - amount label_calc_loan_result_result = Label(result_frame, bg='white', text="{0:.2f}".format(payment), font=('Courier', 20), anchor='n', justify='center') label_calc_loan_result_result.place(relx=0.3, rely=0.3, relwidth=0.4, relheight=0.15) label_total_principal_result = Label(result_frame, bg='white', text="{0:.2f}".format(amount), font=('Courier', 14), anchor='nw', justify='left') label_total_principal_result.place(relx=0.7, rely=0.6, relwidth=0.3, relheight=0.1) label_total_interest_result = Label(result_frame, bg='white', text="{0:.2f}".format(total_interest), font=('Courier', 14), anchor='nw', justify='left') label_total_interest_result.place(relx=0.7, rely=0.7, relwidth=0.3, relheight=0.1) label_total_cost_result = Label(result_frame, bg='white', text="{0:.2f}".format(total_cost), font=('Courier', 14), anchor='nw', justify='left') label_total_cost_result.place(relx=0.7, rely=0.8, relwidth=0.3, relheight=0.1) """dataframe""" pmt = -1 * npf.pmt(interest_monthly, months, amount) ipmt = -1 * npf.ipmt(interest_monthly, 1, months, amount) ppmt = -1 * npf.ppmt(interest_monthly, 1, months, amount) rng = pd.date_range(start_date, periods=months, 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" df["Payment"] = -1 * npf.pmt(interest_monthly, months, amount) df["Principal Paid"] = -1 * npf.ipmt(interest_monthly, 1, months, amount) df["Interest Paid"] = -1 * npf.ppmt(interest_monthly, 1, months, amount) df = df.round(2) df["Ending Balance"] = 0 df.loc[1, "Ending Balance"] = amount - df.loc[1, "Principal Paid"] for period in range(2, len(df) + 1): previous_balance = df.loc[period - 1, "Ending Balance"] principal_paid = df.loc[period, "Principal Paid"] if previous_balance == 0: df.loc[period, [ 'Payment', 'Principal Paid', 'Interest Paid', 'Ending Balance' ]] == 0 continue elif principal_paid <= previous_balance: df.loc[period, 'Ending Balance'] = previous_balance - principal_paid pt = Table(table_frame, dataframe=df) pt.show()
def calc_total_interest(int_rate,payment_periods,princ): pay_per = np.arange(payment_periods)+1 return sum(npf.ipmt(int_rate/12,pay_per,payment_periods,princ))
# Amortorization schedule calculator import numpy_financial as npf import numpy as np # Amoritization Schedule principal = 2_500 years = 1 rate = 0.0824 per = np.arange(years * 12) + 1 ipmt = npf.ipmt(rate / 12, per, years * 12, principal) ppmt = npf.ppmt(rate / 12, per, years * 12, principal) pmt = npf.pmt(rate / 12, per, years * 12, principal) fmt = '{0:2d} {1:8.2f} {2:8.2f} {3:8.2f}' # formatting for payment in per: index = payment - 1 principal = principal + ppmt[index] print(fmt.format(payment, ppmt[index], ipmt[index], principal))
import pandas as pd import numpy as np import numpy_financial as npf import matplotlib.pyplot as plt from collections import namedtuple """ Basic Calculation -- fix coupon, no default, no prepayment """ # loan characteristics orig_bal = 5e05 coupon = 0.08 term = 120 # payments periods = range(1, term + 1) int_payment = npf.ipmt(rate=coupon / 12, per=periods, nper=term, pv=-orig_bal) prin_payment = npf.ppmt(rate=coupon / 12, per=periods, nper=term, pv=-orig_bal) # stacked area plot with relationship between interest and principle over loan life # plt.stackplot(periods, int_payment, prin_payment, labels=['Interest', 'Principle']) # plt.legend(loc='upper left') # plt.xlabel("Period") # plt.ylabel("Payment") # plt.margins(0, 0) # plt.show() # cash flow table cf_table = pd.DataFrame({ 'Interest': int_payment, 'Principle': prin_payment }, index=periods)
def test_when_is_end(self, when): if when is None: result = npf.ipmt(0.1 / 12, 1, 24, 2000) else: result = npf.ipmt(0.1 / 12, 1, 24, 2000, 0, when) assert_allclose(result, -16.666667, rtol=1e-6)
def test_when_is_begin(self, when): assert npf.ipmt(0.1 / 12, 1, 24, 2000, 0, when) == 0
def estimateInterest(self): self.getValues() monthlyInterest = npf.ipmt(self.interest/self.numPayments, 1, self.numPayments*self.term, self.principle) print('\n Estimated monthly interest payment is $%5.2f' %abs(monthlyInterest))
def test_float(self): assert_allclose( npf.ipmt(0.1 / 12, 1, 24, 2000), -16.666667, # Computed using Google Sheet's IPMT rtol=1e-6, )