Пример #1
0
    def _create_storage(
            cls,
            freq=_default_freq,
            storage_start=_default_storage_start,
            storage_end=_default_storage_end,
            constraints=_default_constraints,
            min_inventory=None,
            max_inventory=None,
            max_injection_rate=None,
            max_withdrawal_rate=None,
            injection_cost=_constant_injection_cost,
            withdrawal_cost=_constant_withdrawal_cost,
            cmdty_consumed_inject=_constant_cmdty_consumed_inject,
            cmdty_consumed_withdraw=_constant_cmdty_consumed_withdraw,
            terminal_storage_npv=_default_terminal_npv_calc,
            inventory_loss=_constant_inventory_loss,
            inventory_cost=_constant_inventory_cost):

        return cs.CmdtyStorage(freq,
                               storage_start,
                               storage_end,
                               injection_cost,
                               withdrawal_cost,
                               constraints=constraints,
                               min_inventory=min_inventory,
                               max_inventory=max_inventory,
                               max_injection_rate=max_injection_rate,
                               max_withdrawal_rate=max_withdrawal_rate,
                               cmdty_consumed_inject=cmdty_consumed_inject,
                               cmdty_consumed_withdraw=cmdty_consumed_withdraw,
                               terminal_storage_npv=terminal_storage_npv,
                               inventory_loss=inventory_loss,
                               inventory_cost=inventory_cost)
Пример #2
0
    def test_intrinsic_value_runs(self):

        ratchets = [
                            (date(2019, 8, 28),
                                        [
                                            (0.0, -150.0, 255.2),
                                            (2000.0, -200.0, 175.0),
                                        ]),
                            (date(2019, 9, 10), 
                                     [
                                         (0.0, -170.5, 235.8),
                                         (700.0, -180.2, 200.77),
                                         (1800.0, -190.5, 174.45),
                                    ])
                ]

        storage_start = date(2019, 8, 28)
        storage_end = date(2019, 9, 25)
        constant_injection_cost = 0.015
        constant_pcnt_consumed_inject = 0.0001
        constant_withdrawal_cost = 0.02
        constant_pcnt_consumed_withdraw = 0.000088
        constant_pcnt_inventory_loss = 0.001;
        constant_pcnt_inventory_cost = 0.002;

        def terminal_npv_calc(price, inventory):
            return price * inventory - 15.4 # Some arbitrary calculation

        cmdty_storage = cs.CmdtyStorage('D', storage_start, storage_end, constant_injection_cost, constant_withdrawal_cost,
                                        ratchets, ratchet_interp=cs.RatchetInterp.LINEAR,
                                cmdty_consumed_inject=constant_pcnt_consumed_inject, cmdty_consumed_withdraw=constant_pcnt_consumed_withdraw,
                                terminal_storage_npv=terminal_npv_calc,
                                inventory_loss=constant_pcnt_inventory_loss, inventory_cost=constant_pcnt_inventory_cost)

        inventory = 650.0
        val_date = date(2019, 9, 2)

        forward_curve = utils.create_piecewise_flat_series([58.89, 61.41, 59.89, 59.89], [val_date, date(2019, 9, 12), date(2019, 9, 18), storage_end], freq='D')
        
        # TODO test with proper interest rate curve
        flat_interest_rate = 0.03
        interest_rate_curve = pd.Series(index = pd.period_range(val_date, storage_end + timedelta(days=60), freq='D'))
        interest_rate_curve[:] = flat_interest_rate

        twentieth_of_next_month = lambda period: period.asfreq('M').asfreq('D', 'end') + 20
        intrinsic_results = cs.intrinsic_value(cmdty_storage, val_date, inventory, forward_curve, settlement_rule=twentieth_of_next_month,
                        interest_rates=interest_rate_curve, num_inventory_grid_points=100)
Пример #3
0
    def test_storage_value_date_equals_storage_end_returns_zero_npv_empty_profile(
            self):
        storage_start = date(2019, 8, 28)
        storage_end = date(2019, 9, 25)
        cmdty_storage = cs.CmdtyStorage('D',
                                        storage_start,
                                        storage_end,
                                        injection_cost=0.1,
                                        withdrawal_cost=0.2,
                                        min_inventory=0,
                                        max_inventory=1000,
                                        max_injection_rate=2.5,
                                        max_withdrawal_rate=3.6)

        inventory = 0.0
        val_date = date(2019, 9, 25)

        forward_curve = utils.create_piecewise_flat_series(
            [58.89, 61.41, 70.89, 70.89],
            [storage_start,
             date(2019, 9, 12),
             date(2019, 9, 18), storage_end],
            freq='D')

        flat_interest_rate = 0.03
        interest_rate_curve = pd.Series(index=pd.period_range(
            val_date, storage_end + timedelta(days=60), freq='D'))
        interest_rate_curve[:] = flat_interest_rate

        twentieth_of_next_month = lambda period: period.asfreq('M').asfreq(
            'D', 'end') + 20
        intrinsic_results = cs.intrinsic_value(
            cmdty_storage,
            val_date,
            inventory,
            forward_curve,
            settlement_rule=twentieth_of_next_month,
            interest_rates=interest_rate_curve,
            num_inventory_grid_points=100)

        self.assertEqual(0.0, intrinsic_results.npv)
        self.assertEqual(0, len(intrinsic_results.profile))
Пример #4
0
    def test_trinomial_value_runs(self):
        constraints = [(date(2019, 8, 28), [
            (0.0, -150.0, 255.2),
            (2000.0, -200.0, 175.0),
        ]),
                       (date(2019, 9, 10), [
                           (0.0, -170.5, 235.8),
                           (700.0, -180.2, 200.77),
                           (1800.0, -190.5, 174.45),
                       ])]

        storage_start = date(2019, 8, 28)
        storage_end = date(2019, 9, 25)
        constant_injection_cost = 0.015
        constant_pcnt_consumed_inject = 0.0001
        constant_withdrawal_cost = 0.02
        constant_pcnt_consumed_withdraw = 0.000088
        constant_pcnt_inventory_loss = 0.001
        constant_pcnt_inventory_cost = 0.002

        def terminal_npv_calc(price, inventory):
            return price * inventory - 15.4  # Some arbitrary calculation

        cmdty_storage = cs.CmdtyStorage(
            'D',
            storage_start,
            storage_end,
            constant_injection_cost,
            constant_withdrawal_cost,
            constraints,
            cmdty_consumed_inject=constant_pcnt_consumed_inject,
            cmdty_consumed_withdraw=constant_pcnt_consumed_withdraw,
            terminal_storage_npv=terminal_npv_calc,
            inventory_loss=constant_pcnt_inventory_loss,
            inventory_cost=constant_pcnt_inventory_cost)

        inventory = 650.0
        val_date = date(2019, 9, 2)

        forward_curve = utils.create_piecewise_flat_series(
            [58.89, 61.41, 59.89, 59.89],
            [val_date,
             date(2019, 9, 12),
             date(2019, 9, 18), storage_end],
            freq='D')

        # TODO test with proper interest rate curve
        flat_interest_rate = 0.03
        interest_rate_curve = pd.Series(index=pd.period_range(
            val_date, storage_end + timedelta(days=60), freq='D'))
        interest_rate_curve[:] = flat_interest_rate

        # Trinomial Tree parameters
        mean_reversion = 14.5
        spot_volatility = utils.create_piecewise_flat_series(
            [1.35, 1.13, 1.24, 1.24],
            [val_date,
             date(2019, 9, 12),
             date(2019, 9, 18), storage_end],
            freq='D')
        time_step = 1.0 / 365.0

        twentieth_of_next_month = lambda period: period.asfreq('M').asfreq(
            'D', 'end') + 20
        trinomial_value = cs.trinomial_value(
            cmdty_storage,
            val_date,
            inventory,
            forward_curve,
            spot_volatility,
            mean_reversion,
            time_step,
            settlement_rule=twentieth_of_next_month,
            interest_rates=interest_rate_curve,
            num_inventory_grid_points=100)
        self.assertTrue(isinstance(trinomial_value, float))
Пример #5
0
    def test_trinomial_delta_deep_itm_equals_intrinsic_delta(self):
        storage_start = '2019-12-01'
        storage_end = '2020-04-01'
        constant_injection_rate = 700.0
        constant_withdrawal_rate = 700.0
        constant_injection_cost = 1.23
        constant_withdrawal_cost = 0.98
        min_inventory = 0.0
        max_inventory = 100000.0

        cmdty_storage = cs.CmdtyStorage(
            'D',
            storage_start,
            storage_end,
            constant_injection_cost,
            constant_withdrawal_cost,
            min_inventory=min_inventory,
            max_inventory=max_inventory,
            max_injection_rate=constant_injection_rate,
            max_withdrawal_rate=constant_withdrawal_rate)
        inventory = 0.0
        val_date = '2019-08-29'
        low_price = 23.87
        high_price = 150.32
        num_days_at_high_price = 20
        date_switch_high_price = '2020-03-12'  # TODO calculate this from num_days_at_high_price
        forward_curve = utils.create_piecewise_flat_series(
            [low_price, high_price, high_price],
            [val_date, date_switch_high_price, storage_end],
            freq='D')

        flat_interest_rate = 0.00
        interest_rate_curve = pd.Series(
            index=pd.period_range(val_date, '2020-06-01', freq='D'))
        interest_rate_curve[:] = flat_interest_rate
        # Trinomial Tree parameters
        mean_reversion = 14.5
        spot_volatility = pd.Series(
            index=pd.period_range(val_date, '2020-06-01', freq='D'))
        spot_volatility[:] = 1.15
        time_step = 1.0 / 365.0
        twentieth_of_next_month = lambda period: period.asfreq('M').asfreq(
            'D', 'end') + 20

        delta_fwd_contracts = [(storage_start, '2020-03-11'),
                               (date_switch_high_price, storage_end)]
        trinomial_deltas = cs.trinomial_deltas(
            cmdty_storage,
            val_date,
            inventory,
            forward_curve,
            spot_volatility,
            mean_reversion,
            time_step,
            interest_rates=interest_rate_curve,
            settlement_rule=twentieth_of_next_month,
            fwd_contracts=delta_fwd_contracts,
            num_inventory_grid_points=500)
        withdraw_delta = trinomial_deltas[1]
        expected_withdraw_delta = constant_withdrawal_rate * num_days_at_high_price
        pcnt_error = (withdraw_delta -
                      expected_withdraw_delta) / expected_withdraw_delta
        self.assertAlmostEqual(pcnt_error, 0.0, 3)
        self.assertTrue(isinstance(trinomial_deltas, list))