モデル3 - 医療保険

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

このファイルでは、医療保険のモデルを記述しています。

医療保険


calculation Medical(Base) {

// P基礎基数
module CT_P{

    double CIR = Asm.get_double("CIR_P")
    double[] qx =
       if (sex == "M"){ Asm.get_double("qx_m_SLT1996", x) }
                 else { Asm.get_double("qx_f_SLT1996", x) }

    double[] qx_hosp = if (sex == "M"){ Asm.get_double("qx_hosp_m", x) }
                                 else { Asm.get_double("qx_hosp_f", x) }
    double[] Tx_hosp = if (sex == "M"){ Asm.get_double("Tx_hosp_m", x) }
                                 else { Asm.get_double("Tx_hosp_f", x) }
    double[] qx_acci = if (sex == "M"){ Asm.get_double("qx_acci_m", x) }
                                 else { Asm.get_double("qx_acci_f", x) }
    double[] Tx_acci = if (sex == "M"){ Asm.get_double("Tx_acci_m", x) }
                                 else { Asm.get_double("Tx_acci_f", x) }
    double[] qx_surg = if (sex == "M"){ Asm.get_double("qx_surg_m", x) }
                                 else { Asm.get_double("qx_surg_f", x) }
    double[] Tx_surg = 20.0

    double[] Cx_hosp = Dx(x) * qx_hosp(x) * Tx_hosp(x) * (v ^ 0.5) * (1 - qx(x) * 0.5)
    double[] Cx_acci = Dx(x) * qx_acci(x) * Tx_acci(x) * (v ^ 0.5) * (1 - qx(x) * 0.5)
    double[] Cx_surg = Dx(x) * qx_surg(x) * Tx_surg(x) * (v ^ 0.5) * (1 - qx(x) * 0.5)

    double[] Mx_hosp =
        if (x >= Util.max_x) { Cx_hosp(x) }
        else                 { Cx_hosp(x) + Mx_hosp(x + 1) }
    double[] Mx_acci =
        if (x >= Util.max_x) { Cx_acci(x) }
        else                 { Cx_acci(x) + Mx_acci(x + 1) }
    double[] Mx_surg =
        if (x >= Util.max_x) { Cx_surg(x) }
        else                 { Cx_surg(x) + Mx_surg(x + 1) }

}

// V基礎基数
module CT_V{

    double CIR = Asm.get_double("CIR_V")
    double[] qx =
       if (sex == "M"){ Asm.get_double("qx_m_SLT1996", x) }
                 else { Asm.get_double("qx_f_SLT1996", x) }

    double[] qx_hosp = if (sex == "M"){ Asm.get_double("qx_hosp_m", x) }
                                 else { Asm.get_double("qx_hosp_f", x) }
    double[] Tx_hosp = if (sex == "M"){ Asm.get_double("Tx_hosp_m", x) }
                                 else { Asm.get_double("Tx_hosp_f", x) }
    double[] qx_acci = if (sex == "M"){ Asm.get_double("qx_acci_m", x) }
                                 else { Asm.get_double("qx_acci_f", x) }
    double[] Tx_acci = if (sex == "M"){ Asm.get_double("Tx_acci_m", x) }
                                 else { Asm.get_double("Tx_acci_f", x) }
    double[] qx_surg = if (sex == "M"){ Asm.get_double("qx_surg_m", x) }
                                 else { Asm.get_double("qx_surg_f", x) }
    double[] Tx_surg = 20.0

    double[] Cx_hosp = Dx(x) * qx_hosp(x) * Tx_hosp(x) * (v ^ 0.5) * (1 - qx(x) * 0.5)
    double[] Cx_acci = Dx(x) * qx_acci(x) * Tx_acci(x) * (v ^ 0.5) * (1 - qx(x) * 0.5)
    double[] Cx_surg = Dx(x) * qx_surg(x) * Tx_surg(x) * (v ^ 0.5) * (1 - qx(x) * 0.5)

    double[] Mx_hosp =
        if (x >= Util.max_x) { Cx_hosp(x) }
        else                 { Cx_hosp(x) + Mx_hosp(x + 1) }
    double[] Mx_acci =
        if (x >= Util.max_x) { Cx_acci(x) }
        else                 { Cx_acci(x) + Mx_acci(x + 1) }
    double[] Mx_surg =
        if (x >= Util.max_x) { Cx_surg(x) }
        else                 { Cx_surg(x) + Mx_surg(x + 1) }

}

// レート計算
module Rate{

    // 予定事業費
    double gamma = 0.0
    double alpha = 0.0
    double beta =  0.1
    double zill_alpha = alpha

    // 保険料
    double grossP = baseP * 12.0
    double baseP =
        ( benefitPV_P(0) + alpha + CT_P.annuity_xn(x, n) * gamma )
        / ( (1.0 - beta) * CT_P.annuity_xn_12(x, m) * 12.0 )

    // 純保険料
    double netP_P = ( benefitPV_P(0) + alpha + CT_P.annuity_xn(x, n) * gamma )
                    / CT_P.annuity_xn(x, m)

    double netP_V = ( benefitPV_V(0) + alpha + CT_V.annuity_xn(x, n) * gamma )
                    / CT_V.annuity_xn(x, m)

    // 経過t年での給付現価
    double[] benefitPV_P =  if (t > n) { 0.0 }
                            elseif ( CT_P.Dx(x + t) <= 0.0) { 0.0 }
                            else   { ( CT_P.Mx_hosp(x + t) - CT_P.Mx_hosp(x + n) +
                                       CT_P.Mx_acci(x + t) - CT_P.Mx_acci(x + n) +
                                       CT_P.Mx_surg(x + t) - CT_P.Mx_surg(x + n) )
                                       / CT_P.Dx(x + t) }
    double[] benefitPV_V = if (t > n) { 0.0 }
                            elseif ( CT_V.Dx(x + t) <= 0.0) { 0.0 }
                            else   { ( CT_V.Mx_hosp(x + t) - CT_V.Mx_hosp(x + n) +
                                       CT_V.Mx_acci(x + t) - CT_V.Mx_acci(x + n) +
                                       CT_V.Mx_surg(x + t) - CT_V.Mx_surg(x + n) )
                                       / CT_V.Dx(x + t) }

    // NetV, 解約返戻金、全チルV
    double[] netV_P =
        if (t == 0 || t > n) { 0.0 }
        elseif ( CT_P.Dx(x + t) <= 0.0) { 0.0 }
        else {   Utl.max(  benefitPV_P(t)
                         + CT_P.annuity_xn(x + t, n - t) * gamma
                         - CT_P.annuity_xn(x + t, m - t) * netP_P
                         , 0.0 )
             }

    double[] netV_V =
        if (t == 0 || t > n) { 0.0 }
        elseif ( CT_V.Dx(x + t) <= 0.0) { 0.0 }
        else {  Utl.max(  benefitPV_V(t)
                        + CT_V.annuity_xn(x + t, n - t) * gamma
                        - CT_V.annuity_xn(x + t, m - t) * netP_V
                        , 0.0 )
             }

    double[] CV =
        if (t < 10) { Utl.max( netV_P(t) - zill_alpha * (10.0 - t) / 10.0, 0.0) }
        else        { netV_P(t) }

    double[] azilV_V =
        if (t < m)
            {   netV_V(t)
              - zill_alpha * CT_V.annuity_xn(x + t, m - t) / CT_V.annuity_xn(x, m)
            }
        else { netV_V(t) }

}

// キャッシュフロー
module CashFlow{

    // 前提(死亡率・発生率・解約率・選択効果)
    double[] qx_crude =
        if (t == 0)         { 0.0 }
        elseif (sex == "M") { Asm.get_double("qx_m_SLT1996", x + t - 1) }
        else                { Asm.get_double("qx_f_SLT1996", x + t - 1) }
    double[] qwx_crude = Asm.get_double("qwx_crude_Medical", t)

    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) }
    double[] Tx_hosp       = if (t == 0)         { 0.0 }
                             elseif (sex == "M") { Asm.get_double("Tx_hosp_m", x + t - 1) }
                             else                { Asm.get_double("Tx_hosp_f", x + t - 1) }
    double[] qx_acci_crude = if (t == 0)         { 0.0 }
                             elseif (sex == "M") { Asm.get_double("qx_acci_m", x + t - 1) }
                             else                { Asm.get_double("qx_acci_f", x + t - 1) }
    double[] Tx_acci       = if (t == 0)         { 0.0 }
                             elseif (sex == "M") { Asm.get_double("Tx_acci_m", x + t - 1) }
                             else                { Asm.get_double("Tx_acci_f", x + t - 1) }
    double[] qx_surg_crude = if (t == 0)         { 0.0 }
                             elseif (sex == "M") { Asm.get_double("qx_surg_m", x + t - 1) }
                             else                { Asm.get_double("qx_surg_f", x + t - 1) }
    double[] Tx_surg = 20.0

    double[] selection_factor = Asm.get_double("selection_factor_death", t)
    double[] selection_factor_medical = Asm.get_double("selection_factor_medical", t)

    // コミッション
    double comm_ratio_first = Asm.get_double("comm_ratio_first")
    double comm_ratio_recur = Asm.get_double("comm_ratio_recur")
    double comm_ratio_year = Asm.get_double("comm_ratio_year")

    // 給付の定義
    double[] death_benefit_perS = 0.0
    double[] surrender_benefit_perS =
                    if (t == 0 || t > n) { 0.0 }
                    else { Rate.CV(t) }
    double[] endow_benefit_perS = 0.0

    // 医療給付の定義
    double[] qx_hosp_base = qx_hosp_crude(t) * selection_factor_medical(t)
    double[] qx_acci_base = qx_acci_crude(t) * selection_factor_medical(t)
    double[] qx_surg_base = qx_surg_crude(t) * selection_factor_medical(t)

    double[] qx_hosp = qx_hosp_base(t) * (1.0 + morb_shock) * (1.0 + morb_shock_ex)
    double[] qx_acci = qx_acci_base(t) * (1.0 + morb_shock) * (1.0 + morb_shock_ex)
    double[] qx_surg = qx_surg_base(t) * (1.0 + morb_shock) * (1.0 + morb_shock_ex)

    double[] dx_hosp = lx_beg(t) * qx_hosp(t) * (1.0 - qx(t) / 2.0) * (1.0 - qwx(t) / 2.0)
    double[] dx_acci = lx_beg(t) * qx_acci(t) * (1.0 - qx(t) / 2.0) * (1.0 - qwx(t) / 2.0)
    double[] dx_surg = lx_beg(t) * qx_surg(t) * (1.0 - qx(t) / 2.0) * (1.0 - qwx(t) / 2.0)

    double[] medical_benefit_hosp = S * dx_hosp(t) * Tx_hosp(t)
    double[] medical_benefit_acci = S * dx_acci(t) * Tx_acci(t)
    double[] medical_benefit_surg = S * dx_surg(t) * Tx_surg(t)
    double[] medical_benefit = medical_benefit_hosp(t) + medical_benefit_acci(t) + medical_benefit_surg(t)

    // ユニットコスト
    double expense_acq_perN = Asm.get_double("expense_acq_perN_medical")
    double expense_acq_perS = Asm.get_double("expense_acq_perS_medical")
    double expense_acq_perP = Asm.get_double("expense_acq_perP_medical")
    double expense_maint_paying_perS = Asm.get_double("expense_maint_paying_perS_medical")
    double expense_maint_paying_perN = Asm.get_double("expense_maint_paying_perN_medical")
    double expense_maint_paid_perS = Asm.get_double("expense_maint_paid_perS_medical")
    double expense_maint_paid_perN = Asm.get_double("expense_maint_paid_perN_medical")
    double expense_maint_perP = Asm.get_double("expense_maint_perP_medical")

}

}