0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

アクチュアリーのためのPython入門(保有契約の責任準備金)

0
Last updated at Posted at 2026-07-11

アクチュアリーのためのPython入門(決算数理編第3回)

保有契約の責任準備金の計算

📚 アクチュアリーのためのPython入門
この記事は決算数理編の一部です。
目次はこちら
逆引きガイドはこちら

はじめに

前回で計算基礎別の保険料積立金が計算できるようになりました。
今回は、保有契約データのサンプルを使って、
年度末の責任準備金を計算します。

保有契約データのサンプルはこちらに置きました。

今回は、ここにある前年度末の保有データinforce2024.csv
当年度末の保有データinforce2025.csvを使って、
それぞれの責任準備金を計算します。

前提条件は次とします。

  • 月払いのみの取り扱い
  • 期末の未経過保険料は純保険料×1/2
  • 正常に入金されたと仮定(未収はなし)
  • 異動の発生と支払いは同時(支払備金は考えない)

とします。

保有契約データについて補足

保有契約のデータは次の内容を表しています。
一般的な保有契約の基本データも同じような構成になっていることが多いです。

  • product : 保険種類、保険種類コード
  • policy_year : 契約日の年
  • policy_month : 契約日の月
  • policy_day : 契約日の日
  • sex : 被保険者性別
  • age : 被保険者契約時年齢
  • tearm : 保険期間(保険料払込期間)
  • deposits : 保険料払込回数
  • number : 件数
  • premium : 1件あたり保険料
  • amount : 1件あたり保険金額

他に、責任開始日が契約日と別の場合は責任開始日や、
年払い、半年払いなどの払込方法なども追加されます。

ここでは計算を簡単にするため、
同じ責任準備金となる契約を集計したデータからはじめますが、
実際はその前の1件ごとの契約からはじめる場合もあります。

未経過保険料について補足

月払契約の契約応当日が月内に均等にある場合、
未経過保険料は営業保険料×1/2と、純保険料×1/2が考えられます。

営業保険料×1/2とした場合、経過保険料は、
前年度3月分×1/2 + 当年度4月~2月分 + 当年度3月分×1/2
となります。

予定事業費も、それに合わせて、
前年度3月分×1/2 + 当年度4月~2月分 + 当年度3月分×1/2
とする必要があります。

利源分析の予定事業費でこの調整を行わなければならず、
ここでは純保険料×1/2としました。

実務でも、未経過保険料を営業保険料×1/2としている場合は、
利源分析において予定事業費を先のように調整しています。

前提条件

サンプル保有データを使って、責任準備金を計算します。
必要なのは、次の3つの責任準備金です。
なお、責任準備金は狭義での意味です。
責任準備金 = 未経過保険料 + 保険料積立金

  • 保険料計算基礎の平準純保険料式責任準備金
  • 責任準備金計算基礎の平準純保険料式責任準備金
  • 保険料計算基礎の5年チルメル式責任準備金

上の2つは大きい方を期末の責任準備金とします。
3つ目は利源分析に使用するために計算します。

ファイル構成は次のように考えています。

ワークスペース
├─ core_b(共通ファイル)
├─ calc_inforce.py(保有データの責任準備金の計算) 
├─ calc_movement.py(異動データの保険料積立金の計算) 
├─ calc_payment.py(入金データの予定事業費の計算)
├─ surplus_analysis.py(集計と利源分析)
└─ data/ 
   ├─ inforce2024.csv(期始の保有データ)
   ├─ inforce2025.csv(期末の保有データ)
   ├─ movement2025.csv(異動データ)
   └─ premium2025.csv(入金データ)   

としますので、ダウンロードした各ファイルを.pyを置いている
ワークスペースのdataフォルダの下に置いてください。

保有契約の責任準備金

まず、前回までで作成した共有ファイルのcore_b.py
養老保険のendowment_b.py、定期保険のterm_b.py
終身保険のwhole_b.pyをインポートします。
また、内容を確認するためpandasを使います。

calc_inforce.py
from core_b import *
from endowment_b import PremE, netPremE, ResE, PremCompE
from term_b import PremT, netPremT, ResT, PremCompT
from whole_b import PremW, netPremW, ResW, PremCompW
import pandas as pd

続いて、保険商品ごとの保険料、保険積立金などの関数を計算の途中でif文を使って分岐させることがないように辞書化しておきます。
また、それを使いやすいように関数化します。

保険料積立金と解約返戻金は端数月により直線補間しておきます。

calc_inforce.py
# 保険料の計算式
premium_func = {
    "E":PremE,
    "T":PremT,
    "W":PremW
}
def prem_func(product, sex, age, term):
    return premium_func[product](sex, age, term)

# 純保険料の計算式
net_premium_func = {
    "E":netPremE,
    "T":netPremT,
    "W":netPremW
}
def netprem_func(base, product, sex, age, term):
    return net_premium_func[product](base, sex, age, term)

# 5年チルメル式危険保険料、貯蓄保険料、純保険料の計算式
net_premium_zill_func = {
    "E":PremCompE,
    "T":PremCompT,
    "W":PremCompW
}
def net_premzill_func(base, product, sex, age, term, deposits):
    payment_y = int(deposits / 12)
    riskp, resp, netp = net_premium_zill_func[product](base, sex, age, term, payment_y)
    return riskp, resp, netp

# 保険料積立金・解約返戻金の計算
reserve_func = {
    "E":ResE,
    "T":ResT,
    "W":ResW
}
# 月単位の解約返戻金の計算
def sv_func(product, sex, age, term , deposits):
    payment_y = int(deposits / 12)
    payment_m = deposits % 12
    _, _, W1 = reserve_func[product]("P", sex, age, term, payment_y + 1)
    _, _, W = reserve_func[product]("P", sex, age, term, payment_y)
    W_month = roundhu(W * Decimal(1 - payment_m/12) + W1 * Decimal(payment_m/12), 6)
    return W_month

# 月単位の保険料積立金の計算
def res_func(base, product, sex, age, term, deposits):
    payment_y = int(deposits / 12)
    payment_m = deposits % 12
    Vn1, Vz1, _ = reserve_func[product](base, sex, age, term, payment_y + 1)
    Vn, Vz, _ = reserve_func[product](base, sex, age, term, payment_y)
    Vn_month = roundhu(Vn * Decimal(1 - payment_m / 12) + Vn1 * Decimal(payment_m / 12), 6)
    Vz_month = roundhu(Vz * Decimal(1 - payment_m / 12) + Vz1 * Decimal(payment_m / 12), 6)
    return Vn_month, Vz_month

続いて、保有契約データを読み込みこんで、
責任準備金を計算する関数です。
先ほどの3種類の責任準備金を計算します。

  1. 保険料計算基礎の平準純保険料式保険料積立金
  2. 保険料計算基礎の5年チルメル式保険料積立金
  3. 責任準備金計算基礎の平準純保険料式保険料積立金
  4. 未経過保険料として、純保険料の1/2
  5. 未経過保険料として、5年チルメル式純保険料の1/2

1.と3.は大きい方を事業年度末の保険料積立金とします。
これに4.を加えたのが、事業年度末の責任準備金です。
2.と5.は5年チルメル式の責任準備金で利源分析に使用します。

calc_inforce.py
# 保有契約データの責任準備金を計算
def calc_inforce(year):
    # 保有データのファイル名
    input_file = f"data/inforce{year}.csv"
    # 保有契約データの取得
    inforce_df = pd.read_csv(input_file)
    # 保険料積立金、未経過保険料のリスト
    P_Vn_list = []
    P_Vz_list = []
    V_Vn_list = []
    UPR_list = []
    UPRz_list = []
    calc_Vn_list = []
    # 保有保険金額
    amount_list = []
    for _, row in inforce_df.iterrows():
        product = row["product"]
        sex = row["sex"]
        age = int(row["age"])
        term = row["term"]
        deposits = int(row["deposits"])
        number = int(row["number"])
        amount = int(row["amount"])

        # 経過月数のP基礎保険料積立金
        P_Vn, P_Vz = res_func("P", product, sex, age, term ,deposits - 1)
        P_Vn_list.append(roundhu(P_Vn * amount,0) * number)
        P_Vz_list.append(roundhu(P_Vz * amount,0) * number)
        # 経過月数のV基礎保険料積立金
        V_Vn, _ = res_func("V", product, sex, age, term ,deposits - 1)
        V_Vn_list.append(roundhu(V_Vn * amount,0) * number)
        # 未経過保険料(純保険料)
        upr = roundhu(netprem_func("P", product, sex, age, term) * amount * 1/2, 0) * number
        UPR_list.append(upr)
        # 事業年度末V
        calc_Vn_list.append(max(P_Vn_list[-1], V_Vn_list[-1]))
        # 未経過保険料(5年チルメル式)
        _, _, netpz = net_premzill_func("P", product, sex, age, term, deposits)
        uprz = roundhu(netpz * amount * 1/2, 0) * number
        UPRz_list.append(uprz)
        # 保有保険金額
        amount_list.append(amount * number)
    
    # 保険料積立金、未経過保険料の追加
    inforce_df["P_Vn"] = P_Vn_list
    inforce_df["V_Vn"] = V_Vn_list
    inforce_df["UPR"] = UPR_list
    inforce_df["calc_Vn"] = calc_Vn_list
    inforce_df["UPRz"] = UPRz_list
    inforce_df["P_Vz"] = P_Vz_list
    # 保有保険金額の追加
    inforce_df["amount"] = amount_list
    
    return inforce_df

returnでの戻り値は、DataFrame化した
元のCSVに責任準備金の値を加えています。

以下のコードで出力してあげれば、
1件ごとの責任準備金が確認できます。
ただし、これはメインで実行した場合だけ出力されます。
別に集計用のPythonファイルからimportされた場合は出力されません。

calc_inforce.py
if __name__ == "__main__":
    # 出力する保有契約の年度
    year = 2024
    # 出力ファイル名
    output_file = f"data/inforce{year}_calc.csv"
    # 責任準備金の計算
    inforce_df = calc_inforce(year)
    # 出力
    inforce_df.to_csv(output_file, index=False, encoding="utf-8-sig")

ここのyearで年度を必要に応じて変更します。

実務メモ

  • 保険料計算基礎の責任準備金
  • 責任準備金計算基礎の責任準備金
    両方の大きい方を事業年度末の責任準備金として積み立てます。
     
  • 5年チルメル式の責任準備金
    利源分析に使用しますので、保有契約だけではなく、
    異動契約(支払い)でも計算します。
    入金データでは、責任準備金ではないですが、
    5年チルメル式の危険保険料と予定事業費を計算します。
     
  • 保有保険金額
    年度始保有保険金額 + 新契約保険金額 - 死亡契約保険金額
    - 満期契約保険金額 - 解約契約保険金額 = 年度末保有保険金額
    となることを確認するために集計します。
    イレギュラー対応などで契約データに反映漏れなどがないか確認します。
    ※ 新契約と満期は今回取り扱いません

まとめ

今回は保有契約1件ずつの責任準備金の計算を実施しました。
決算時に最低限計算する責任準備金はこのようになります。
いくつも種類があるので、取り違えることがないように注意します。

次回は、異動契約について、
どのような計算を行っているのかを取り上げます。


📚 ナビゲーション
前の記事
計算基礎別の保険料積立金

次の記事
異動契約の保険料積立金

📚 目次
アクチュアリーのためのPython入門

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?