美文网首页解密大数据呆鸟的Python数据分析
用Python分析房屋抵押贷款 —— 带着Python玩金融(3

用Python分析房屋抵押贷款 —— 带着Python玩金融(3

作者: 鱼心DrFish | 来源:发表于2018-10-22 16:11 被阅读4次

    你打算买房了,可是你对抵押贷款却是一头雾水。每月该还多少呢?利息占多少?房子几成属于自己呢?房价上涨或下跌时怎么估算房产价值?别担心,本文将通过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年的年利率,表述成数学公式如下:

    (1 + R_{Month})^{12} = 1 + R_{Annual}

    其中 R_{Month} 是月利率, R_{Annual} 是年利率。将上述等式变换一下,我们就得到月利率的计算公式。

    R_{Month} = (1 + R_{Annual})^\frac{1}{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的学习笔记。
    更多该课程的笔记:

    相关文章

      网友评论

        本文标题:用Python分析房屋抵押贷款 —— 带着Python玩金融(3

        本文链接:https://www.haomeiwen.com/subject/wiugzftx.html