Пример #1
0
 def set_rel_time(self, init_date, freq, days_per_year):
     self._t_0 = init_date
     self._var_funcs = [
         InsStepFunc(
             vol_crv.index_time_rel_from(init_date,
                                         freq=freq,
                                         days_per_year=days_per_year),
             np.insert(np.power(vol_crv.data.values, 2), 0, 0.))
         for vol_crv in self._vol
     ]
Пример #2
0
 def test_prob_mono(self):
     """
         Test the probability is monotonic w.r.t year_frac.
     """
     x = np.array(range(0, 90))
     y = np.array(range(0, 90)) * 0.01
     y = np.insert(y, y.size, float('inf'))
     mort_func = InsStepFunc(x, y)
     mort_model = InsMortModel(mort_func)
     _probs = np.array([
         mort_model.prob(
             namedtuple('mock_iter',
                        ['attained_age', 'year_frac'])(0, year_frac))
         for year_frac in range(0, 90)
     ])
     self.assertTrue(all((_probs[1:] - _probs[:-1]) >= 0.0))
Пример #3
0
 def test_prob_range(self):
     """
         Test the probability is between 0 and 1.
     """
     x = np.random.uniform(0, 90, 10)
     x.sort()
     y = np.random.uniform(0, 4, 10)
     y = np.insert(y, y.size, float('inf'))
     mort_func = InsStepFunc(x, y)
     mort_model = InsMortModel(mort_func)
     for age, year_frac in zip(np.random.uniform(0, 90, 100),
                               np.random.uniform(0, 1, 100)):
         _prob = mort_model.prob(
             namedtuple('mock_iter',
                        ['attained_age', 'year_frac'])(age, year_frac))
         self.assertTrue(0.0 <= _prob <= 1.0)
Пример #4
0
 def test_prob_limit(self):
     """
         Test the limit case:
         1. When duration is zero, the prob is zero
         2. When duration is over the upper limit of age, prob is 1
     """
     x = np.array(range(0, 90))
     y = np.array(range(0, 90)) * 0.01
     y = np.insert(y, y.size, float('inf'))
     mort_func = InsStepFunc(x, y)
     mort_model = InsMortModel(mort_func)
     for age in range(0, 100):
         _prob = mort_model.prob(
             namedtuple('mock_iter', ['attained_age', 'year_frac'])(age,
                                                                    0.0))
         self.assertAlmostEqual(_prob, 0.0, 10)
         _prob = mort_model.prob(
             namedtuple('mock_iter',
                        ['attained_age', 'year_frac'])(age, 100 - age))
         self.assertAlmostEqual(_prob, 1.0, 10)
Пример #5
0
class InsMortModel(object):
    """
        This is the mortality model.
    """
    def __init__(self, mort_func):
        """
            The mortality model is initialized by the mort_func, which provides the
             aggregate mortality intensity
        """
        self._mort_func = mort_func

    def prob(self, model_iter):
        return 1.0 - np.exp(-1 * self._mort_func.integral(
            model_iter.attained_age, model_iter.year_frac))


if __name__ == '__main__':
    from lib.insurance import InsStepFunc
    from collections import namedtuple
    x = np.array(range(0, 90))
    y = np.array(range(0, 90)) * 0.01
    y = np.insert(y, y.size, float('inf'))
    mort_func = InsStepFunc(x, y)
    mort_model = InsMortModel(mort_func)
    for age in range(0, 90):
        _prob = mort_model.prob(
            namedtuple('mock_iter', ['attained_age', 'year_frac'])(age,
                                                                   100 - age))
        print(_prob)
Пример #6
0
    def run_va_model(self):
        raw_input = {"Acct Value": 1344581.6,
                     "Attained Age": 52.8,
                     "ID": "000001",
                     "Issue Age": 45.1,
                     "Issue Date": dt.date(2005, 6, 22),
                     "Initial Date": dt.date(2013, 2, 1),
                     "Maturity Age": 90,
                     "Population": 1,
                     "Riders": dict({}),
                     "ROP Amount": 1038872.0,
                     "Gender": "F",
                     "RPB": 1038872.0,
                     "Free Withdrawal Rate": 0.1,
                     "Asset Names": ["Fund A", "Fund B"],
                     "Asset Values": [1344581.6/2, 1344581.6/2]}

        # For now, we assume the init_date is month begin
        step_per_year = 12
        periods = 360
        init_date = dt.date(2013, 2, 1)
        pricing_date = init_date
        # Set up the investment index
        #credit_rider = isr.InsCreditRateFixed(credit_rate)

        # set up the mutual fund return index
        init_df = [ pd.TimeSeries(data=[100], index=[init_date], name='stock A'),
                    pd.TimeSeries(data=[100], index=[init_date], name='stock B')
                    ]
        eq_index = [ip.IndexProvider(init_df[0], 'stock A'), ip.IndexProvider(init_df[1], 'stock B')]

        # no vol, otherwise randomness will break my test
        sim_engine = EqBSEngine(np.array([0.02, 0.02]), np.array([0.0, 0.0]), corr=np.array([[1., 0.3], [0.3, 1.]]))
        simulator = ScenarioGenerator(eq_index, sim_engine, **{'max_time_step': 5. / BDAYS_PER_YEAR})

        MARKET_DATA_MANAGER.reset()
        MARKET_DATA_MANAGER.setup(init_date)
        MARKET_DATA_MANAGER.index_table[ 'stock A'] = eq_index[0]
        MARKET_DATA_MANAGER.index_table[ 'stock B'] = eq_index[1]
        MARKET_DATA_MANAGER.scen_gen_table['stock A']=simulator
        MARKET_DATA_MANAGER.scen_gen_table['stock B']=simulator

        fund_info = {'Fund A':
                         {
                             'Allocations': {
                                 'stock A': 1,
                                 'stock B': 0,
                             },
                             'Management Fee': 0.01,
                             'Description': 'blah blah',
                         },
                     'Fund B':
                         {
                             'Allocations': {
                                 'stock A': 0,
                                 'stock B': 1,
                             },
                             'Management Fee': 0.01,
                             'Description': 'blah blah',
                         },
        }

        credit_rider = isr.InsCreditRateMutualFunds(fund_info=fund_info)

        # Set up non-rider fees
        annual_fee_rate = 0.01
        annual_booking_fee = 100
        mgmt_fee = mif.InsFeeProp(annual_fee_rate, fee_name="Mgmt Fee")
        booking_fee = mif.InsFeeConst(annual_booking_fee, fee_name="Booking Fee")
        fees = [mgmt_fee, booking_fee]

        # Set up rider
        db_rider_fee_rate = 0.005
        db_rider = mir.InsRiderDB(extract_strict(raw_input, "ROP Amount"), db_rider_fee_rate, rider_name="UWL")
        riders = [db_rider]

        # Setup investment index
        inv_index = credit_rider.inv_index(init_date, periods, step_per_year)

        # Setup iteration
        product = InsProduct(riders, fees, inv_index)
        acct = InsAcct(raw_input, product)
        acct_iter = acct.acct_iterator()

        # Setup lapse function and lapse model
        xs = [0]
        ys = [0.0, 0.1]
        shock_func = linear_comp_bounded(1, 0, floor=0.5, cap=1.5)
        lapse_model = LapseDynamic(InsStepFunc(xs, ys), shock_func, rider_name='UWL')

        # Setup surrender charge
        xs = [0]
        ys = [100, 100]
        fixed_charge_func = InsStepFunc(xs, ys)
        xs = [0, 1, 2]
        ys = [0.0, 0.3, 0.2, 0.0]
        pct_charge_func = InsStepFunc(xs, ys)
        surrender_charge = SurrenderCharge(fixed_charge_func, pct_charge_func)

        # Setup mortality function and mortality model
        xs = [x for x in range(0, 100)]
        ys = [0.01] * 100
        ys.append(float('inf'))
        mort_model = InsMortModel(InsStepFunc(xs, ys))

        # Setup VA Model
        model = InsModelVA(acct, lapse_model, mort_model, surrender_charge)
        model_iter = model.create_iterator(pricing_date)

        # model iterator to evolve the model_iter to move forward
        metrics = ['Account Value',
                   'Active Population',
                   'Benefit Base.UWL',
                   'Rider Fee.UWL',
                   'Benefit.UWL',
                   'Fee.Mgmt Fee',
                   'Fee.Booking Fee',
                   'Date',
                   'Attained Age',
                   'Anniv Flag',
                   'Death',
                   'Lapse',
                   'Paid Benefit.UWL',
                   'Surrender Charge',
                   ]
        crv_aggregator = create_curve_aggregator(metrics)

        params = {'pricing date': init_date, 'periods': 60, 'frequency': 'MS'}
        proj_mgr = ProjectionManager(crv_aggregator, model_iter, **params)
        proj_mgr.run()

        df = crv_aggregator.to_dataframe()
        # df[['Rider Fee.UWL', 'Fee.Mgmt Fee', 'Fee.Booking Fee', 'Surrender Charge']].plot(kind='bar', stacked=True)
        return df
Пример #7
0
    riders = [db_rider]

    # Setup investment index
    inv_index = credit_rider.inv_index(init_date, periods, step_per_year)

    # Setup iteration
    product = InsProduct(riders, fees, inv_index)
    acct = InsAcct(raw_input, product)
    acct_iter = acct.acct_iterator()

    # Setup lapse function and lapse model
    xs = [0]
    ys = [0.0, 0.1]
    shock_func = linear_comp_bounded(1, 0, floor=0.5, cap=1.5)
    # lapse_model = LapseStatic(InsStepFunc(xs, ys))
    lapse_model = LapseDynamic(InsStepFunc(xs, ys),
                               shock_func,
                               rider_name='UWL')

    # Setup surrender charge
    xs = [0]
    ys = [100, 100]
    fixed_charge_func = InsStepFunc(xs, ys)
    xs = [0, 1, 2]
    ys = [0.0, 0.3, 0.2, 0.0]
    pct_charge_func = InsStepFunc(xs, ys)
    surrender_charge = SurrenderCharge(fixed_charge_func, pct_charge_func)

    # Setup mortality function and mortality model
    xs = [x for x in range(0, 100)]
    ys = [0.01] * 100
from Models.InsMortModel import InsMortModel
from Models.InsLapseModel import SurrenderCharge, LapseDynamic
from lib.insurance import InsStepFunc, linear_comp_bounded
from utils.database import pickle_save

#TODO: Technically, all the assumptions can be saved or generate on the fly or interact with user input
#TODO: But pickel it is not working now due to the use of decorator I believe.

# Setup lapse function and lapse model
xs = [0]
ys = [0.0, 0.1]
shock_func = linear_comp_bounded(1, 0, floor=0.5, cap=1.5)
lapse_model = LapseDynamic(InsStepFunc(xs, ys), shock_func, rider_name='UWL')
# pickle_save(lapse_model, 'lapse_model_sample_1')

# Setup surrender charge
xs = [0]
ys = [100, 100]
fixed_charge_func = InsStepFunc(xs, ys)
xs = [0, 1, 2]
ys = [0.0, 0.3, 0.2, 0.0]
pct_charge_func = InsStepFunc(xs, ys)
surrender_charge = SurrenderCharge(fixed_charge_func, pct_charge_func)
# pickle_save(surrender_charge, 'surrender_charge_sample_1')

# Setup mortality function and mortality model
xs = [x for x in range(0, 100)]
ys = [0.01] * 100
ys.append(float('inf'))
mort_model = InsMortModel(InsStepFunc(xs, ys))
# pickle_save(mort_model, 'mort_model_sample_1')
Пример #9
0
    def run_fa_model(self):
        raw_input = {
            "Acct Value": 1344581.6,
            "Attained Age": 52.8,
            "ID": "000001",
            "Issue Age": 45.1,
            "Issue Date": dt.date(2005, 6, 22),
            "Initial Date": dt.date(2013, 2, 1),
            "Maturity Age": 90,
            "Population": 1,
            "Riders": dict({}),
            "ROP Amount": 1038872.0,
            "Gender": "F",
            "RPB": 1038872.0,
            "Free Withdrawal Rate": 0.1,
            "Asset Names": ["Credit Account"],
            "Asset Values": [1344581.6]
        }

        # For now, we assume the init_date is month begin
        step_per_year = 12
        credit_rate = 0.03
        periods = 360
        init_date = dt.date(2013, 2, 1)
        pricing_date = init_date
        # Set up the investment index
        credit_rider = isr.InsCreditRateFixed(credit_rate)

        # Set up non-rider fees
        annual_fee_rate = 0.01
        annual_booking_fee = 100
        mgmt_fee = mif.InsFeeProp(annual_fee_rate, fee_name="Mgmt Fee")
        booking_fee = mif.InsFeeConst(annual_booking_fee,
                                      fee_name="Booking Fee")
        fees = [mgmt_fee, booking_fee]

        # Set up rider
        db_rider_fee_rate = 0.005
        db_rider = mir.InsRiderDB(extract_strict(raw_input, "ROP Amount"),
                                  db_rider_fee_rate,
                                  rider_name="UWL")
        riders = [db_rider]

        # Setup investment index
        inv_index = credit_rider.inv_index(init_date, periods, step_per_year)

        # Setup iteration
        product = InsProduct(riders, fees, inv_index)
        acct = InsAcct(raw_input, product)

        # Setup lapse function and lapse model
        xs = [0]
        ys = [0.0, 0.1]
        lapse_model = LapseStatic(InsStepFunc(xs, ys))

        # Setup surrender charge
        xs = [0]
        ys = [100, 100]
        fixed_charge_func = InsStepFunc(xs, ys)
        xs = [0, 1, 2]
        ys = [0.0, 0.3, 0.2, 0.0]
        pct_charge_func = InsStepFunc(xs, ys)
        surrender_charge = SurrenderCharge(fixed_charge_func, pct_charge_func)

        # Setup mortality function and mortality model
        xs = [x for x in range(0, 100)]
        ys = [0.01] * 100
        ys.append(float('inf'))
        mort_model = InsMortModel(InsStepFunc(xs, ys))

        # Setup FA Model
        model = InsModelFA(acct, lapse_model, mort_model, surrender_charge)
        model_iter = model.create_iterator(pricing_date)

        # model iterator to evolve the model_iter to move forward
        metrics = [
            'Account Value',
            'Active Population',
            'Benefit Base.UWL',
            'Rider Fee.UWL',
            'Benefit.UWL',
            'Fee.Mgmt Fee',
            'Fee.Booking Fee',
            'Date',
            'Attained Age',
            'Anniv Flag',
            'Death',
            'Lapse',
            'Paid Benefit.UWL',
            'Surrender Charge',
        ]
        crv_aggregator = create_curve_aggregator(metrics)

        time_line = pd.date_range(init_date, periods=60, freq='MS').date
        prev_date = init_date
        for d in time_line:
            if d != init_date:
                year_frac = (d - prev_date).days / DAYS_PER_YEAR
                model_iter.next(d, year_frac)
            crv_aggregator.collect_element(model_iter)
            prev_date = d
        df = crv_aggregator.to_dataframe()
        return df