期間短縮型と返済額軽減型|住宅ローンの繰上げ返済の2つの選択肢を解説
tadanori
Aruの雑記(Aruaru0)
60歳で確定拠出年金を受け取る予定ですが、一時金と60~65歳の間の5年間に年金でもらう額の最適解を解く方法を考えてみました。まだ、情報が不足している気がしますが、とりあえず「個人メモ」としてブログに残しておきます。
確定拠出年金を「一時金で受け取る」か、「年金で受け取るか」って結構複雑です。これを検討するために、受け取り金額等から計算するPythonコードを作成してみました。
個人的なメモのようなコードですが、参考になれば幸いです
以下がPythonのプログラムです。一応、ざっと目を通しましたが細かな部分で勘違いがあるかもしれません。
処理としては、受取金額を一時金の額を「0〜全額まで、1万円づつ変化させて最適なポイントを見つける」という力技のプログラムになります。
利用する場合は、以下の部分を自分のデータに変更します
# 実行例:
X_man = 2000 # DC総額: 2000万円
Y_man = 100 # 別途所得: 100万円
N_years = 5 # 控除年数(加入年数): 10年Y_manは、60歳から別途収入がある場合を想定しています。なければ0(ゼロ)にします。
def calculate_income_tax(taxable_income):
"""所得税の計算(令和基準・累進課税)"""
if taxable_income <= 0: return 0
elif taxable_income <= 1950000: return taxable_income * 0.05
elif taxable_income <= 3290000: return taxable_income * 0.10 - 97500
elif taxable_income <= 6950000: return taxable_income * 0.20 - 427500
elif taxable_income <= 9000000: return taxable_income * 0.23 - 636000
elif taxable_income <= 18000000: return taxable_income * 0.33 - 1536000
elif taxable_income <= 40000000: return taxable_income * 0.40 - 2796000
else: return taxable_income * 0.45 - 4796000
def get_retirement_deduction(n_years):
"""退職所得控除額の計算"""
if n_years <= 0:
return 0
elif n_years <= 20:
# 最低80万円保障
return max(800_000, 400_000 * n_years)
else:
return 8_000_000 + 700_000 * (n_years - 20)
def get_pension_deduction(pension_revenue, other_income):
"""公的年金等控除(65歳未満)"""
if other_income <= 10_000_000:
if pension_revenue <= 1300000: return 600000
elif pension_revenue <= 4100000: return pension_revenue * 0.25 + 275000
else: return pension_revenue * 0.15 + 685000
elif other_income <= 20_000_000:
if pension_revenue <= 1300000: return 500000
elif pension_revenue <= 4100000: return pension_revenue * 0.25 + 175000
else: return pension_revenue * 0.15 + 585000
else:
if pension_revenue <= 1300000: return 400000
elif pension_revenue <= 4100000: return pension_revenue * 0.25 + 75000
else: return pension_revenue * 0.15 + 485000
def get_basic_deduction(total_income):
"""基礎控除(合計所得金額で逓減)"""
if total_income <= 24_000_000: return 480000, 430000
elif total_income <= 24_500_000: return 320000, 290000
elif total_income <= 25_000_000: return 160000, 150000
else: return 0, 0
def calc_nhi_60plus(income, household_size=1):
"""
特定の地域の・60歳以上向け国保(簡易だが実用レベル)
income: 住民税ベース課税所得(円)
"""
# --- 医療分 ---
med_rate = 0.073 # 所得割
med_per_capita = 27000
med_flat = 20000
med_cap = 650000
# --- 後期支援分 ---
sup_rate = 0.023
sup_per_capita = 10000
sup_flat = 8000
sup_cap = 220000
# --- 計算 ---
med = income * med_rate + med_per_capita * household_size + med_flat
sup = income * sup_rate + sup_per_capita * household_size + sup_flat
total = min(med, med_cap) + min(sup, sup_cap)
return total
def calc_annual_taxes_and_nhi(pension_revenue, other_income):
"""1年分の税金と国保料を計算する"""
pension_deduction = get_pension_deduction(pension_revenue, other_income)
pension_income = max(0, pension_revenue - pension_deduction) if pension_revenue > 0 else 0
total_income = pension_income + other_income
basic_deduction_inc, basic_deduction_res = get_basic_deduction(total_income)
taxable_income = max(0, total_income - basic_deduction_inc)
income_tax = calculate_income_tax(taxable_income)
taxable_resident = max(0, total_income - basic_deduction_res)
resident_tax = taxable_resident * 0.10
nhi_premium = calc_nhi_60plus(taxable_resident, household_size=1)
return income_tax + resident_tax + nhi_premium
def optimize_dc_final(X_man, Y_man, n_years):
total_amount = X_man * 10000
other_income = Y_man * 10000
step = 10000
best_net_income = -1
best_x, best_y = 0, 0
base_annual_cost = calc_annual_taxes_and_nhi(0, other_income)
retirement_deduction = get_retirement_deduction(n_years)
for x in range(0, total_amount + step, step):
y = total_amount - x
# -----------------------------------
# 1. 一時金 (y) にかかる税・手取り
# -----------------------------------
# 退職所得控除を差し引き、さらに1/2にする
taxable_retirement = max(0, y - retirement_deduction) / 2
tax_y_income = calculate_income_tax(taxable_retirement)
tax_y_resident = taxable_retirement * 0.10
net_y = y - tax_y_income - tax_y_resident
# -----------------------------------
# 2. 年金 (x) にかかる差分コストと手取り (5年間)
# -----------------------------------
annual_pension_revenue = x / 5
total_annual_cost = calc_annual_taxes_and_nhi(annual_pension_revenue, other_income)
annual_additional_cost = total_annual_cost - base_annual_cost
net_x = x - (annual_additional_cost * 5)
# -----------------------------------
# 3. 総合評価
# -----------------------------------
total_net_income = net_x + net_y
if total_net_income > best_net_income:
best_net_income = total_net_income
best_x = x
best_y = y
return best_x, best_y, best_net_income, retirement_deduction
# 実行例:
X_man = 2000 # DC総額: 2000万円
Y_man = 100 # 別途所得: 100万円
N_years = 5 # 控除年数(加入年数): 10年
best_x, best_y, net, deduction = optimize_dc_final(X_man, Y_man, N_years)
print(f"--- 最適化結果 ---")
print(f"前提条件: DC総額 {X_man}万円 / 別途所得 {Y_man}万円 / 控除年数 {N_years}年")
print(f"退職所得控除額 : {deduction / 10000:,.0f} 万円")
print(f"------------------")
print(f"年金で受け取る額 (x) : {best_x / 10000:,.0f} 万円 (毎年 {best_x / 5 / 10000:,.1f} 万円)")
print(f"一時金で受け取る額 (y): {best_y / 10000:,.0f} 万円")
print(f"推定される最大手取り : {net / 10000:,.1f} 万円")
print(f"総額に対する手取り率 : {(net / (X_man * 10000)) * 100:.1f}%")
print(f"税金と社会保険料の合計: {(X_man * 10000 - net) / 10000:,.1f} 万円")プログラムを実行すると、以下のような情報が表示されます。
参考にしてください。
--- 最適化結果 ---
前提条件: DC総額 2000万円 / 別途所得 100万円 / 控除年数 5年
退職所得控除額 : 200 万円
------------------
年金で受け取る額 (x) : 300 万円 (毎年 60.0 万円)
一時金で受け取る額 (y): 1,700 万円
推定される最大手取り : 1,816.1 万円
総額に対する手取り率 : 90.8%
税金と社会保険料の合計: 183.9 万円