モデル3 - EV計算

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

このファイルでは、EV計算のロジックを記述しています。

EV計算


// EV計算のベースクラス
abstract calculation EVBase {

module Util{
    int max_t = 100
}

module EV{

    @range = t
    @range_last = Util.max_t

    // EV計算用の係数
    double lapsemass_factor = 0.3
    double coc_factor = 0.05
    double tax_rate = 0.25

    // 負債キャッシュフロー現価などの取得
    double[] discount_factor      = NotImplemented
    double[] PVLiab_adj_base      = NotImplemented
    double[] PVLiab_adj_mortup    = NotImplemented
    double[] PVLiab_adj_mortdown  = NotImplemented
    double[] PVLiab_adj_lapseup   = NotImplemented
    double[] PVLiab_adj_lapsedown = NotImplemented
    double[] PVLiab_adj_morbup    = NotImplemented
    double[] PVLiab_adj_expup     = NotImplemented
    double[] CV_end               = NotImplemented

    // リスク量の計算
    double[] risk_mortup     = Utl.max(PVLiab_adj_mortup(t)    - PVLiab_adj_base(t), 0.0)
    double[] risk_mortdown   = Utl.max(PVLiab_adj_mortdown(t)  - PVLiab_adj_base(t), 0.0)
    double[] risk_lapseup    = Utl.max(PVLiab_adj_lapseup(t)   - PVLiab_adj_base(t), 0.0)
    double[] risk_lapsedown  = Utl.max(PVLiab_adj_lapsedown(t) - PVLiab_adj_base(t), 0.0)
    double[] risk_morbup     = Utl.max(PVLiab_adj_morbup(t)    - PVLiab_adj_base(t), 0.0)
    double[] risk_expup      = Utl.max(PVLiab_adj_expup(t)     - PVLiab_adj_base(t), 0.0)
    double[] risk_lapsemass  = lapsemass_factor * Utl.max(CV_end(t) - PVLiab_adj_base(t), 0.0)
    double[] risk_lapse      = Utl.max(risk_lapseup(t), risk_lapsedown(t), risk_lapsemass(t))

    double[] risk = calc_risk(risk_mortup(t), risk_mortdown(t), risk_morbup(t), risk_lapse(t), risk_expup(t))

    // 資本コスト、CNHRの計算
    // (資本コストをCNHRに反映するタイミングはいくつかあるが、即座に反映するものとした)
    double[] coc = risk(t) * coc_factor
    double[] cnhr_before_tax = if (t == Util.max_t)               { coc(t) }
                               elseif (discount_factor(t) <= 0.0) { coc(t) }
                               else                               { coc(t) + cnhr_before_tax(t+1) * discount_factor(t+1) / discount_factor(t) }
    double[] cnhr_after_tax = cnhr_before_tax(t) * (1.0 - tax_rate)

    // PVFP, TVOG, CNHR, MCEV, 保険料現価, 新契約マージンの計算
    double PVFP = NotImplemented
    double PVFPTVOG = NotImplemented
    double TVOG = PVFPTVOG - PVFP
    double CNHR = -cnhr_after_tax(0)
    double MCEV = PVFP + TVOG + CNHR
    double PVP  = NotImplemented
    double NBM  = if (PVP <= 0.0) { 0.0 }
                  else            { MCEV / PVP }

    // 相関を用いてリスク量を計算する関数
    function double calc_risk(double _risk_mortup, double _risk_mortdown, double _risk_morbup,
                              double _risk_lapse, double _risk_expup) =
                                ( _risk_mortup * _risk_mortup     * 1.00
                                + _risk_mortup * _risk_mortdown   * -0.25
                                + _risk_mortup * _risk_morbup     * 0.25
                                + _risk_mortup * _risk_lapse      * 0.00
                                + _risk_mortup * _risk_expup      * 0.25

                                + _risk_mortdown * _risk_mortup   * -0.25
                                + _risk_mortdown * _risk_mortdown * 1.00
                                + _risk_mortdown * _risk_morbup   * 0.00
                                + _risk_mortdown * _risk_lapse    *  0.25
                                + _risk_mortdown * _risk_expup    * 0.25

                                + _risk_morbup * _risk_mortup     * 0.25
                                + _risk_morbup * _risk_mortdown   * 0.00
                                + _risk_morbup * _risk_morbup     * 1.0
                                + _risk_morbup * _risk_lapse      * 0.00
                                + _risk_morbup * _risk_expup      * 0.50

                                + _risk_lapse * _risk_mortup      * 0.00
                                + _risk_lapse * _risk_mortdown    * 0.25
                                + _risk_lapse * _risk_morbup      * 0.00
                                + _risk_lapse * _risk_lapse       * 1.00
                                + _risk_lapse * _risk_expup       * 0.50

                                + _risk_expup * _risk_mortup      * 0.25
                                + _risk_expup * _risk_mortdown    * 0.25
                                + _risk_expup * _risk_morbup      * 0.50
                                + _risk_expup * _risk_lapse       * 0.50
                                + _risk_expup * _risk_expup       * 1.00
                                ) ^ 0.5

    // 1回目のランから計算結果を取得する関数
    function double get_factor_deter(string varible_name, int shock, int t) = Fac.get_double("ev_deter", "OutputEV", varible_name, 0,  shock, t)
    function double get_factor_stoch(string varible_name, int shock, int t) = Fac.get_double("ev_stoch", "OutputEV", varible_name, -1, shock, t)

}

// 出力(リスク量)
module OutputRisk{

    @range = t
    @range_last = Util.max_t

    double[] discount_factor = EV.discount_factor(t)
    double[] PVLiab_adj_base = EV.PVLiab_adj_base(t)
    double[] PVLiab_adj_mortup = EV.PVLiab_adj_mortup(t)
    double[] PVLiab_adj_mortdown = EV.PVLiab_adj_mortdown(t)
    double[] PVLiab_adj_lapseup = EV.PVLiab_adj_lapseup(t)
    double[] PVLiab_adj_lapsedown = EV.PVLiab_adj_lapsedown(t)
    double[] PVLiab_adj_morbup = EV.PVLiab_adj_morbup(t)
    double[] PVLiab_adj_expup = EV.PVLiab_adj_expup(t)
    double[] CV_end = EV.CV_end(t)

    double[] risk_mortup = EV.risk_mortup(t)
    double[] risk_mortdown = EV.risk_mortdown(t)
    double[] risk_lapseup = EV.risk_lapseup(t)
    double[] risk_lapsedown = EV.risk_lapsedown(t)
    double[] risk_morbup = EV.risk_morbup(t)
    double[] risk_expup = EV.risk_expup(t)
    double[] risk_lapsemass = EV.risk_lapsemass(t)
    double[] risk_lapse = EV.risk_lapse(t)

    double[] risk = EV.risk(t)
    double[] coc = EV.coc(t)
    double[] cnhr_before_tax = EV.cnhr_before_tax(t)
    double[] cnhr_after_tax = EV.cnhr_after_tax(t)
}

// 出力(EV数値)
module OutputSummary{

    double PVFP = EV.PVFP
    double TVOG = EV.TVOG
    double CNHR = EV.CNHR
    double MCEV = EV.MCEV
    double PVP = EV.PVP
    double NBM = EV.NBM
}

}

// 決定論でのEV計算クラス
calculation EVDeter(EVBase) {

module EV{

    double[] discount_factor      = get_factor_deter("discount_factor_end", 0, t)

    double[] PVLiab_adj_base      = get_factor_deter("PVLiab_adj", 0, t)
    double[] PVLiab_adj_mortup    = get_factor_deter("PVLiab_adj", 1, t)
    double[] PVLiab_adj_mortdown  = get_factor_deter("PVLiab_adj", 2, t)
    double[] PVLiab_adj_lapseup   = get_factor_deter("PVLiab_adj", 3, t)
    double[] PVLiab_adj_lapsedown = get_factor_deter("PVLiab_adj", 4, t)
    double[] PVLiab_adj_morbup    = get_factor_deter("PVLiab_adj", 5, t)
    double[] PVLiab_adj_expup     = get_factor_deter("PVLiab_adj", 6, t)
    double[] CV_end               = get_factor_deter("CV_end", 0, t)

    double PVFP     = get_factor_deter("PV_profit_after_tax", 0, 0)
    double PVFPTVOG = get_factor_deter("PV_profit_after_tax", 0, 0)
    double PVP      = get_factor_deter("PV_premium_income", 0, 0)

   }
}

// 確率論でのEV計算クラス
calculation EVStoch(EVBase) {

module EV{

    double[] discount_factor      = get_factor_deter("discount_factor_end", 0, t)

    double[] PVLiab_adj_base      = get_factor_stoch("PVLiab_adj", 0, t)
    double[] PVLiab_adj_mortup    = get_factor_stoch("PVLiab_adj", 1, t)
    double[] PVLiab_adj_mortdown  = get_factor_stoch("PVLiab_adj", 2, t)
    double[] PVLiab_adj_lapseup   = get_factor_stoch("PVLiab_adj", 3, t)
    double[] PVLiab_adj_lapsedown = get_factor_stoch("PVLiab_adj", 4, t)
    double[] PVLiab_adj_morbup    = get_factor_stoch("PVLiab_adj", 5, t)
    double[] PVLiab_adj_expup     = get_factor_stoch("PVLiab_adj", 6, t)
    double[] CV_end               = get_factor_stoch("CV_end", 0, t)

    double PVFP     = get_factor_deter("PV_profit_after_tax", 0, 0)
    double PVFPTVOG = get_factor_stoch("PV_profit_after_tax", 0, 0)
    double PVP      = get_factor_stoch("PV_premium_income", 0, 0)

   }

}