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-04

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

計算基数を加えた保険料積立金の計算

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

はじめに

前回は共通部分となるcore_b.pyを作成したので、
引き続いて保険商品別のファイルの純保険料と保険料積立金の計算を修正します。
大きな修正ポイントは3つです。

  • 引数に計算基礎をいれること
  • 月払いの計算に変更すること
  • 5年チルメル式の計算を加えること

決算では5年チルメル式の純保険料や保険料積立金を
利源分析で使用するので、それも出力できるようにしておきます。

養老保険

前回、予定事業費を関数の中に入れていましたが、
一部の予定事業費は保険料積立金や解約返戻金にも使用しますので、
関数の外に置いて共有にします。

保険料積立金は平準純保険料式と5年チルメル式は両方を並行して使うので、
一緒に計算を行い、戻り値は解約返戻金も加えて3つとします。
この方法は小ネタとして取り上げました。

まずは養老保険です。
説明した以外では、利源分析を行う材料として、
危険保険料と貯蓄保険料、
その合計値(5年チルメル式の純保険料)を計算します。

月払で正確に計算するのは複雑になってしまうので、
年払いの危険保険料と貯蓄保険料を1/12しています。

endowment_b.py
# 養老保険
from core_b import *

# 予定事業費
alpha = 0.025
delta = 0.02
gamma = 0.00215
beta = 0.03

# 営業保険料
def PremE(sex, start_age, term):
    n = parse_term(term, start_age)

    # 営業保険料の計算
    An = Axn("P", sex, start_age, n)
    an = axn12("P", sex, start_age, n)
    value = (An + alpha + gamma * an) / (12 * (1 - beta - delta) * an)
    # 端数処理
    value = roundhu(value, 6)
    return value

# 純保険料
def netPremE(base, sex, start_age, term):
    n = parse_term(term, start_age)
    return Axn(base, sex, start_age, n) / (12 * axn12(base, sex, start_age, n))

# 保険料積立金
def ResE(base, sex, start_age, term, t):
    n = parse_term(term, start_age)
    benefit = Axn(base, sex, start_age + t, n - t)
    income = 12 * netPremE(base, sex, start_age, n) * axn12(base, sex, start_age + t, n - t)
    value = Decimal(str(benefit)) - Decimal(str(income))
    # 平準純保険料式
    Vn = roundhu(value, 6)
    # 5年チルメル式
    if t < 5:
        a = alpha * axn(base, sex, start_age + t, 5 - t) / axn(base, sex, start_age, 5)
    else:
        a = 0
    value = roundhu(value - Decimal(str(a)), 6)
    Vz = max(value, 0)
    # 解約返戻金
    if t < 10:
        surrender_fact = alpha * (1 - t / min(n, 10))
    else:
        surrender_fact = 0
    value = roundhu(Vn - Decimal(str(surrender_fact)),6)
    W = max(value, 0)
    return Vn, Vz, W

# 危険保険料と純保険料(5年チルメル式)
def PremCompE(base, sex, start_age, term, t):
    # 現価率
    vh = (1 + ival[base]) ** (-0.5)
    v1 = (1 + ival[base]) ** (-1)
    # 5年チルメル式V
    _, Vz1, _ = ResE(base, sex, start_age, term, t + 1)
    _, Vz, _ = ResE(base, sex, start_age, term, t)
    Vz1 = float(Vz1)
    Vz = float(Vz)
    # 危険保険料
    riskp = vh * qx[base][sex][start_age + t] * (1 - vh * Vz1)
    # 貯蓄保険料
    resp = v1 * Vz1 - Vz
    # 純保険料
    netp = riskp + resp
    return riskp/12, resp/12, netp/12

続いて、定期保険です。
養老保険と同様です。

term_b.py
# 定期保険
from core_b import *

# 予定事業費
alpha = 0.001
delta = 0.06
gamma = 0.00115
beta = 0.03

# 営業保険料
def PremT(sex, start_age, term):
    n = parse_term(term, start_age)
    # 営業保険料の計算
    An = A1xn("P", sex, start_age, n)
    an = axn12("P", sex, start_age, n)
    value = (An + alpha + gamma * an) / (12 * (1 - beta - delta) * an)
    # 端数処理
    value = roundhu(value, 6)
    return value

# 純保険料
def netPremT(base, sex, start_age, term):
    n = parse_term(term, start_age)
    return A1xn(base, sex, start_age, n) / (12 * axn12(base, sex, start_age, n))

# 保険料積立金
def ResT(base, sex, start_age, term, t):
    n = parse_term(term, start_age)
    benefit = A1xn(base, sex, start_age + t, n - t)
    income = 12 * netPremT(base, sex, start_age, n) * axn12(base, sex, start_age + t, n - t)
    value = Decimal(str(benefit)) - Decimal(str(income))
    # 平準純保険料式
    Vn = roundhu(value, 6)
    # 5年チルメル式
    if t < 5:
        a = alpha * axn(base, sex, start_age + t, 5 - t) / axn(base, sex, start_age, 5)
    else:
        a = 0
    value = roundhu(value - Decimal(str(a)), 6)
    Vz = max(value, 0)
    # 解約返戻金
    if t < 10:
        surrender_fact = alpha * (1 - t / min(n, 10))
    else:
        surrender_fact = 0
    value = roundhu(Vn - Decimal(str(surrender_fact)),6)
    W = max(value, 0)
    return Vn, Vz, W

# 危険保険料と貯蓄保険料(5年チルメル式)
def PremCompT(base, sex, start_age, term, t):
    # 現価率
    vh = (1 + ival[base]) ** (-0.5)
    v1 = (1 + ival[base]) ** (-1)
    # 5年チルメル式V
    _, Vz1, _ = ResT(base, sex, start_age, term, t + 1)
    _, Vz, _ = ResT(base, sex, start_age, term, t)
    Vz1 = float(Vz1)
    Vz = float(Vz)
    # 危険保険料
    riskp = vh * qx[base][sex][start_age + t] * (1 - vh * Vz1)
    # 貯蓄保険料
    resp = v1 * Vz1 - Vz
    # 純保険料
    netp = riskp + resp
    return riskp/12, resp/12, netp/12

最後に終身保険です。
これも養老保険と定期保険と同様です。

whole_b.py
# 終身保険
from core_b import *

# 予定事業費
alpha = 0.02
delta = 0.025
gamma = 0.00215
gamma2 = 0.002
beta = 0.03

# 営業保険料
def PremW(sex, start_age, term):
    n = parse_term(term, start_age)
    # 営業保険料の計算
    An = A1x("P", sex, start_age)
    an = axn("P", sex, start_age, n)
    an12 = axn12("P", sex, start_age, n)
    a = ax("P", sex, start_age)
    value = (An + alpha + gamma * an12 + gamma2 * (a - an)) \
        / (12 * (1 - beta - delta) * an12)
    # 端数処理
    value = roundhu(value, 6)
    return value

# 純保険料
def netPremW(base, sex, start_age, term):
    n = parse_term(term, start_age)
    A = A1x(base, sex, start_age)
    an = axn(base, sex, start_age, n)
    an12 = axn12(base, sex, start_age, n)
    a = ax(base, sex, start_age)
    return (A + gamma2 * (a - an)) / (12 * an12)

# 保険料積立金
def ResW(base, sex, start_age, term, t):
    n = parse_term(term, start_age)
    if t < n:
        an = axn(base, sex, start_age + t, n - t)
        an12 = axn12(base, sex, start_age + t, n - t)
        benefit = A1x(base, sex, start_age + t)
        income = 12 * netPremW(base, sex, start_age, n) * an12
        expense = gamma2 * (ax(base, sex, start_age + t) - an)
        value = Decimal(str(benefit)) - Decimal(str(income)) + Decimal(str(expense))
    else:
        benefit = A1x(base, sex, start_age + t)
        expense = gamma2 * ax(base, sex, start_age + t)
        value = Decimal(str(benefit)) + Decimal(str(expense))
    # 平準純保険料式
    Vn = roundhu(value, 6)
    # 5年チルメル式
    if t < 5:
        a = alpha * axn(base, sex, start_age + t, 5 - t) / axn(base, sex, start_age, 5)
    else:
        a = 0
    value = roundhu(value - Decimal(str(a)), 6)
    Vz = max(value, 0)
    # 解約返戻金
    if t < 10:
        surrender_fact = alpha * (1 - t / min(n, 10))
    else:
        surrender_fact = 0
    value = roundhu(Vn - Decimal(str(surrender_fact)),6)
    W = max(value, 0)
    return Vn, Vz, W

# 危険保険料と貯蓄保険料(5年チルメル式)
def PremCompW(base, sex, start_age, term, t):
    # 現価率
    vh = (1 + ival[base]) ** (-0.5)
    v1 = (1 + ival[base]) ** (-1)
    # 5年チルメル式V
    _, Vz1, _ = ResW(base, sex, start_age, term, t + 1)
    _, Vz, _ = ResW(base, sex, start_age, term, t)
    Vz1 = float(Vz1)
    Vz = float(Vz)
    # 危険保険料
    riskp = vh * qx[base][sex][start_age + t] * (1 - vh * Vz1)
    # 貯蓄保険料
    resp = v1 * Vz1 - Vz
    # 純保険料
    netp = riskp + resp
    return riskp/12, resp/12, netp/12

まとめ

今回は計算基礎別の養老保険、定期保険と終身保険について
保険料の保険料積立金を計算する関数を
月払いに修正しました。

Pythonとして特に難しい内容はありません。
次回以降に、簡単なサンプルデータを使って、
決算数理システムで行っていることを、
再現していきましょう。


📚 ナビゲーション
前の記事
計算基礎別の給付現価

次の記事
保有契約の責任準備金

📚 目次
アクチュアリーのための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?