Beispiel #1
0
    def test_multidimensional_constrained_optimiser(self):
        tolerance = 1e-7

        def equality_constraint(x):
            # x[0] - 1 = 0
            return x[0] - 1

        def inequality_constraint(x):
            # x_i > 0 for all i
            return x

        optimiser = Optimiser(0, tolerance, 1,
                              self.multidimensional_merit_function)

        initial_point_i = [1, 1, 1, 1, 1]
        lower_bound_i = [-1, -2, -3, -4, -5]
        upper_bound_i = [1, 2, 3, 4, 5]

        [_, obj] = optimiser.multidimensional_optimiser(
            lower_bound_i, upper_bound_i, initial_point_i,
            inequality_constraint, equality_constraint)

        target_obj = 1.0 / 5
        self.assertTrue(
            abs(obj - target_obj) < tolerance,
            "MDO didn't work, OBJ = " + str(obj))
Beispiel #2
0
    def test_brent(self):
        """
        Calculates sqrt(2) numerically by means of Brent method
        :return:
        """
        optimiser = Optimiser(2, 1e-8, 100,
                              self.single_dimensional_merit_function)

        sqrt_2 = optimiser.brent_method(0, 5)

        self.assertTrue(abs(sqrt_2 / sqrt(2) - 1) < 1e-7, "Brent didn't work")
Beispiel #3
0
    def test_newton(self):
        """
          Calculates sqrt(2) numerically by means of Newton-Raphson method
          :return:
        """
        optimiser = Optimiser(2, 1e-8, 100,
                              self.single_dimensional_merit_function)

        sqrt_2 = optimiser.newton_method(3)

        self.assertTrue(
            abs(sqrt_2 / sqrt(2) - 1) < 1e-15, "Newton didn't work")
Beispiel #4
0
    def test_root_bracketing(self):
        """
        Launch Brent with a non-bracketing interval
        :return:
        """
        optimiser = Optimiser(2, 1e-8, 100,
                              self.single_dimensional_merit_function)

        sqrt_2 = optimiser.brent_method(0, 1)
        self.assertTrue(
            abs(sqrt_2 / sqrt(2) - 1) < 1e-7,
            "Monotonic root bracketing didn't work")
        self.assertRaises(Exception, optimiser.brent_method, -1, 1)
Beispiel #5
0
    def test_multidimensional_optimiser(self):
        tolerance = 1e-7

        optimiser = Optimiser(0, tolerance, 1,
                              self.multidimensional_merit_function)

        initial_point_i = [1, 1, 1, 1, 1]
        lower_bound_i = [-1, -2, -3, -4, -5]
        upper_bound_i = [1, 2, 3, 4, 5]

        [_,
         obj] = optimiser.multidimensional_optimiser(lower_bound_i,
                                                     upper_bound_i,
                                                     initial_point_i)

        target_obj = 0
        self.assertTrue(
            abs(obj - target_obj) < tolerance,
            "MDO didn't work, OBJ = " + str(obj))
        self.assertTrue(obj < tolerance, "MDO didn't work, OBJ = " + str(obj))
Beispiel #6
0
 def _binary_search(self, random_number, t):
     from NumericalLibrary.COptimiser import Optimiser
     vector = self.model.total_cumulative_stochastic_kernels[t][
         self.model.x0, :]
     x = Optimiser.binary_search(vector, random_number)
     return x
Beispiel #7
0
def calculate_implied_volatility(underlying, strike, annuity, domestic_short_rate, foreign_short_rate,
                                 price, days_to_maturity, pay_rec):
    """ Find sigma s.t. P_t = A_t * (S_t * N(d_1(sigma)) - k * e^(- (r_d - r_f) * T) * N(d_2(sigma)))
    :param domestic_short_rate:
    :param foreign_short_rate:
    :param underlying:
    :param strike:
    :param annuity:
    :param price:
    :param days_to_maturity:
    :param pay_rec:
    :return:
    """
    from NumericalLibrary.COptimiser import Optimiser
    from math import exp

    sigma_min = 0.0001
    sigma_max = 10

    tolerance = 1e-7
    iteration_max = 100

    # --- Sanity checks --- #
    r = domestic_short_rate - foreign_short_rate
    year_fraction = float(days_to_maturity) / 365
    df = exp(-r * year_fraction)

    price_lb = 1e9
    price_ub = 0

    if pay_rec == "Payer" or pay_rec == "Call":
        price_lb = annuity * (underlying - strike * df)
        price_ub = annuity * underlying
    else:
        if pay_rec == "Receiver" or pay_rec == "Put":
            price_lb = annuity * (strike - underlying)
            price_ub = annuity * strike

    # P_t / A_t \in [i_s - i_k, i_s]
    if price < price_lb or price > price_ub:
        raise ValueError("Price not allowed in the Black model")

    if abs(price - price_lb) <= tolerance:
        raise ValueError("Price hits its lower bound. Impossible to calculate the implied vol")

    if abs(price - price_ub) <= tolerance:
        raise ValueError("Price hits its upper bound. Impossible to calculate the implied vol")

    # ---  --- #

    def internal_calculate_price(sigma):
        return calculate_price(underlying, strike, annuity, domestic_short_rate, foreign_short_rate,
                               sigma, days_to_maturity, pay_rec)

    optimiser = Optimiser(price, tolerance, iteration_max, internal_calculate_price)

    implied_vol = optimiser.brent_method(sigma_min, sigma_max)

    if abs(implied_vol - sigma_min) <= tolerance:
        raise ValueError("Hit lower bound. Algorithm might have not converged")
    if abs(implied_vol - sigma_max) <= tolerance:
        raise ValueError("Hit upper bound. Algorithm might have not converged")

    return implied_vol