Если быть более точным: когда я рассчитываю французскую амортизацию с этими входными данными:
Код: Выделить всё
Enter interest rate: 4.5
Enter loan term (in years): 10
Enter amount borrowed: 1500000
Choose amortization type (French or Italian): French
Choose payment frequency (monthly, quarterly, semi-annual, annual): annual
Вот код Python, который я использую для расчета графика амортизации:
Код: Выделить всё
import datetime as dt
from dateutil.relativedelta import relativedelta
import numpy_financial as npf
import pandas as pd
class Loan:
def __init__(self, rate, term, loan_amount, amortization_type, frequency, start=dt.date.today().isoformat()):
self.rate = rate
self.term = term
self.loan_amount = loan_amount
self.start = dt.datetime.fromisoformat(start).replace(day=1)
self.frequency = frequency
self.periods = self.calculate_periods()
self.period_rate = self.calculate_period_rate()
self.pmt = npf.pmt(self.period_rate, self.periods, -self.loan_amount)
self.amortization_type = amortization_type
self.table = self.loan_table()
def calculate_periods(self):
if self.frequency == 'monthly':
return self.term * 12
elif self.frequency == 'quarterly':
return self.term * 4
elif self.frequency == 'semi-annual':
return self.term * 2
elif self.frequency == 'annual':
return self.term
else:
raise ValueError("Unsupported frequency")
def calculate_period_rate(self):
if self.frequency == 'monthly':
return self.rate / 12
elif self.frequency == 'quarterly':
return self.rate / 4
elif self.frequency == 'semi-annual':
return self.rate / 2
elif self.frequency == 'annual':
return self.rate
else:
raise ValueError("Unsupported frequency")
def loan_table(self):
if self.frequency == 'monthly':
periods = [self.start + relativedelta(months=x) for x in range(self.periods)]
elif self.frequency == 'quarterly':
periods = [self.start + relativedelta(months=3*x) for x in range(self.periods)]
elif self.frequency == 'semi-annual':
periods = [self.start + relativedelta(months=6*x) for x in range(self.periods)]
elif self.frequency == 'annual':
periods = [self.start + relativedelta(years=x) for x in range(self.periods)]
else:
raise ValueError("Unsupported frequency")
if self.amortization_type == "French":
interest = [npf.ipmt(self.period_rate, month, self.periods, -self.loan_amount, when="end")
for month in range(1, self.periods + 1)]
principal = [npf.ppmt(self.period_rate, month, self.periods, -self.loan_amount)
for month in range(1, self.periods + 1)]
table = pd.DataFrame({'Payment': self.pmt,
'Interest': interest,
'Principal': principal}, index=pd.to_datetime(periods))
table['Balance'] = self.loan_amount - table['Principal'].cumsum()
elif self.amortization_type == "Italian":
interest = [self.loan_amount * self.period_rate]
principal_payment = self.loan_amount / self.periods
principal = [principal_payment]
payment = [interest[0] + principal[0]]
for month in range(1, self.periods):
interest_payment = (self.loan_amount - (month) * principal_payment) * self.period_rate
interest.append(interest_payment)
principal.append(principal_payment)
payment.append(interest_payment + principal_payment)
principal[-1] = self.loan_amount - sum(principal[:-1])
payment[-1] = interest[-1] + principal[-1]
table = pd.DataFrame({'Payment': payment,
'Interest': interest,
'Principal': principal}, index=pd.to_datetime(periods))
table['Balance'] = self.loan_amount - table['Principal'].cumsum()
else:
raise ValueError("Unsupported amortization type")
return table.round(2)
- платеж в размере 6750000,27 евро, основной платеж (увеличивающийся с течением времени) 0,27 евро и выплата процентов в размере 6750000 евро; в то время как в Excel я получаю (постоянный) платеж в размере 189,568,23 евро, первоначальный (увеличивающийся со временем) основной платеж в размере 122,068,23 евро и выплату процентов в размере 67 500 евро, что, однако, неверно в последующих периодах, поскольку в моем коде Python во втором периоде выплата процентов составляет около 64 000 евро, а в моем файле Excel - около 62 000 евро).
Может ли кто-нибудь помочь мне понять, что может быть причиной этих несоответствий и как их устранить?