確定拠出年金の最適受取方法を計算するPythonコード|個人メモ

tadanori
記事内に商品プロモーションを含む場合があります

60歳で確定拠出年金を受け取る予定ですが、一時金と60~65歳の間の5年間に年金でもらう額の最適解を解く方法を考えてみました。まだ、情報が不足している気がしますが、とりあえず「個人メモ」としてブログに残しておきます。

確定拠出年金(iDeCo, 企業型など)の受取り

確定拠出年金を「一時金で受け取る」か、「年金で受け取るか」って結構複雑です。これを検討するために、受け取り金額等から計算するPythonコードを作成してみました。

個人的なメモのようなコードですが、参考になれば幸いです

本記事の計算は、税制および社会保険料(国民健康保険)を簡易モデル化した概算シミュレーションです。特に国保は自治体・世帯構成・軽減措置などにより大きく変動します。また、退職所得の扱いや他の所得状況によって結果は変わります。本コードは受取方法による有利・不利の傾向を把握することを目的としています。実際の受取方法の決定は、最新の制度と個別条件に基づいて確認する必要があります。

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 万円

プログラムにバグがある可能性があるので、利用時は気をつけてください。また、社会保険料は地域により変化します。このプログラムでは私の地域の保険料を想定しています。

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT ME
ある/Aru
ある/Aru
ファイナンシャル・プランナー(CFP®)/ 博士(情報工学)
2023年5月、54歳で早期退職しブログを開設。 データ分析・機械学習を専門とするITエンジニアで、投資歴20年以上。 CFP®・宅地建物取引士・マンション管理士などの資格を保有し、不動産分野に強みがあります。
error: コンテンツはプロテクトされています
記事URLをコピーしました