def test_put_payoff_function(self): """Tests the put payoff function returns the right numbers.""" # See Longstaff, F.A. and Schwartz, E.S., 2001. Valuing American options by # simulation: a simple least-squares approach. samples = [[1.0, 1.09, 1.08, 1.34], [1.0, 1.16, 1.26, 1.54], [1.0, 1.22, 1.07, 1.03], [1.0, 0.93, 0.97, 0.92], [1.0, 1.11, 1.56, 1.52], [1.0, 0.76, 0.77, 0.90], [1.0, 0.92, 0.84, 1.01], [1.0, 0.88, 1.22, 1.34]] # Expand dims to reflect that `samples` represent sample paths of # a 1-dimensional process for dtype in (np.float32, np.float64): # Create payoff functions for 2 different strike values payoff_fn = payoff_utils.make_basket_put_payoff([1.1, 1.2], dtype=dtype) sample_paths = tf.convert_to_tensor(samples, dtype=dtype) sample_paths = tf.expand_dims(sample_paths, -1) # Actual payoff payoff = payoff_fn(sample_paths, 3) # Expected payoffs at the final time expected_payoff = [[0, 0], [0, 0], [0.07, 0.17], [0.18, 0.28], [0, 0], [0.2, 0.3], [0.09, 0.19], [0, 0]] self.assertAllClose(expected_payoff, payoff, rtol=1e-8, atol=1e-8)
def test_put_payoff_function(self, dtype): """Tests the put payoff function for a batch of strikes.""" # Create payoff functions for 2 different strike values payoff_fn = payoff_utils.make_basket_put_payoff([1.1, 1.2], dtype=dtype) sample_paths = tf.convert_to_tensor(_SAMPLES, dtype=dtype) sample_paths = tf.expand_dims(sample_paths, -1) # Actual payoff payoff = payoff_fn(sample_paths, 3) # Expected payoffs at the final time expected_payoff = [[0, 0], [0, 0], [0.07, 0.17], [0.18, 0.28], [0, 0], [0.2, 0.3], [0.09, 0.19], [0, 0]] self.assertAllClose(expected_payoff, payoff, rtol=1e-6, atol=1e-6)
def test_american_option_put(self): """Tests that LSM price of American put option is computed as expected.""" # This is the same example as in Section 1 of # Longstaff, F.A. and Schwartz, E.S., 2001. Valuing American options by # simulation: a simple least-squares approach. The review of financial # studies, 14(1), pp.113-147. basis_fn = lsm.make_polynomial_basis(2) for dtype in (np.float32, np.float64): payoff_fn = payoff.make_basket_put_payoff([1.1], dtype=dtype) # Option price american_put_price = lsm.least_square_mc( self.samples, [1, 2, 3], payoff_fn, basis_fn, discount_factors=self.discount_factors, dtype=dtype) self.assertAllClose(american_put_price, [0.1144], rtol=1e-4, atol=1e-4)
def test_american_basket_option_put(self): """Tests the LSM price of American Basket put option.""" # This is the same example as in Section 1 of # Longstaff, F.A. and Schwartz, E.S., 2001. Valuing American options by # simulation: a simple least-squares approach. The review of financial # studies, 14(1), pp.113-147. # This is the minimum number of basis functions for the tests to pass. basis_fn = lsm.make_polynomial_basis(10) exercise_times = [1, 2, 3] dtype = np.float64 payoff_fn = payoff.make_basket_put_payoff([1.1, 1.2, 1.3], dtype=dtype) # Create a 2-d process which is simply follows the `samples` paths: samples = tf.convert_to_tensor(self.samples, dtype=dtype) samples_2d = tf.concat([samples, samples], -1) # Price American basket option american_basket_put_price = lsm.least_square_mc( samples_2d, exercise_times, payoff_fn, basis_fn, discount_factors=self.discount_factors, dtype=dtype) # Since the marginal processes of `samples_2d` are 100% correlated, the # price should be the same as of the American option computed for # `samples` american_put_price = lsm.least_square_mc( self.samples, exercise_times, payoff_fn, basis_fn, discount_factors=self.discount_factors, dtype=dtype) self.assertAllClose(american_basket_put_price, american_put_price, rtol=1e-4, atol=1e-4) self.assertAllEqual(american_basket_put_price.shape, [3])