Shell 技巧 - 计算抵押贷款利率

作者:Dave Taylor

多年前(Fiorina 时代之前),我曾在 Hewlett-Packard 工作,那时我们的座右铭之一是“邻座综合症”。您可能听说过:构建您自己想使用的东西。这是合乎逻辑的,虽然我们常常不处于那种位置,但这无疑是许多伟大业余项目的基石。

这也是本月脚本项目的基础。在我撰写本专栏时,我住的房子“已签约”出售,并且我对一个新的地方提出了报价,这个地方离这里四英里远,而且大得多——更多的空间放置那些服务器,当然!谈论购买房屋、联排别墅、公寓甚至公寓,都离不开从友好的银行获得贷款——至少,我没有闲钱烧得银行账户发烫!

在看房时,关键问题始终变为“我能负担多少?”,而构成这个等式的变量包括您的首付金额、贷款期限、银行将向您收取的利率,以及当然,您正在考虑的房屋的基本成本。

还有更多因素,包括如果您的首付低于房价的 20% 的抵押贷款保险、税费、点数、过户费用等等,但我们将跳过这些,因为,嗯,它们令人费解地复杂,并且远远超出了本专栏或杂志的范围!

我们需要的基本计算相当复杂

M = P [ i((1 + i)**n) ] / [ ((1 + i)**n) - 1] 

在此计算中,M 是所需的每月付款;n 是每月付款总数(对于 30 年期抵押贷款,为 30 * 12);P 是本金/贷款本身的金额,i 是年利率除以 12 得出的月利率。

因此,假设您银行当前的抵押贷款利率为 5.00% APR。这意味着 i 将为 5/12 = 0.42。

Shell 脚本中的数学运算

这如何转换为 shell 脚本?令人惊讶的是,如果我们利用 bc 的强大功能并进行一些中间计算,使其易于使用并确保我们没有数学错误,那么复制公式并不太困难。

真正的技巧是确保我们从计算中获得足够的精度,这样我们就不会看到严重的舍入误差,这种误差在这种公式中会急剧增加。

为了实现这一点,每次我调用 bc 时,我都会指定 scale=6,这将给出小数点后六位的精度。这意味着上面的 5/12 计算将更正确地计算为 0.426667。

该脚本首先设置了 30 年的默认期限和 4.85% APR 的默认利率,这在撰写本文时是一个典型的利率。以下是我如何编码这些

dfltduration=30  # 30 year loan
dfltint=4.85  # 4.85% APR is the default
pmts=$(( $dfltduration * 12 )) 

该脚本将期望指定两个变量,尽管只需要一个,即本金和实际利率

princ=$1 ; int=$2 

这是一种偷懒的分配这些变量的方式,因为正如应该立即显而易见的,如果未指定它们,我们现在就有了空变量。我编写脚本的一般方法始终是从核心功能开始,然后嫁接上所有的错误测试和友好的错误。我打赌你也一样。

这有点棘手,因为我们需要规范化百分比;否则,用户会认为他们输入的是 5.25%,而公式将基于 525% 计算付款(例如,5.25 而不是 0.0525)。我将所有这些都包装在一个中

if [ -z "$int" ] ; then
  int="$(echo "scale=6; $dfltint / (100*12)" | bc -q)"
else
  int="$(echo "scale=6; $int / (100*12)" | bc -q)"
fi 

这就是设置。现在可以在将其推送到 bc 之前将计算配置为变量,以便于调试

calculation="$princ * ( $int * ((1 + $int) ^ $pmts )) / 
 ↪( ((1 + $int) ^ $pmts) - 1)" 

在继续之前,让我们看一个例子。假设我想为一套价值 30 万美元的房屋贷款,利率为 4.85% APR,期限为典型的 30 年期抵押贷款。以下是上述公式的实际样子

300000 * ( .004041 * ((1 + .004041) ^ 360 )) /
  ( ((1 + .004041) ^ 360) - 1) 

希望到目前为止,鉴于我的解释,所有这些数字都变得有意义。

最后一步只是通过将其馈送到 bc 来运行计算

payment="$(echo "scale=6; $calculation" | bc -q)" 

这仍然不太正确,因为结果值最终看起来像 1582.859358 / 月,当我们习惯了小数点后两位数字时,这有点令人困惑!

我可以在 bc 中调整它,但更改比例会产生不良的副作用,即降低所有计算的精度。相反,这是一个我之前展示过并喜欢的简单调整

payment="$(echo "$payment" | rev | cut -c5- | rev)" 

我让您自己弄清楚它的作用。

最后,输出

echo Payments: \$$payment/month for $pmts payments to pay off $princ 

让我们使用这个功能脚本运行一些计算

$ mortgage-calc.sh 300000 
Payments: $1582.85/month for 360 payments to pay off 300000 

$ mortgage-calc.sh 300000 7 
Payments: $1995.78/month for 360 payments to pay off 300000 

$ mortgage-calc.sh 500000 
Payments: $2638.09/month for 360 payments to pay off 500000 

您可以看到,即使是几个百分点的利息(7% 而不是 4.85%)也会使每月付款产生巨大差异。

现在,去寻找一套真正的好房子来购买吧!

Dave Taylor 从事 shell 脚本编写已经很长时间了,30 年。他是畅销书 Wicked Cool Shell Scripts 的作者,您可以在 Twitter 上通过 @DaveTaylor 找到他,更普遍地可以在 www.DaveTaylorOnline.com 上找到他。

加载 Disqus 评论