チュートリアル3

最後に、複数商品を管理し、またEV(エンベデッドヴァリュー)の計算ができる本格的なモデルについて説明します。

Web上でモデルを参照する場合は、以下をご覧下さい。

ヒント

  • エンベデッドヴァリューを必要としない場合は、ev.modelや2回目のランに関する部分は不要となります。

モデルを開く

チュートリアル2 と同様に、PyCharmでサンプルモデルのdemo3を開き、 コマンドウィンドウ を開いて下さい。

モデルのランを行う

チュートリアル2 と同様に、ランを実行して下さい。

  1. コマンドウィンドウで delver と入力し、Enterを押して実行して下さい

  2. resultフォルダが作成され、その中に計算結果(とインフォース)のファイルが作成されていれば成功です

    商品ごとに計算結果が出力されています。養老保険を例にとると、

    • 01_endow-bspl.txtで、PL項目・BS項目を出力しています
    • 01_endow-profitability.txtで、プロフィットマージンなどの収益性を出力しています
    • 01_endow-ev_deter.txtで、基本のシナリオの値( 決定論 )での、リスク量計算などに必要な値を出力しています
    • 01_endow-ev_stoch.txtで、シナリオ平均値( 確率論 )での、リスク量計算などに必要な値を出力しています
    • 01_endow-risk.txtで、リスク量を出力しています
    • 01_endow-summary.txtで、最終的に求める対象となる、EVを出力しています

モデルを理解する

チュートリアル1, 2では扱わなかった部分を中心に説明をしていきます。

モデル

このモデルでは、複数のファイルに複数の計算モデルが定義されています。

ファイル 計算クラス 説明
base.model Base 共通のロジックを定義するクラス
endow.model Endow 養老保険のモデル(Baseを継承する)
wl.model WL 終身保険のモデル(Baseを継承する)
term.model Term 定期保険のモデル(Baseを継承する)
medical.model Medical 医療保険のモデル(Baseを継承する)
ev.model EV, EVDeter, EVStoch
EV計算用のモデル
(EVDeter, EVStochはEVを継承する)
EVDeterは1シナリオのみ計算を行う場合
(決定論と呼ばれる)
EVStochは複数シナリオの計算を行う場合
(確率論と呼ばれる)

継承

継承 という機能により、保険種類に共通のロジックと保険種類ごとに異なるロジックを分けて記述することができます。 このため、複数商品を管理する場合に、重複した記述を行う必要がありません。

  • 計算クラスBaseでは、

    • 基数・キャッシュフロー計算などの保険種類によらず共通のロジックを記述しています。
    • 基数の予定利率や死亡率、レート、キャッシュフローの前提や給付額などは保険種類それぞれで異なるので、 NotImplemented (まだ実装していないことを意味する)と設定し、継承先で定義させます。
  • 計算クラスEndowでは、Baseを継承し、上記の保険種類ごとに異なる要素のみを記述しています(計算クラスWL, Termも同様です)

  • 計算クラスMedicalでは、

    保険種類ごとに異なる要素に加え、以下についても記述しています。

    • 医療給付用の発生率の前提など、追加で定義しなくてはいけない部分

      double[] qx_hosp_crude = if (t == 0)        { 0.0 }
                               elseif (sex == "M"){ Asm.get_double("qx_hosp_m", x + t - 1) }
                               else               { Asm.get_double("qx_hosp_f", x + t - 1) }
      
    • 医療給付のキャッシュフローへの反映など、共通のロジックを修正する必要のある部分
      (Baseでは、medical_benefitは0としています)
      double[] medical_benefit = medical_benefit_hosp(t) + medical_benefit_acci(t)
                               + medical_benefit_surg(t)
      
  • EV計算用のクラスでは、計算クラスEVに共通のロジックを定義し、計算クラスEVDeter, EVStochではデータの取得元について異なるロジックを定義しています。

  • NotImplemented を含む計算クラスには、計算クラス名の記述のところに abstract とつけ、継承せずに計算することができないことを示す必要があります。

2回目のラン

  • EV計算などを行うために、1回目のランで計算を行い、その計算結果を用いて2回目のランを行う機能があります。

    • 資本コスト法でEVを計算するには、キャッシュフローをシナリオ・ショックごとに計算し、各タイムステップごとの負債現在価値を求めた後、 それらを集計してヘッジ不能コスト(CNHR)を求める必要があります。

養老保険の場合の計算の流れは以下のとおりです。

  • 1回目のランでは計算クラスEndowで計算を行います。
  • 出力定義にev_deter, ev_stochが設定されており、EV計算用に必要な値が保持されています。
  • 2回目のランでは、計算クラスEVStochで計算を行います。 Fac.get_double という関数などを用いて、1回目のランでの計算結果を読み込みます。
  • 1回目のラン、2回目のランともに、計算結果は出力定義にしたがって出力されます。

インプット

ランの概要

  • 養老保険、終身保険、定期保険、医療保険と4つのランを行います。

  • 養老保険、終身保険では、0から10番目までのシナリオ、0番目から6番目までのショックでランを行います。
    各シナリオ・ショックによる計算結果を用いて、EVの計算についても行います。
    (実務では1000シナリオなどで計算することが一般的だと思いますが、サンプルのため計算時間を削減するために10シナリオとしています)
  • 定期保険、医療保険では、0番目のシナリオ、0番目から6番目までのショックでランを行います。
    各シナリオ・ショックによる計算結果を用いて、EVの計算についても行います。
    (シナリオを複数行わないのは、定期保険や医療保険のキャッシュフローは金利シナリオに依存しないとしているためです。)
  • 1回目の計算では、それぞれの保険種類に応じたキャッシュフロー計算を行います。

  • 2回目の計算では、EV計算用の集計を行います。決定論・確率論によって計算結果の読み込みが異なります。

ラン定義

  • 養老保険、終身保険、定期保険、医療保険と4つのランを行うように設定しています。
  • それぞれのランでは、インフォースを変えています。
  • 1回目の計算はcalculation列の計算クラスを使用します。出力定義はoutput, シナリオ・ショックはsc_st, sc_la, sh_st, sh_laの値を使用します。
  • 2回目の計算はcalculation2列の計算クラスを使用します。出力定義はoutput2, シナリオ・ショックはsc_st2, sc_la2, sh_st2, sh_la2の値を使用します。
  • モデルやインフォース、アサンプションは1回目のランと2回目のランで共通です。

出力定義

出力定義 説明
debug デバッグ用
profitability (1回目のラン) プロフィットマージンなどの収益性
bspl (1回目のラン) BS, PL
ev_deter (1回目のラン) EV計算に必要な値(決定論 - 0番目のシナリオ)
ev_stoch (1回目のラン) EV計算に必要な値(確率論 - シナリオ平均)
summary (2回目のラン) EV計算による収益性
risk (2回目のラン) EV計算のリスク量

インフォース

実際の商品開発の場面を想定し、契約年齢・性別・プラン(保険期間や払込期間)を網羅するようにしたインフォースを作成しています。

  • プラン上の値(年満期・歳満期など)と実際の保険期間・払込期間の列を作成しています。
  • 組み合わせを作ったときに、実際の保険期間・払込期間がマイナスになるなど、不適切なケースが起こりえます。
  • ここでは、 列SKIPにフラグを立てることにより、不適切なケースをスキップ しています。計算をスキップした場合、計算結果はデフォルト値(数値である場合は0)となります。

アサンプション

  • シート(a1d)baseで、スカラー値および1次元配列のアサンプションが設定されています。
  • シート(a2d)int_rateで、金利シナリオが2次元配列として設定されています。
    • 左上セルのint_rateがキーを表します。
    • この場合では、(1+10)行 * (1+100)列 の2次元配列でアサンプションが設定されています。

練習問題

以下の練習問題が解ければ、十分にすべてのチュートリアルの内容を理解していることになります!