見出し画像

Pythonを用いた住宅ローンシミュレーション(繰上げ返済前編)

こんにちは。分析屋のFと申します。

前回の「Pythonを用いた住宅ローンシミュレーション(導入編)」に続き、住宅ローンについてお伝えしたいと存じます。
前回の記事はこちらになります。

今回は繰上げ返済について前編と後編に分けてお伝え致します。
前編ではプログラムの処理について、後編ではシミュレーション結果に基づいて、繰上げ返済が総返済額や返済期間にどのような効果をもたらすのか、幾つかのテーマに沿って論じていきたいと思います。

本記事の構成は以下の通りとなります。



1.繰上げ返済の概要

繰上げ返済の方法は「期間短縮型」と「返済額軽減型」の2つがあります。

  • 期間短縮型
    繰上げ返済によって返済期間を短くする方法で、毎月の返済額は変わらない。

  • 返済額軽減型
    繰上げ返済によってそれ以降の毎月の返済額を少なくする方法で、返済期間は変わらない。

いずれの場合も総利息額が幾分か軽減することができます。
今回のプログラムでは返済方法は元利均等返済、繰上げ返済の方法は期間短縮型と致します。
また、繰上げ返済にかかる手数料は考慮しておりませんので、繰上げ返済される際は契約内容をしっかりご確認頂くようお願い致します。
今回も導入編同様、基本情報は金利0.8%、返済期間420ヶ月(35年)、借入額4000万と致します。


2.繰上げ返済の仕様及びフローチャート

繰上げ返済に必要な入力は以下4点となります。

  • 1回あたり繰り上げ返済概算額

  • 繰上げ返済開始時期

  • 回数

  • 間隔

期間短縮型の繰上げ返済はある回である額の繰上げ返済を行った場合、その翌月以降の元金部分を当該回で返済することになるため、入力した返済概算額がそのまま返済に充てられるるわけではありません。
そのため、入力した返済概算額が翌月の元金部分を下回っていては繰上げ返済は行われません。
他方で入力した返済概算額が翌月の元金部分に加えて、翌々月の元金部分を加算した額を下回らない限りは更にその翌月の元金部分が返済に充てられることになります。
以下のページも合わせてご参照下さい。

<フローチャート>


3.繰上げ返済のプログラム及び実行結果

<プログラム>

import numpy as np
import numpy_financial as npf
import pandas as pd
import math

##############################
#### 基本情報(元利均等返済) ####
##############################
# 金利
per = 0.8

# 返済期間(単位:月)
period = int(12*35)

# 借入額(単位:万)
repay_amount = 4000

######################
#### 繰上げ返済情報 ####
#####################
# 1回あたり繰り上げ返済概算額(単位:万)
early_repay = 500

# 繰上げ返済開始時期(例:2年目6ヶ月であれば30)
st = 49

# 回数
kai = 1

# 返済間隔(月)
turn = 1

##### 入力ここまで #####

# 月毎の返済額
repay_month = math.floor(npf.pmt(0.01*per/12, period, -repay_amount*10000))

# 各種初期化
early_col = 0
early_cnt = 0
principal_acc = 0

# 空のデータフレーム
kihon = pd.DataFrame()

# 関数定義
def short_term(x):
	if x % 12 == 0:
		y = str(math.floor(x/12))+'年'
	else:
		y = str(math.floor(x/12))+'年'+str(x%12)+'ヶ月'
	return y	

def create_term(x):
	if x % 12 == 0:
		y = str(math.ceil(x/12))+'年目12ヶ月目'
	else:
		y = str(math.ceil(x/12))+'年目'+str(x%12)+'ヶ月目'
	return y

# 償還表作成
for indx in range(1, period+1):

	if indx == 1: 
		remain = repay_amount * 10000

	# 毎月の利息
	interest = math.floor(npf.ipmt(0.01*per/12, 1, period-indx+1, -remain))
	
	# 毎月の元金
	principal = repay_month - interest
	
	# 返済済額
	principal_acc += principal
	
	# 残債
	remain = repay_amount*10000 - principal_acc
			
	kihon_new = pd.DataFrame([[indx, repay_month, interest, principal, principal_acc, remain]],
	columns=["indx", "repay_month", "interest", "principal", "principal_acc", "remain"])
	kihon = pd.concat([kihon, kihon_new])
	
# 最終月の処理
kihon['term'] = kihon['indx'].apply(create_term)
kihon.loc[kihon["indx"]==period, "principal"] = kihon.loc[kihon["indx"]==period-1, "remain"]
kihon.loc[kihon["indx"]==period, "repay_month"] = kihon.loc[kihon["indx"]==period, "principal"] + kihon.loc[kihon["indx"]==period, "interest"]
kihon.loc[kihon["indx"]==period, "principal_acc"] = repay_amount*10000
kihon.loc[kihon["indx"]==period, "remain"] = 0

print("#### 金利:", per, "%、返済期間:", period, "ヶ月、総返済額:", repay_amount, "万円によるシミュレーション結果 ####")
print("総返済額は", '¥{:,.0f}'.format(kihon["repay_month"].sum()), "です。")
print("総利息額は", '¥{:,.0f}'.format(kihon["interest"].sum()), "です。")

early = pd.DataFrame()
early_sum = 0
def early_func(x):
	def tmp():
		cnt = 0
		while kihon["principal"][x:x+cnt].sum() <= early_repay*10000: 
			cnt += 1
			if kihon["principal"][x:x+cnt].sum() == kihon["principal"][x:x+cnt-1].sum():
				break
		return cnt
	early_tmp = kihon.iloc[x:x+tmp()-1]
	early_sum = early_tmp["principal"].sum()
	early_cnt = tmp()
	early_st = early_tmp["indx"].min()
	early_ed = early_tmp["indx"].max()
	return early_st, early_ed, early_cnt, early_sum, early_tmp

print("")
print("####", early_repay, "万円の繰上げ返済を", create_term(st), "から", turn, "ヶ月間隔で", kai, "回実行した結果 ####")

for j in range(st, st + turn*kai, turn):
	if early_func(j)[3] == 0:
		break
	print(create_term(j), "繰上げ返済額は", '¥{:,.0f}'.format(early_func(j)[3]),"です。")
	early = pd.concat([early, early_func(j)[4]])
	kihon = kihon[(kihon.indx < early_func(j)[0]) | (early_func(j)[1] < kihon.indx)]
	kihon['indx'] = range(1, len(kihon.index) + 1)	
	kihon['term'] = kihon['indx'].apply(create_term)

print("総返済額は", '¥{:,.0f}'.format(kihon["repay_month"].sum()+early["principal"].sum()), "です。")	
print("繰上げ返済総額は", '¥{:,.0f}'.format(early["principal"].sum()), "です。")
print("短縮期間は", short_term(len(early)), "です。")
print("軽減額は", '¥{:,.0f}'.format(early["interest"].sum()), "です。")

実行結果は以下になります。
今回は返済5年目1ヶ月目に500万円の繰上げ返済資金を有している状況を想定しております。
導入編で出力した基本情報に加えて、繰上げ返済による短縮期間及び返済軽減額を出力致しました。

<実行結果>

#### 金利: 0.8 %、返済期間: 420 ヶ月、総返済額: 4000 万円によるシミュレーション結果 ####
総返済額は ¥45,874,024 です。
総利息額は ¥5,874,024 です。

#### 500 万円の繰上げ返済を 5年目1ヶ月目 から 1 ヶ月間隔で 1 回実行した結果 ####
5年目1ヶ月目 繰上げ返済額は ¥4,953,880 です。
総返済額は ¥44,602,136 です。
繰上げ返済総額は ¥4,953,880 です。
短縮期間は 49ヶ月 です。
軽減額は ¥1,271,888 です。


4.結言

今回は住宅ローンの繰上げ返済の処理部分にフォーカス致しました。
後編では本プログラムを実行して幾つかテーマを設けましたので、そちらについての投稿を予定しております。
次回以降もご期待頂ければと存じます。尚、本プログラムはご自身の責任においてご利用頂けますようお願いいたします。
当社はいかなる損害についても一切の責任を負いかねます。

免責事項は以下の記事に記載しております。




ここまでお読みいただき、ありがとうございました!
この記事が少しでも参考になりましたら「スキ」を押していただけると幸いです!

これまでの記事はこちら!


株式会社分析屋について

弊社が作成を行いました分析レポートを、鎌倉市観光協会様HPに掲載いただきました。

ホームページはこちら。

noteでの会社紹介記事はこちら。

【データ分析で日本を豊かに】
分析屋はシステム分野・ライフサイエンス分野・マーケティング分野の知見を生かし、多種多様な分野の企業様のデータ分析のご支援をさせていただいております。 「あなたの問題解決をする」をモットーに、お客様の抱える課題にあわせた解析・分析手法を用いて、問題解決へのお手伝いをいたします!
【マーケティング】
マーケティング戦略上の目的に向けて、各種のデータ統合及び加工ならびにPDCAサイクル運用全般を支援や高度なデータ分析技術により複雑な課題解決に向けての分析サービスを提供いたします。
【システム】
アプリケーション開発やデータベース構築、WEBサイト構築、運用保守業務などお客様の問題やご要望に沿ってご支援いたします。
【ライフサイエンス】
機械学習や各種アルゴリズムなどの解析アルゴリズム開発サービスを提供いたします。過去には医療系のバイタルデータを扱った解析が主でしたが、今後はそれらで培った経験・技術を工業など他の分野の企業様の問題解決にも役立てていく方針です。
【SES】
SESサービスも行っております。


この記事が参加している募集

やってみた