Python:计算贷款支付的更智能方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1525611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:29:17  来源:igfitidea点击:

Python: smarter way to calculate loan payments

pythonalgorithmmathfinance

提问by googletorp

How to calculate the monthly fee on a loan?

如何计算贷款的月费?

Given is:

给定的是:

  • a: an amount to loan.
  • b: the loan period (number of months).
  • c: the interest rate p.a. (interests is calculated and added every month, 1/12 of the interest is added. So if the interest is on 12%, 1% interest is added every month).
  • d: the amount of money owed after the end of the period.
  • a:贷款金额。
  • b:贷款期限(月数)。
  • c:利率pa(按月计算加息,加息的1/12。所以如果利率是12%,则每个月加息1%)。
  • d:期末欠款金额。

This problem is a bit different than the usual since, the goal is not to have the loan payed after the loan period has ended, but to still owe an amount that is given. I have been able to find an algorithm so solve the problem if I wanted to pay the entire amount, but it will of course not work for this problem where the goal is to end up owing a given amount rather than not owing anything.

这个问题与通常的问题有点不同,因为目标不是在贷款期结束后支付贷款,而是仍然欠给定的金额。如果我想支付全部金额,我已经能够找到一个算法来解决问题,但它当然不适用于这个目标是最终欠给定金额而不是不欠任何东西的问题。

I managed to make a solution to this problem by starting with an guess and then keep on improving that guess until it was close enough. I wondered however, if there is a better way to simply calculate this, rather than just guessing.

我设法通过猜测开始解决这个问题,然后不断改进该猜测,直到它足够接近为止。然而,我想知道是否有更好的方法来简单地计算这个,而不仅仅是猜测。

Edit: Here's how I'm doing it now.

编辑:这就是我现在的做法。

def find_payment(start, end, months, interest):
    difference = start
    guess = int(start / months * interest)
    while True:
        total = start
        for month in range(1, months + 1):
            ascribe = total * interest / 12
            total = total + ascribe - guess
        difference = total - end
        # See if the guess was good enough.
        if abs(difference) > start * 0.001:
            if difference < 0:
                if abs(difference) < guess:
                    print "payment is %s" % guess
                    return evolution(start, guess, interest, months)
                else:
                    mod = int(abs(difference) / start * guess)
                    if mod == 0:
                        mod = 1
                    guess -= mod
            else:
                mod = int(difference / start * guess)
                if mod == 0:
                    mod = 1
                guess += mod
        else:
            print "payment is %s" % guess
            return evolution(start, guess, interest, months)

evolution is just a function that displays how the loan would look like payment for payment and interest for interest, summing up total amount of interest paid etc.

进化只是一个函数,它显示贷款的支付方式和利息支付方式,汇总支付的利息总额等。

An example would be if I wanted to find out the monthly payments for a loan starting with $100k and ending at $50k with an interest of 8% and a duration of 70 months, calling

一个例子是,如果我想找出一笔贷款的每月还款额,从 10 万美元到 5 万美元,利息为 8%,期限为 70 个月,请致电

>>> find_payment(100000, 50000, 70, 0.08)
payment is 1363

In the above case I would end up owing 49935, and I went through the loop 5 times. The amount of times needed to go through the loop depends on how close I want to get to the amount and it varies a bit.

在上述情况下,我最终会欠 49935,并且我经历了 5 次循环。通过循环所需的次数取决于我想要达到该数量的程度,并且它会有所不同。

回答by JDunkerley

This is a basically a mortgage repayment calculation.

这基本上是一个按揭还款计算

Assuming that start is greater than end, and that interest is between 0 and 1 (i.e. 0.1 for 10% interest)

假设开始大于结束,并且利息在 0 和 1 之间(即 0.1 表示 10% 的利息)

First consider the part of the payment you want to pay off.

首先考虑您要还清的付款部分。

Principal = start - end

The monthly payment is given by:

每月付款由以下方式提供:

pay_a = (interest / 12) / (1 - (1+interest/12) ^ (-months))) * Principal

You then need to consider the extra interest. Which is just equal to the remaining principal times the monthly interest

然后你需要考虑额外的利息。刚好等于剩余本金乘以每月利息

pay_b = interest / 12 * end

So the total payment is

所以总付款是

payment = (interest / 12) * (1 / (1 - (1+interest/12) ^ (-months))) * Principal + end)

On the example you gave of

在你给出的例子中

Start: 100000
End:  50000
Months: 70
Interest: 8% 
pay_a = 896.20
pay_b = 333.33
Payment = 1229.54

When I tested these values in Excel, after 70 payments the remaing loan was 50,000. This is assuming you pay the interest on the notional before the payment is made each month.

当我在 Excel 中测试这些值时,70 次付款后,剩余贷款为 50,000。这是假设您在每月付款之前支付名义利息。

回答by Jitse Niesen

Perhaps the easiest way to think about this is to split the loan in two parts, one part which is to be repaid in full and another part where you don't pay off anything. You have already computed the monthly fee for the first part.

也许最简单的考虑方法是将贷款分成两部分,一部分是要全额偿还的,另一部分是您不还清任何东西的。您已经计算了第一部分的月费。

回答by NawaMan

You can keep paying the interest of every month; then, you will alway owe the same amont.

您可以继续支付每个月的利息;那么,你将永远欠同样的amont。

Owe_1 = a

Int_2 = Owe_1*(InterestRate/12)
Pay_2 = Int_2
Owe_2 = Owe_1 + Int_2 - Pay_2 # ==> Owe_1 + Int_2 - Int_2 = Owe_1

Int_3 = Owe_2*(InterestRate/12)
Pay_3 = Int_3
Owe_3 = Owe_2 + Int_3 - Pay_3 # ==> Owe_2 + Int_3 - Int_3 = Owe_2 = Owe_1

回答by Emil George James

python code to calculate emi

计算emi的python代码

class EMI_CALCULATOR(object):
 # Data attributes
 # Helps to calculate EMI

  Loan_amount = None # assigning none values
  Month_Payment = None # assigning none values
  Interest_rate = None #assigning none values
  Payment_period = None #assigning none values

  def get_loan_amount(self):
 #get the  value of loan amount
      self.Loan_amount = input("Enter The Loan amount(in rupees) :")
      pass

  def get_interest_rate(self):
   # get the value of interest rate
      self.Interest_rate = input("Enter The Interest rate(in percentage(%)) : ")
      pass

  def get_payment_period(self):
   # get the payment period"
      self.Payment_period = input("Enter The Payment period (in month): ")
      pass


  def calc_interest_rate(self):
  # To calculate the  interest rate"
      self.get_interest_rate()

      if self.Interest_rate > 1:
         self.Interest_rate = (self.Interest_rate /100.0) 

      else:
         print "You have not entered The interest rate correctly ,please try again "
      pass

  def calc_emi(self):
  # To calculate the EMI"          

      try:

        self.get_loan_amount() #input loan amount 
        self.get_payment_period() #input payment period
        self.calc_interest_rate() #input interest rate and calculate the interest rate

      except NameError:
             print "You have not entered Loan amount (OR) payment period (OR) interest rate  correctly,Please enter and try again. "

      try:
        self.Month_Payment = (self.Loan_amount*pow((self.Interest_rate/12)+1,
                             (self.Payment_period))*self.Interest_rate/12)/(pow(self.Interest_rate/12+1,
                             (self.Payment_period)) - 1)

      except ZeroDivisionError: 
                    print "ERROR!! ZERO DIVISION ERROR , Please enter The Interest rate correctly and Try again."

      else:
         print "Monthly Payment is : %r"%self.Month_Payment
      pass


  if __name__ == '__main__':# main method 

        Init = EMI_CALCULATOR() # creating  instances


        Init.calc_emi() #to calculate EMI

for more info visit : https://emilgeorgejames.wordpress.com/2015/07/29/python-emi-equated-monthly-installment-calculator/

欲了解更多信息,请访问:https: //emilgeorgejames.wordpress.com/2015/07/29/python-emi-eqated-monthly-installment-calculator/

回答by AHT

This rather a detailed way but will give the whole payment as well

这是一种相当详细的方式,但也会支付全部款项

# Mortgage Loan that gives the balance and total payment per year

# Function that gives the monthly payment
def f1 (principle,annual_interest_rate,duration):
    r = annual_interest_rate/1200
    n = duration*12
    a=principle*r*((1+r)**n)
    b= (((1+r)**n)- 1)
    if r > 0 :
        MonthlyPayment = (a/b)
    else :
        MonthlyPayment = principle/n

    return MonthlyPayment

# Function that gives the balance
def f2 (principle,annual_interest_rate,duration,number_of_payments):
    r = annual_interest_rate/1200
    n = duration*12
    a= ((1+r)**n)
    b= ((1+r)**number_of_payments)
    c= (((1+r)**n)-1)
    if r > 0 :
        RemainingLoanBalance = principle*((a-b)/c)
    else :
        RemainingLoanBalance = principle*(1-(number_of_payments/n))

    return RemainingLoanBalance
# Entering the required values
principle=float(input("Enter loan amount: "))
annual_interest_rate=float(input("Enter annual interest rate (percent): "))
duration=int(input("Enter loan duration in years: "))

# Output that returns all useful data needed
print ("LOAN AMOUNT:",principle,"INTEREST RATE (PERCENT):",annual_interest_rate)
print ("DURATION (YEARS):",duration,"MONTHLY PAYMENT:",int(f1(principle,annual_interest_rate,duration)))


k=duration+1
BALANCE=principle
total=0
for i in range (1,k):
    TOTALPAYMENT= f1(BALANCE,annual_interest_rate,k-i)*12
    total+= TOTALPAYMENT
    BALANCE= f2(principle,annual_interest_rate,duration,12*i)
    print("YEAR:",i,"BALANCE:",int(BALANCE),"TOTAL PAYMENT",int(total))

回答by shakti singh

How about this?

这个怎么样?

def EMI_calc(principle, rate, time, frequency):
    return (principle / ((1-((1+(rate/frequency))**(-1*(time*frequency))))/(rate/frequency)))

print("""
----- Welcome to EMI programe for Python -----
""")
print("\n You have chosen to know the EMI for Loan.\n")
input('\nTo Continue Press ENTER --- to ABORT Press ctrl+c > \n')

print("\nPlease Enter amount of Loan to be taken: >\n")
principle = int(input())
print("\nEnter rate of interst (%): >\n")
rate = float(input())/100
print("\nEnter Term (Years): >\n")
time = float(input())
print("\nPlease enter the frequency of installments) : >\n")
frequency = int(input())

EMI = round(EMI_calc(principle, rate, time, frequency),0)

print("""

---------------------------------------------------------------------

""")
print(f"""
The EMI for Loan of Rs.{principle};
at interest rate of {rate*100} % for {time} years;
would be: Rs.""", EMI)

print("""

---------------------------------------------------------------------

""")

回答by Orvar Korvar

Here is a code snippet using numpy functions. This shows you the payment, principal, interest, instalment and total_amount each month. Run it and see the output. You can also check the syntax for Excel "IPMT()" and "PPMT()" functions for more explanation of the arguments. https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.pmt.html#numpy.pmt

这是使用 numpy 函数的代码片段。这会显示您每月的付款、本金、利息、分期付款和总金额。运行它并查看输出。您还可以检查 Excel“IPMT()”和“PPMT()”函数的语法,以获取对参数的更多解释。 https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.pmt.html#numpy.pmt

import math
import numpy as np
rate = 0.08
start_amount = 100000.0
end_amount = 50000.0
diff_amount = start_amount - end_amount
# nr_years = 4
payment_frequency = int (12)
nr_months = 70 # = nr_years * payment_frequency
per_np = np.arange (nr_months) + 1 # +1 because index starts with 1 here
pay_b = rate / payment_frequency * end_amount
ipmt_np = np.ipmt (rate / payment_frequency, per_np, nr_months, diff_amount) - pay_b
ppmt_np = np.ppmt (rate / payment_frequency, per_np, nr_months, diff_amount)
for payment in per_np:
    idx = payment - 1
    principal = math.fabs (ppmt_np [idx])
    start_amount = start_amount - principal
    interest = math.fabs (ipmt_np [idx])
    instalment = principal + interest
    print payment, "\t", principal, "\t", interest, "\t\t", instalment, "\t\t", start_amount
print np.sum (ipmt_np)