你打算買房了,可是你對抵押貸款卻是一頭霧水。每月該還多少呢?利息占多少?房子幾成屬于自己呢?房價上漲或下跌時怎么估算房產價值?別擔心,本文將通過Python帶你一步步算清這其中的門道。
每月還款額
抵押貸款是指購房者將所購房屋作為抵押,從銀行獲得貸款,并且按照一定的利率分期還款給銀行。
假如你打算按揭貸款一套500萬的房子,首付三成,我們先來計算首付和貸款的金額。
import numpy as np
# 設置房屋總價值
home_value = 5000000
# 設置首付比例
down_payment_percent = 0.3
# 計算首付金額
down_payment = home_value * down_payment_percent
print("首付金額: " + str(down_payment))
# 計算貸款額度
mortgage_loan = home_value - down_payment
print("貸款金額: " + str(mortgage_loan))
首付金額: 1500000.0
貸款金額: 3500000.0
假設商業貸款的年利率是5.6%,那么在計算每月還款額之前,我們需要先將年利率換算成月利率。注意這里采用的是復利,12個月累計的復利等價于1年的年利率,表述成數學公式如下:
其中 是月利率,
是年利率。將上述等式變換一下,我們就得到月利率的計算公式。
使用該公式,在python中計算貸款的月利率。
# 設置年利率
annual_rate = 0.056
# 計算月利率
month_rate = (1 + annual_rate) ** (1/12) -1
print("貸款的月利率:", round(month_rate,6))
貸款的月利率: 0.004551
假設貸款30年,那么貸款的總期數是:
# 計算貸款期數
payment_periods = 12 * 30
print("貸款總期數:", payment_periods)
貸款總期數: 360
接下來就可以計算每月的按揭還款額了,這里采用等額本息的還款方式,即每月的還款額固定。我們可使用Numpy包中的.pmt()
函數來計算,該函數說明如下:
numpy.pmt(rate, nper, pv)
- rate:定期利率
- nper:總的支付期數
- pv:抵押貸款的總額度
# 計算每月還款額
periodic_payment = -np.pmt(rate=month_rate, nper=payment_periods, pv=mortgage_loan)
print("每月的按揭還款額: " + str(round(periodic_payment, 2)))
每月的按揭還款額: 19787.51
每期償還的本金和利息
我們采用等額本息還款,每月還款的額度固定,先支付剩余本金產生的利息,然后才歸還本金。由于貸款的額度很高,在貸款初期,主要支付的是利息部分;隨著時間的推移,利息在還款額中所占的比例將越來低,而本金部分的比例越來越高。為了說明這一點,接下來我們將具體計算利息和本金部分,并繪制其曲線圖。
首先來看第一期還款的情況,先支付貸款利息。
initial_interest = mortgage_loan * month_rate
print("第一期支付的利息: " + str(round(initial_interest, 2)))
第一期支付的利息: 15928.52
每期的還款額減去利息,剩下的才是對本金部分的還款。
initial_principal = periodic_payment - initial_interest
print("第一期支付的本金: " + str(round(initial_principal, 2)))
第一期支付的本金: 3858.99
第一期還款中利息部分占了大頭。下面我們將使用循環來計算每一期還款的利息和本金部分,并將這些數值存儲到NumPy數組中。
# 初始化numpy數組,長度等于總支付期數,初始值設為0.0
principal_remaining = np.repeat(0., payment_periods) # 剩余本金
interest_paid = np.repeat(0., payment_periods) # 每期支付的利息部分
principal_paid = np.repeat(0., payment_periods) # 每期支付的本金部分
# 計算每一期還款的利息和本金部分
for i in range(0, payment_periods):
# 將上一期還款后剩余的本金存儲在變量previous_principal_remaining中
# 如果是第一期,previous_principal_remaining的值等于總的貸款額度
if i == 0:
previous_principal_remaining = mortgage_loan
else:
previous_principal_remaining = principal_remaining[i-1]
# 根據前一次還款后剩余的本金,計算本次還款的利息和本金部分
interest_payment = previous_principal_remaining * month_rate
principal_payment = periodic_payment - interest_payment
# 在最后一次還款時,如果剩余本金小于上面計算的還款本金,
# 則還款本金將等于剩余本金
if previous_principal_remaining < principal_payment:
principal_payment = previous_principal_remaining
# 將本期還款的利息、本金和剩余本金存儲到數組中
interest_paid[i] = interest_payment
principal_paid[i] = principal_payment
principal_remaining[i] = previous_principal_remaining - principal_payment
# 輸出前5次還款的情況
if i < 5 :
print("第"+str(i+1)+"期--利息:" \
+ str(round(interest_payment,2)) + " 本金:" \
+ str(round(principal_payment,2)) + " 剩余本金" \
+ str(round(principal_remaining[i],2)))
第1期--利息:15928.52 本金:3858.99 剩余本金3496141.01
第2期--利息:15910.96 本金:3876.55 剩余本金3492264.46
第3期--利息:15893.32 本金:3894.19 剩余本金3488370.26
第4期--利息:15875.6 本金:3911.92 剩余本金3484458.35
第5期--利息:15857.79 本金:3929.72 剩余本金3480528.63
我們將用圖表更直觀的表現每期還款中利息和本金的變化。
from matplotlib import pyplot as plt # 使用matplotlib繪圖庫
%config InlineBackend.figure_format = 'retina' # 設置圖片清晰度
plt.rcParams['font.sans-serif']=['SimHei'] #設置中文字體
# 繪圖
plt.plot(interest_paid, color="red", label="利息")
plt.plot(principal_paid, color="blue", label="本金")
plt.legend(loc=2)
plt.xlabel("貸款期數")
plt.ylabel("金額")
plt.show()
從上圖中可以明顯看出,隨著時間的流逝,還款額中利息的比例越來越少,而本金的比例越來越多,這兩者的總額不變,即每期支付的還款額。這就是等額本息還款的特點。
累計的本金和利息
隨著還款時間的推移,總共還了多少本金,多少利息呢?我們可以使用numpy.cumsum()
函數來進行累積求和,它返回的是一系列迭代的和,而不是一個數字。
比如對數組[1,2,3,4,5]進行累積求和,返回的是數組[1, 1+2, 1+2+3, 1+2+3+4, 1+2+3+4+5]。
np.cumsum(np.array([1,2,3,4,5]))
array([ 1, 3, 6, 10, 15])
下面就使用numpy.cumsum()
計算累積的本金和利息,并繪制成圖表。
# 計算累計的本金
cumulative_principle = np.cumsum(principal_paid)
# 計算累積的利息
cumulative_interest = np.cumsum(interest_paid)
# 繪圖
plt.plot(cumulative_interest, color='red', label="累計的利息")
plt.plot(cumulative_principle, color='blue', label="累計的本金")
plt.legend(loc=2)
plt.xlabel("貸款期數")
plt.ylabel("金額")
plt.show()
從圖中我們看出,支付的總利息甚至比貸款額度還高,這是由于貸款期限較長,金額較高,一開始都在還利息了。
還款中累計的本金部分才對房屋所有權有貢獻,你實際擁有的房產等于首付加上累計的本金,計算如下:
# 計算所占房屋產權的比例
house_owned = down_payment_percent + (cumulative_principle/home_value)
print("10年后占有的房產:", round(house_owned[10*12],4))
print("20年后占有的房產:", round(house_owned[20*12],4))
# 繪圖
plt.plot(house_owned)
plt.xlabel("期數")
plt.ylabel("擁有房屋產權的比例")
plt.show()
10年后占有的房產: 0.4242
20年后占有的房產: 0.637
首付后,你擁有房產的30%;10年后才占有42.42%;20年后占有63.7%;直到30年后還完房貸才對房屋有100%的所有權。
房價變化的影響
我們知道,房價是會隨著時間變化的。如果房價上升,那你擁有的房產也會升值。現在假設房價以每月0.25%的速度穩步上升,讓我們來繪制你所擁有的房產隨時間的變化曲線。
首先來計算增長的房價,這里需要使用 numpy.cumprod()
函數來進行累積求乘積,類似于上節中使用的累積求和函數。比如對數組[1,2,3,4,5]進行累積求乘積,返回的是數組[1, 1x2, 1x2x3, 1x2x3x4, 1x2x3x4x5]。
np.cumprod(np.array([1,2,3,4,5]))
array([ 1, 2, 6, 24, 120])
使用 numpy.cumprod()
函數計算累積的增長率,然后乘上原先的房價,就能預測房價隨時間的變化了。
# 計算累積的增長率
growth_array = np.repeat(0.0025, payment_periods)
cumulative_growth = np.cumprod(1 + growth_array)
# 預測房價
home_value_forecast = home_value * cumulative_growth
將預測的房價乘上你對房屋所有權擁有的比例,就得到你實際擁有的房產價值。
# 預測你擁有的房產
home_value_owned = home_value_forecast * house_owned
# 繪圖
plt.plot(home_value_forecast, color='red', label="房價")
plt.plot(home_value_owned, color='blue', label="擁有的房屋產權價值")
plt.legend(loc=2)
plt.xlabel("期數")
plt.ylabel("金額")
plt.show()
從圖中看出,由于不斷增長的房價,即使沒有完成還款,大概在還款18年后,你擁有的房屋價值也超過了當初的500萬房價。這將是一項成功的投資。
先不要太過樂觀,房價并不是永遠上升的,你也需要警惕房價下跌。假設房價以每月0.45%的速度持續下跌,我們使用上述類似的方法來分析未來的房價和你所擁有房產的價值。
# 計算累積的增長率,負數表示下跌
decline_array = np.repeat(-0.0045, payment_periods)
cumulative_decline = np.cumprod(1+decline_array)
# 預測房價
home_value_forecast = home_value * cumulative_decline
# 預測你擁有的房產
home_value_owned = home_value_forecast * house_owned
# 繪圖
plt.plot(home_value_forecast, color='red', label="房價")
plt.plot(home_value_owned, color='blue', label="擁有的房屋產權價值")
plt.legend(loc=1)
plt.xlabel("期數")
plt.ylabel("金額")
plt.show()
可見即使按期還款,你所擁有的房產價值也是在不斷下跌的,這是一項失敗的投資。
這時賣掉房子也許是更好的選擇,但更差的情況是,即便你賣了房子還是還不了貸款。為了更直觀的看清這一點,我們來繪制房價和剩余應還本金的曲線圖。
plt.plot(home_value_forecast, color='red', label="房價")
plt.plot(principal_remaining, color='blue', label="剩余本金")
plt.legend(loc=1)
plt.xlabel("期數")
plt.ylabel("金額")
plt.show()
上圖中有一段時間剩余的貸款金額(藍線)高于房屋的實際價值(紅線),出現了資不抵債的情況,也就是說即使賣了房子你也還不起貸款。這也是2008年美國金融危機時發生的情況。
小結
本文對抵押貸款進行了剖析,計算了房貸每期的還款額、每期還款中本金和利息部分,以及累計還款的本金和利息,并且分析了房價上漲和下跌時的房產投資情況。
另外還學習了三個 NumPy 函數:
# 計算按揭還款額
numpy.pmt(rate, nper,pv)
# 累計求和
numpy.cumsum(array)
# 累計求乘積
numpy.cumprod(array)
注:本文是DataCamp課程Intro to Financial Concepts using Python的學習筆記。
更多該課程的筆記: