Example #1
0
 def index(self):
     """return a dataframe, keep API the same after introducing .indices, which is a list ot ts"""
     result = pd.concat([x.data for x in self.indices],
                        join='outer',
                        axis=1)
     result.columns = self.index_names
     result = ip.IndexProvider(result)
     return result
Example #2
0
    def asset_return(self, _prev_date):

        # reorder the inv index to be consistent with asset names if needed.
        # if the investment index is of a single asset: use that asset for all accounts -> dangerous
        # TODO: more strict asset setting: crediting index must have the same asset name as self._asset_names

        return_index = self._inv_index if self._inv_index.n_assets == 1 else \
            ip.IndexProvider(self._inv_index.data[self._asset_names])
        return inv_return(_prev_date, self._date, self._asset_values,
                          return_index)
Example #3
0
    # 1/ create a fixed rate bond
    b = AssBondFixRate(face=100,
                       coupon_rate=0.05,
                       frequency=4,
                       issue_date=dt.date(2014, 4, 15),
                       expiration_date=dt.date(2016, 4, 15),
                       dcf=dcf_act_act,
                       pricing_model=None,
                       name='Sample Bond 1',
                       )

    # or a "float rate bond" but provided with a scenario generator gives you flat rate
    init_df = pd.TimeSeries(data=[[0.0]], index=pd.date_range(start=dt.date(2014, 4, 15), periods=1, freq='D').date,
                            name=['LIBOR_3M'])
    ir_index = ip.IndexProvider(init_df, 'LIBOR_3M')
    sim_engine = FixRateEngine(0.05)
    scen_gen = ScenarioGenerator([ir_index], sim_engine, **{'max_time_step': 5. / 252})

    # a LIBOR 3M +50 bps floater
    b = AssBondFloater(rate_index_name='LIBOR_3M', spread=0.005)

    # 1.5/ print coupon rate at any fixing date
    print(b.coupon_rate(dt.date(2014, 6, 12)))

    # 2/ create bond iterator
    it = b.bond_iterator()

    # 3/ print essentials at initial step
    print(it)
Example #4
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
Example #5
0
    def test_variable_credit_rate(self):
        # TODO: bear in mind that the fund info fee is not implemented yet
        init_df = [pd.TimeSeries(data=np.exp(np.random.randn(10)),
                                 index=pd.date_range(start=dt.date(2014, 1, 1), periods=10, freq='D').date,
                                 name='stock A'),
                   pd.TimeSeries(data=np.exp(np.random.randn(10)),
                                 index=pd.date_range(start=dt.date(2014, 1, 1), periods=10, freq='D').date,
                                 name='stock B'),
                   ]
        eq_index = [ip.IndexProvider(init_df[0], 'stock A'), ip.IndexProvider(init_df[1], 'stock B')]
        sim_engine = EqBSEngine(np.array([0.02, 0.02]), np.array([0.2, 0.25]), 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(dt.date(2014, 1, 1))
        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

        mix_weight = 0.4

        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',
                         },
                     'Fund C':
                         {
                             'Allocations': {
                                 'stock A': mix_weight,
                                 'stock B': 1-mix_weight,
                             },
                             'Management Fee': 0.01,
                             'Description': 'blah blah',
                         },
        }

        ic = InsCreditRateMutualFunds(fund_info=fund_info)
        index = ic.inv_index(dt.date(2014, 1, 10), periods=360, step_per_year=12)

        # since Fund A is 100% stock A, the return should be equal
        self.assertEqual(np.array(abs(eq_index[0].data - index.data['Fund A'])).max(),0.0)

        # since Fund B is 100% stock B, the return should be equal
        self.assertEqual(np.array(abs(eq_index[1].data - index.data['Fund B'])).max(),0.0)

        # Fund C is 50% 50% mix of stock A and B
        self.assertEqual(np.array(abs(mix_weight * eq_index[0].data + (1-mix_weight) * eq_index[1].data)
                                  - index.data['Fund C']).max(), 0.0)
Example #6
0
def main():

    # # Test single asset
    # init_df = pd.DataFrame(data=np.exp(np.random.randn(10)),
    #                        index=pd.date_range(start=dt.date(2014, 1, 1), periods=10, freq='D').date,
    #                        columns=['stock A'])
    # eq_index = ip.IndexProvider(init_df)
    # print(eq_index.data)
    # sim_engine = EqBSEngine(np.array([0.02]),
    #                         np.array([0.2]))
    # simulator = ScenarioGenerator(eq_index, sim_engine, **{'max_time_step': 5./BDAYS_PER_YEAR})
    # simulator.next(dt.date(2014, 3, 1))
    # print(eq_index.data)

    # # Test Multiple asset case
    # init_df = pd.DataFrame(data=np.exp(np.random.randn(10, 2)),
    #                        index=pd.date_range(start=dt.date(2014, 1, 1), periods=10, freq='D').date,
    #                        columns=['stock A', 'stock B'])
    # eq_index = ip.IndexProvider(init_df)
    # print(eq_index.data)
    # sim_engine = EqBSEngine(np.array([0.02, 0.02]), np.array([0.2, 0.25]), corr=np.array([[1., 0.3], [0.3, 1.]]))
    # simulator = ScenarioGenerator(eq_index, sim_engine, **{'max_time_step': 5./BDAYS_PER_YEAR})
    # simulator.next(dt.date(2014, 3, 1))
    # print(eq_index.data)

    # Test Term Structure
    data = [
        pd.TimeSeries(data=np.exp(np.random.randn(10)),
                      index=pd.date_range(start=dt.date(2014, 1, 1),
                                          periods=10,
                                          freq='D').date),
        pd.TimeSeries(data=np.exp(np.random.randn(10)),
                      index=pd.date_range(start=dt.date(2014, 1, 1),
                                          periods=10,
                                          freq='D').date)
    ]

    vol_term = pd.TimeSeries(data=np.array([0.2, 0.25, 0.3, 0.32, 0.35, 0.4]),
                             index=[
                                 dt.date(2014, 1, 1),
                                 dt.date(2014, 7, 1),
                                 dt.date(2015, 1, 1),
                                 dt.date(2016, 1, 1),
                                 dt.date(2019, 1, 1),
                                 dt.date(2024, 1, 1)
                             ])
    eq_indices = [
        ip.IndexProvider(data[0], 'index A'),
        ip.IndexProvider(data[1], 'index B')
    ]

    print(eq_indices[0].index_name)
    print(eq_indices[0].data)
    print(eq_indices[1].index_name)
    print(eq_indices[1].data)

    sim_engine = EqBSTermEngine(np.array([0.02]),
                                np.array([ip.IndexProvider(vol_term)]))
    simulator = ScenarioGenerator(
        eq_indices, sim_engine, **{
            'max_time_step': 5. / BDAYS_PER_YEAR,
            'initial_date': dt.date(2014, 1, 1)
        })
    simulator.next(dt.date(2020, 12, 31))

    print(eq_indices[0].index_name)
    print(eq_indices[0].data)
    print(eq_indices[1].index_name)
    print(eq_indices[1].data)