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)
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)
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))
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))
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))