アクチュアリーのためのPython入門(応用編第1回)
保有契約の将来収支の仕組み
📚 アクチュアリーのためのPython入門
この記事は応用編の一部です。
▶ 目次はこちら
はじめに
これまでのブログ記事では、
新契約のみの将来収支を計算してきました。
今回は一歩進んで、
複数の保有契約の将来収支を作成したいのですが、
生命保険数学のテキストレベルを超えてしまうので、
まずは複数契約をどのように合算して保有契約の将来収支を作るか
の考え方を整理します。
計算基準日からの将来収支
私自身、何も予備知識がない状態で、
保有契約の将来収支のプログラムを作成しようとしたときに、
「各契約について、計算基準日からの将来収支を計算して、
それを合計すればよいのでは?」
と考えていました。
ただ、実際に作ってみると、問題点がいくつかでてきます。
- 前提条件の整合性が難しい
途中時点から将来収支を計算する場合、
収支のバランスを取るのが難しかったり、
その時点の保険料積立金を正確に反映できなかったりします。
これを個別契約ごとに扱うのは複雑になります。
- 実装が複雑になる
途中から計算する場合は「どの時点から開始するか」
を常に意識する必要があります。
コードも分岐が増え、分かりにくくなります。
保有契約の将来収支の考え方
そこで、次のように考えます。
- 各契約について、契約時点から満期までの将来収支を計算する
- それを事業年度を基準として合計する
- 計算基準日以降の将来収支を出力する
このようにすると、
契約ごとの計算は前回までの計算と同じ方法が取れます。
各保険契約の保険収支を合計するコード、
result_df = pd.DataFrame(results)
grouped = result_df.groupby("t").sum()
summary = grouped.reset_index()
summary.to_excel("term_result.xlsx", index=False)
この2行目で経過年数tを基準に合計している部分を、
事業年度(契約年度+経過年数)を基準にして合計すれば、
できるのではないかと考えます。
実務で使われる保険数理ソフトウェアでは、
契約ごとに「契約時点から」将来収支を計算し、
それを事業年度の年月で合計しています。
そのため、この考え方に慣れておくことは、
実務でそのソフトウェアを操作する上でも重要です。
今回の修正箇所
今回は養老保険の保険収支を例として取り扱いのですが、
事業年度を基準とする以外に、次の点も修正します。
-
計算期間を保険期間へ変更
前回までは、保険収支の計算期間を設定していましたが、
今回は契約年度によって必要な計算期間が異なるので、
計算期間を保険期間へ変更します。
この部分のコードは次回とします。
-
解約率と死亡率を関数化
解約率は計算期間分としていましたが、そこが変更にします。
ついでに期間によって解約率を変更し、
1年目は0.05、2~3年目は0.03、4年目~は0.02の前提とします。
また、取り扱いやすいように関数化します。死亡率も同じように扱えるように関数化します。
-
残存表に満期を追加
定期と養老の単独だけでしたら満期は特に考えずに、
保険料や保険金支払のところで、
満期を制御しようとしていたのですが、
将来的に終身を混ぜことを考えています。
そうすると、分かりにくくなると考えました。今更になりますが、満期の異動を加えて、
養老保険の満期保険金を対応させます。
解約率と死亡率の関数化
解約率の関数は次のように作成します。
# 解約率の関数
def qwx(t):
if t == 0:
w = 0.05
elif t < 3:
w = 0.03
else:
w = 0.02
return w
また、解約率を関数で定義しているのに、
死亡率は現在のままですと、
同じように取り扱えないので、
死亡率も関数化しておきます。
# 死亡率の関数
def qdx(sex, age):
return qx[sex][age]
満期の追加
今まで残存表の中では、
満期を作成していませんでしたが、
このままだと、先へ進んだときに
分かりにくくなるので、満期を加えます。
l0 = amount # 初期保険金額
# 残存表の項目
lx = [l0] # 保有保険金額
dx = [] # 死亡保険金額
wx = [] # 解約保険金額
mx = [] # 満期保険金額
# 保険期間の変換
InsPeriod = parse_term(term, age)
# 残存表の作成
for t in range(InsPeriod):
q = qdx(sex, age + t)
w = qwx(t)
next_d = lx[-1] * q * k
next_w = lx[-1] * w
if t == range(InsPeriod) - 1:
next_m = lx[-1] - next_d - next_w
next_l = 0
else:
next_m = 0
next_l = lx[-1] - next_d - next_w
lx.append(next_l)
dx.append(next_d)
wx.append(next_w)
mx.append(next_m)
保険金支払いの部分も
満期保険金を加えるように修正します。
また、運用利息代わりに予定利息を計算していますが、
期末の責任準備金は満期契約が対象になるため、
満期契約を加えておきます。
interest.append(((lx[t + 1] + mx[t]) * Vt1 + lx[t] * Vt) \
* 0.006 / (2 + 0.006)) # ハーディの公式
if t == InsPeriod - 1:
pay_ben = dx[t] + mx[t] # 死亡+満期保険金の支払い
else:
pay_ben = dx[t] # 死亡保険金の支払い
事前準備はここまでとして、
次回は養老保険の保有契約の保険収支を計算します。
▶ 次の記事
保有契約の将来収支2
📚 目次
アクチュアリーのためのPython入門