def run_test(self, instrument, barrier, outin, updown, price_expected,
                 adjoint_expected):
        option = derivatives.BarrierCall(self.maturity, self.strike, barrier,
                                         self.rate, self.volatility, outin,
                                         updown)

        with tf.GradientTape() as tape:
            tape.watch(instrument)
            price_result = option.value(self.time, instrument, self.numeraire)
        delta_expected = tape.gradient(price_result, instrument)

        mask = tf.equal(delta_expected, delta_expected[..., -1, tf.newaxis])
        updates = tf.cast(price_expected > 0, FLOAT_DTYPE) / self.numeraire
        delta_expected = tf.where(mask, updates, delta_expected)

        payoff_result = option.payoff(self.time, instrument, self.numeraire)
        delta_result = option.delta(self.time, instrument, self.numeraire)
        adjoint_result = option.adjoint(self.time, instrument, self.numeraire)

        payoff_expected = price_expected[..., -1]

        assert_near(price_result, price_expected, atol=1e-4)
        assert_near(delta_result[..., :-1], delta_expected[..., :-1])
        assert_near(payoff_result, payoff_expected)
        assert_near(adjoint_result, adjoint_expected)
    def test_value_delta(self):
        # https://www.math.drexel.edu/~pg/fin/VanillaCalculator.html

        maturity, strike, rate, volatility = 1, 100, 0.05, 0.2
        binary = derivatives.BinaryCall(maturity, strike, volatility)

        time = tf.constant([0, 1 / 2, maturity], FLOAT_DTYPE)
        instrument = tf.constant([[100, 101, 91], [100., 121, 122]],
                                 FLOAT_DTYPE)
        numeraire = tf.math.exp(rate * time)

        price_expected = tf.constant([[
            0.532324834261914, 0.555946305588727, 0.
        ], [0.532324834261914, 0.904132417939148, 1.]]) / numeraire

        delta_expected = tf.constant([[
            0.018762017345847, 0.026819916282967, 0.
        ], [0.018762017345847, 0.007901435056954, 0.]]) / numeraire

        payoff_expected = price_expected[..., -1]
        adjoint_expected = tf.constant([[0., 0., 0.], [0., 0., 0.]
                                        ]) / numeraire[-1]

        price_result = binary.value(time, instrument, numeraire)
        delta_result = binary.delta(time, instrument, numeraire)
        payoff_result = binary.payoff(time, instrument, numeraire)
        adjoint_result = binary.adjoint(time, instrument, numeraire)

        assert_near(price_result, price_expected)
        assert_near(delta_result, delta_expected)
        assert_near(payoff_result, payoff_expected)
        assert_near(adjoint_result, adjoint_expected)
    def test_call(self):
        maturity, strike, rate, volatility, theta = 0.25, 90, 0.05, 0.2, 1
        jumpsize, jumpvol, intensity = 0.3, 0.2, 2.3
        putcall = derivatives.JumpPutCall(maturity, strike, rate, volatility,
                                          intensity, jumpsize, jumpvol, theta)

        time = tf.constant([0, 0.1, maturity], FLOAT_DTYPE)
        instrument = tf.constant([[100, 110, 91], [100, 121, 85]], FLOAT_DTYPE)
        numeraire = tf.math.exp(rate * time)

        price_expected = tf.constant([[
            16.8930892792925, 21.1647925209847, 1.0
        ], [16.8930892792925, 31.7191011838734, 0.0]]) / numeraire

        delta_expected = tf.constant([[
            0.573198330210462, 0.900506824015922, 1.0
        ], [0.573198330210462, 0.990415604060569, 0.0]]) / numeraire

        payoff_expected = price_expected[..., -1]

        adjoint_expected = tf.constant([[0.91, 91 / 110, 1.], [0.0, 0.0, 0.0]
                                        ]) / numeraire[-1]

        price_result = putcall.value(time, instrument, numeraire)
        delta_result = putcall.delta(time, instrument, numeraire)
        payoff_result = putcall.payoff(time, instrument, numeraire)
        adjoint_result = putcall.adjoint(time, instrument, numeraire)

        assert_near(price_result, price_expected)
        assert_near(delta_result, delta_expected)
        assert_near(payoff_result, payoff_expected)
        assert_near(adjoint_result, adjoint_expected)
示例#4
0
    def test_value_delta_multivariate(self):
        init_instruments, init_numeraire, book = \
            random_put_call_book(1.25, 10, 4, 3, 69)
        time, instruments, numeraire = book.sample_paths(
            init_instruments, init_numeraire, 3, 5, True)

        value_expected, delta_expected = self.lazy_marginal(
            instruments, numeraire, time, book)

        value_result = book.value(time, instruments, numeraire)
        delta_result = book.delta(time, instruments, numeraire)

        assert_near(value_result, value_expected)
        assert_near(delta_result, delta_expected)
    def test_call(self):
        maturity, strike, rate, volatility, theta = 0.25, 90, 0.05, 0.2, 1
        putcall = derivatives.PutCall(maturity, strike, rate, volatility,
                                      theta)

        time = tf.constant([0, 0.1, maturity], FLOAT_DTYPE)
        instrument = tf.constant([[100, 110, 91], [100., 121, 85]],
                                 FLOAT_DTYPE)
        numeraire = tf.math.exp(rate * time)

        price_expected = tf.constant([[
            11.670086691861101, 20.680949336572269, 1.
        ], [11.670086691861101, 31.672557545579522, 0.]]) / numeraire

        delta_expected = tf.constant([[
            0.89039005940552085, 0.99679661077351212, 1.
        ], [0.89039005940552085, 0.99996199608869929, 0.]]) / numeraire

        payoff_expected = price_expected[..., -1]

        adjoint_expected = tf.constant([[0.91, 91 / 110, 1.], [0., 0., 0.]
                                        ]) / numeraire[-1]

        price_result = putcall.value(time, instrument, numeraire)
        delta_result = putcall.delta(time, instrument, numeraire)
        payoff_result = putcall.payoff(time, instrument, numeraire)
        adjoint_result = putcall.adjoint(time, instrument, numeraire)

        assert_near(price_result, price_expected)
        assert_near(delta_result, delta_expected)
        assert_near(payoff_result, payoff_expected)
        assert_near(adjoint_result, adjoint_expected)
示例#6
0
    def test_value_delta_univariate(self):
        init_instruments, init_numeraire, book = simple_put_call_book(
            1., 100., 105., 0.05, 0.1, 0.2, 1.)

        time, instruments, numeraire = book.sample_paths(
            init_instruments, init_numeraire, 1, 1, True)

        value_result = book.value(time, instruments, numeraire)
        delta_result = book.delta(time, instruments, numeraire)

        value_expected, delta_expected = self.lazy_marginal(
            instruments, numeraire, time, book)

        assert_near(value_result, value_expected)
        assert_near(delta_result, delta_expected)
    def test_put_value_delta(self):
        maturity, strike, rate, volatility, theta = 1.3, 110, 0.02, 0.05, -1
        putcall = derivatives.PutCall(maturity, strike, rate, volatility,
                                      theta)

        time = tf.constant([0, 0.41, maturity], FLOAT_DTYPE)
        instrument = tf.constant([[100, 110, 120], [110., 121, 85]],
                                 FLOAT_DTYPE)
        numeraire = tf.math.exp(rate * time)

        price_expected = tf.constant([[
            7.4973075500600146, 1.2255281792756278, 0.
        ], [1.3101071219942781, 0.014761684729265312, 25.]]) / numeraire

        delta_expected = tf.constant([[
            -0.88244073147661295, -0.3442306041250397, 0.
        ], [-0.31398908314745166, -0.0077279609756593093, -1]]) / numeraire

        payoff_expected = price_expected[..., -1]

        price_result = putcall.value(time, instrument, numeraire)
        delta_result = putcall.delta(time, instrument, numeraire)
        payoff_result = putcall.payoff(time, instrument, numeraire)

        assert_near(price_result, price_expected)
        assert_near(delta_result, delta_expected)
        assert_near(payoff_result, payoff_expected)
    def test_low_variance(self):
        batch, height, width = 2**20, 3, 2
        x = get_low_variance_sample(batch, height, width, 69)
        inputs = [x[..., 0] for x in tf.split(x, width, axis=-1)]

        normaliser = preprocessing.MeanVarianceNormaliser()
        outputs = normaliser.fit_transform(inputs)

        for op in outputs:
            tf.debugging.assert_type(op, FLOAT_DTYPE)

            # test with FLOAT_DTYPE
            mean, variance = tf.nn.moments(op, 0)
            assert_near(mean, 0.)
            assert_near(variance, 1., atol=1e-2)

            # test with tf.float64
            mean, variance = tf.nn.moments(tf.cast(op, tf.float64), 0)
            assert_near(mean, 0., atol=1e-8)
            assert_near(variance, 1., atol=1e-8)

        assert_near(normaliser.inverse_transform(outputs), inputs)
示例#9
0
    def test_sample_paths(self):
        one_dim = random_put_call_book(2.5, 1, 1, 1, 56)
        multi_dim = random_put_call_book(0.5, 4, 4, 1, 69)

        for init_instruments, init_numeraire, book in [one_dim, multi_dim]:
            num_paths, num_steps = 2**22, 2
            time, instruments, numeraire = book.sample_paths(
                init_instruments, init_numeraire, num_paths, num_steps, True,
                use_sobol=True, skip=0)

            expected_dims = (num_paths, book.instrument_dim, num_steps + 1)
            self.assertTupleEqual(tuple(instruments.shape), expected_dims)

            expected_dims = (num_steps + 1, )
            self.assertTupleEqual(tuple(numeraire.shape), expected_dims)

            payoff = book.payoff(time, instruments, numeraire)
            self.assertTupleEqual(tuple(payoff.shape), (num_paths, ))

            price_result = tf.reduce_mean(payoff)
            price_expected = book.value(time, instruments, numeraire)[0, 0]

            # convergence very slow
            assert_near(price_result, price_expected, atol=1e-1)
    def test_degenerate_col(self):
        batch, height, width, degenerate = 6, 7, 8, 4
        x = get_degenerate_sample(batch, height, width, degenerate, 69)
        inputs = [x[..., 0] for x in tf.split(x, width, axis=-1)]

        normaliser = preprocessing.MeanVarianceNormaliser()
        outputs = normaliser.fit_transform(inputs)

        for step, op in enumerate(outputs):
            assert_near(tf.reduce_mean(op, 0), 0.)

            expected_var = 0. if step == degenerate else 1.
            assert_near(tf.math.reduce_variance(op, 0), expected_var)

        assert_near(normaliser.inverse_transform(outputs), inputs)
示例#11
0
 def test_jaccard_index_loss(self, y_true, y_pred, expected):
     jaccard = JaccardIndexLoss()
     try:
         assert_near(jaccard(y_true, y_pred), expected)
     except errors.InvalidArgumentError as e:
         pytest.fail(e.message, pytrace=False)
示例#12
0
 def test_f1_score(self, y_true, y_pred, expected):
     try:
         assert_near(f1_score(y_true, y_pred), expected)
     except errors.InvalidArgumentError as e:
         pytest.fail(e.message, pytrace=False)
示例#13
0
 def test_dice_coef_metric(self, y_true, y_pred, expected):
     dice = DiceCoefMetric()
     try:
         assert_near(dice(y_true, y_pred), expected)
     except errors.InvalidArgumentError as e:
         pytest.fail(e.message, pytrace=False)