def test_call_payoff_is_correct(self):
    np.random.seed(0)
    num_samples = 8
    price = 100.0
    strike = 100.0

    price_samples = price * np.exp(
        np.random.normal(size=[num_samples]).astype(np.float32))

    payoff_samples = payoffs.call_payoff(price_samples, strike)

    with self.session() as session:
      payoff_samples_eval = session.run(payoff_samples)

    for i in range(num_samples):
      self.assertEqual(payoff_samples_eval[i],
                       (price_samples[i] -
                        strike) if price_samples[i] > strike else 0.0)
Beispiel #2
0
    def test_european_call_estimator_converges_close_to_black_scholes(self):
        current_price = 100.0
        r = interest_rate = 0.05
        vol = 0.2
        strike = 120.0
        maturity = 0.5
        dt = 0.001
        discount = tf.exp(-r * maturity)

        tol = 5e-2
        conf_level = 0.95
        batch_size = int(1e4)
        k = key_placeholder = tf.placeholder(shape=(), dtype=tf.int32)
        max_num_steps = 1e5

        bs_call_price = util.black_scholes_call_price(current_price,
                                                      interest_rate, vol,
                                                      strike, maturity)

        initial_state = tf.constant(current_price)

        dynamics_op = lambda s, t, dt: dynamics.gbm_euler_step(
            s, r, vol, t, dt, k)
        payoff_fn = lambda s: discount * payoffs.call_payoff(s, strike)

        (mean_est, mean_sq_est, _) = monte_carlo_manager.non_callable_price_mc(
            initial_state, dynamics_op, payoff_fn, maturity, batch_size, dt)

        with self.test_session() as session:
            (mean_est_eval, _, converged) = monte_carlo_manager.mc_estimator(
                mean_est, mean_sq_est, batch_size, key_placeholder, {}, tol,
                conf_level, max_num_steps, session)

            bs_call_price_eval = session.run(bs_call_price)

        self.assertTrue(converged)
        # Here the discretization bias would make these asserts fail with larger dt.
        self.assertLessEqual(mean_est_eval, bs_call_price_eval * (1.0 + tol))
        self.assertGreaterEqual(mean_est_eval,
                                bs_call_price_eval * (1.0 - tol))
Beispiel #3
0
    def test_european_call_log_euler_mc_close_to_black_scholes(self):
        current_price = 100.0
        r = interest_rate = 0.05
        vol = 0.2
        strike = 120.0
        maturity = 0.5
        dt = 0.01
        discount = tf.exp(-r * maturity)

        bs_call_price = util.black_scholes_call_price(current_price,
                                                      interest_rate, vol,
                                                      strike, maturity)

        num_samples = int(1e4)
        initial_state = tf.constant(current_price)

        dynamics_op = lambda s, t, dt: dynamics.gbm_log_euler_step(
            s, r, vol, t, dt)
        payoff_fn = lambda s: discount * payoffs.call_payoff(tf.exp(s), strike)

        (mean_outcome, mean_sq_outcome,
         _) = monte_carlo_manager.non_callable_price_mc(
             tf.log(initial_state), dynamics_op, payoff_fn, maturity,
             num_samples, dt)

        std_outcomes = util.stddev_est(mean_outcome, mean_sq_outcome)

        with self.test_session() as session:
            bs_call_price_eval = session.run(bs_call_price)
            mean_outcome_eval, std_outcomes_eval = session.run(
                (mean_outcome, std_outcomes))

        self.assertLessEqual(
            mean_outcome_eval, bs_call_price_eval +
            3.0 * std_outcomes_eval / np.sqrt(num_samples))
        self.assertGreaterEqual(
            mean_outcome_eval, bs_call_price_eval -
            3.0 * std_outcomes_eval / np.sqrt(num_samples))
Beispiel #4
0
 def _payoff_fn(log_s):
     return tf.exp(-r * maturity) * payoffs.call_payoff(
         tf.exp(log_s), strike)