示例#1
0
def test_mc_rn_measure():

    kappa = 0.3
    rate = 0.04
    initial_curve = get_mock_yield_curve_const(rate=rate)

    linear_local = LinearLocalVolatility.from_const(30, 0.1, 0.1, 0.1)

    number_samples = 400
    number_steps = 100

    t_horizon = 5
    dt = t_horizon / number_steps
    x_simulator = ProcessSimulator(number_samples, number_steps, dt)
    local_volatility = linear_local

    res = x_simulator.simulate_xy(kappa=kappa,
                                  local_volatility=local_volatility)

    interest_rate = res.x + initial_curve.get_inst_forward(res.time_grid)

    bond_mc = np.exp(-np.trapz(interest_rate, res.time_grid))

    avg_bond = np.mean(bond_mc)
    std_mc = np.std(bond_mc) / np.sqrt(number_samples)

    upper_bound = avg_bond + 3 * std_mc
    lower_bound = avg_bond - 3 * std_mc

    assert np.exp(-rate * t_horizon) > lower_bound and np.exp(
        -rate * t_horizon) < upper_bound
示例#2
0
def test_runge_kutta_approx():

    kappa = 0.3
    t = 10

    initial_curve = LiborCurve.from_constant_rate(0.06)
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    sigma_r = LinearLocalVolatility.from_const(t, 0.4, 0.1, 0)
    swap = Swap(4, 5, 0.5)

    swap0 = swap_pricer.price(swap, 0, 0, 0)

    integration_grid_size = 2*10 + 1
    rk_approx = RungeKuttaApproxXY(integration_grid_size, swap_pricer, sigma_r, swap)
    res = rk_approx.calculate_xy()

    piterbarg_approx = PiterbargExpectationApproximator(sigma_r, swap_pricer)

    time_grid = res.t
    xbar = []
    ybar = []
    for t in time_grid:
        ybar.append(piterbarg_approx.ybar_formula(t))
        xbar.append(piterbarg_approx.xbar_formula(t, ybar[-1], swap, swap0, 0))

    print("As")
示例#3
0
    def simulate_process(self,
                         kappa: float,
                         local_volatility: LinearLocalVolatility,
                         random_numbers,
                         chunk_sim=0):

        number_samples, number_time_steps = random_numbers.shape

        x = np.zeros(shape=(number_samples, number_time_steps + 1))
        y = np.zeros(shape=(number_samples, number_time_steps + 1))

        for i in np.arange(0, number_samples):
            print("Simulation: " + str(i + chunk_sim))
            for j in np.arange(0, number_time_steps):
                t = self.dt * j
                eta = local_volatility.calculate_vola(t, x[i][j], y[i][j])
                # mu_x = y[i][j] - kappa * x[i][j]
                # x[i][j + 1] = x[i][j] + mu_x * self.dt + eta * random_numbers[i][j] * np.sqrt(self.dt)
                # y[i][j + 1] = y[i][j] + (np.power(eta, 2) - 2 * kappa * y[i][j]) * self.dt

                x[i][j + 1] = x[i][j] + self.get_drift_x(kappa, y[i][j], x[i][j], eta, t) * self.dt + eta * \
                              random_numbers[i][j]
                y[i][j + 1] = y[i][j] + self.get_drift_y(eta, kappa,
                                                         y[i][j]) * self.dt
        return x, y
示例#4
0
def test_approx():
    kappa = 0.03

    initial_curve = LiborCurve.from_constant_rate(0.06)
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    sigma_r = LinearLocalVolatility.from_const(15, 0.4, 0.06, 0.2)
    swaption_expiry = 4
    swap = Swap(swaption_expiry, 5, 0.5)

    coupon = swap_pricer.price(swap, 0, 0, 0)

    swaption = Swaption(swaption_expiry, coupon, swap)
    xyapproximator = RungeKuttaApproxXY
    #xyapproximator = PitergargDiscreteXY

    for xyapproximator in [RungeKuttaApproxXY, PitergargDiscreteXY]:
        for k in [16]:
            grid_size = 2**k + 1
            #xy_calculator = PitergargDiscreteXY(grid_size, swap_pricer, sigma_r, swap)
            xy_calculator = xyapproximator(grid_size, swap_pricer, sigma_r, swap)
            integration_approx = DiscreteParameterAveraging(grid_size, swap_pricer, sigma_r, swap, xy_calculator)
            lambda_avg, beta_avg = integration_approx.calculate_average_param()
            swaption_value, black_implied_vola = lognormalimpliedvola(swaption, swap_pricer, lambda_avg, beta_avg)

            print(lambda_avg, beta_avg)
            print(swaption_value, black_implied_vola)
示例#5
0
def test_swaption_price():

    kappa = 0.03

    swaption_expiry = 4
    swap_maturity = 5
    swap_freq = 0.5

    initial_curve = LiborCurve.from_constant_rate(0.06)
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    sigma_r = LinearLocalVolatility.from_const(swap_maturity, 0.4, 0.1, 0)

    piterbarg_approx = PiterbargExpectationApproximator(sigma_r, swap_pricer)
    swap = Swap(swaption_expiry, swap_maturity, swap_freq)

    displaced_diffusion = DisplacedDiffusionParameterApproximator(sigma_r, swap_pricer, swap, piterbarg_approx)
    coupon = swap_pricer.price(swap, 0, 0, 0)

    swaption = Swaption(swaption_expiry, coupon, swap)

    b_s = displaced_diffusion.calculate_bs
    lambda_s_bar, b_bar = calculate_vola_skew(swaption.expiry, displaced_diffusion.calculate_lambda_square, b_s)

    swaption_value, black_implied_vola = lognormalimpliedvola(swaption, swap_pricer, lambda_s_bar, b_bar)

    print(lambda_s_bar, b_bar)
    print(swaption_value, black_implied_vola)
示例#6
0
def plot_model_vs_market_data(market_data, res, approximator):

    expiry = market_data["Expiry"].iloc[0]
    tenor = market_data["Tenor"].iloc[0]
    curve_rate = market_data["Rate"].iloc[0]

    kappa = 0.03
    initial_curve = get_mock_yield_curve_const(rate=curve_rate)
    swap_pricer = SwapPricer(initial_curve, kappa)
    swaption_pricer = SwaptionPricer(swap_pricer)
    swap = Swap(expiry, expiry + tenor, frequency=0.5)

    atm_swap_price = swap_pricer.price(swap, 0, 0, 0)

    sigma_r = LinearLocalVolatility.from_const(int(swap.TN), res.x[0],
                                               curve_rate, res.x[1])

    xy_calculator = approximator(grid_size, swap_pricer, sigma_r, swap)
    aprox_type = str(xy_calculator)
    integration_approx = DiscreteParameterAveraging(grid_size, swap_pricer,
                                                    sigma_r, swap,
                                                    xy_calculator)
    lambda_avg, beta_avg = integration_approx.calculate_average_param()

    moneyness_ls = []
    market_implied_vola_ls = []
    black_implied_vola_ls = []
    swaption_value_fd_ls = []
    for row_id, inp_data in market_data.iterrows():
        expiry = inp_data["Expiry"]
        coupon = inp_data["moneyness"] + atm_swap_price
        if coupon < 0:
            continue
        swaption = Swaption(expiry, coupon, swap)
        market_implied_vola_ls.append(inp_data["implied black vola"])

        swaption_value_fd = price_fd(swaption_pricer, sigma_r, swaption)

        swaption_value_fd_ls.append(swaption_value_fd)
        swaption_value, black_implied_vola = lognormalimpliedvola(
            swaption, swap_pricer, lambda_avg, beta_avg)
        black_implied_vola_ls.append(black_implied_vola)
        print(swaption_value_fd_ls)
        moneyness_ls.append(inp_data["moneyness"])

    fig = plt.figure()
    plt.plot(moneyness_ls, market_implied_vola_ls, "g-x", label="Market data")
    plt.plot(moneyness_ls,
             black_implied_vola_ls,
             "r-x",
             label="Approximate solution")
    plt.plot(moneyness_ls,
             swaption_value_fd_ls,
             "b-x",
             label="Finite Difference repricing")
    plt.legend()

    return fig
示例#7
0
def test_mc_swaption():

    swap_T0 = 1
    swap_TN = 2
    coupon = 0.062
    frequency = 0.5

    swap = Swap(swap_T0, swap_TN, frequency)

    kappa = 0.3
    rate = 0.06
    initial_curve = get_mock_yield_curve_const(rate=rate)

    x = np.arange(0, 31)
    y = np.ones(31) * 0.1

    lambda_t = interp1d(x, y, kind='previous')
    alpha_t = interp1d(x, y, kind='previous')
    b_t = interp1d(x, y * 0, kind='previous')

    linear_local = LinearLocalVolatility(lambda_t, alpha_t, b_t)

    #linear_vola = local_volatility
    #linear_local = LinearLocalVolatility.from_const(30, 0.1, 0.1, 0.1)

    number_samples = 100
    number_steps = 10
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    t_horizon = swap_T0
    dt = t_horizon / number_steps
    x_simulator = ProcessSimulator(number_samples, number_steps, dt)
    local_volatility = linear_local

    res = x_simulator.simulate_xy(kappa=kappa,
                                  local_volatility=local_volatility)

    interest_rate = res.x + initial_curve.get_inst_forward(res.time_grid)

    swaption = Swaption(swap_T0, coupon, swap)
    swaption_pricer = SwaptionPricer(swap_pricer)

    swaption_fair = swaption_pricer.maturity_price(swaption, res.x[:, -1],
                                                   res.y[:, -1])
    swaption_mc = np.exp(
        -np.trapz(interest_rate, res.time_grid)) * swaption_fair

    exp_swaption_mc = np.mean(swaption_mc)
    upper_value = exp_swaption_mc + 3 * np.std(swaption_mc) / np.sqrt(
        number_samples)
    lower_value = exp_swaption_mc - 3 * np.std(swaption_mc) / np.sqrt(
        number_samples)

    print("Swaption mean: {:.4f}, lower: {:.4f}, upper: {:.4f}".format(
        exp_swaption_mc, lower_value, upper_value))
示例#8
0
def test_mc_swaption_annuity():
    swap_T0 = 1
    swap_TN = 2
    coupon = 0.062
    frequency = 0.5

    swap = Swap(swap_T0, swap_TN, frequency)
    random_number_generator_type = "sobol"
    random_number_generator_type = "normal"

    kappa = 0.3
    rate = 0.06
    initial_curve = get_mock_yield_curve_const(rate=rate)

    x = np.arange(0, 31)
    y = np.ones(31) * 0.1

    lambda_t = interp1d(x, y, kind='previous')
    alpha_t = interp1d(x, y, kind='previous')
    b_t = interp1d(x, y * 0, kind='previous')

    linear_local = LinearLocalVolatility(lambda_t, alpha_t, b_t)

    # linear_vola = local_volatility
    # linear_local = LinearLocalVolatility.from_const(30, 0.1, 0.1, 0.1)

    number_samples = np.power(2, 12)
    number_steps = np.power(2, 7)
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    t_horizon = swap_T0
    dt = t_horizon / number_steps
    annuity_pricer = AnnuityPricer(swap_pricer.bond_pricer)
    x_simulator = ProcessSimulator(number_samples, number_steps, dt,
                                   random_number_generator_type,
                                   annuity_pricer)

    local_volatility = linear_local
    annuity = Annuity(swap.bond_list, frequency)

    res = x_simulator.simulate_xy(kappa=kappa,
                                  local_volatility=local_volatility,
                                  annuity_measure=annuity)
    swaption_pricer = SwaptionPricer(swap_pricer)
    swaption = Swaption(swap_T0, coupon, swap)

    res = monte_carlo_pricer_annuity(res, swaption, swaption_pricer)

    exp_swaption_mc = np.mean(res)
    upper_value = exp_swaption_mc + 3 * np.std(res) / np.sqrt(number_samples)
    lower_value = exp_swaption_mc - 3 * np.std(res) / np.sqrt(number_samples)

    fd_price = 0.002313
    print("Swaption mean: {:.6f}, lower: {:.6f}, upper: {:.6f}".format(
        exp_swaption_mc, lower_value, upper_value))
示例#9
0
def calculate_x_boundaries(y, kappa, maturity,
                           volatility: LinearLocalVolatility):

    eta_square = volatility.calculate_vola(0, 0, 0)
    exp_x = y / kappa * (1 - np.exp(-kappa * maturity))
    var_x = eta_square / (2 * kappa) * (1 - np.exp(-2 * kappa * maturity))

    x_max = exp_x + 3 * np.sqrt(var_x)
    x_min = exp_x - 3 * np.sqrt(var_x)

    return x_min, x_max
示例#10
0
def test_adi_swaption():

    swaption_expiry = 1
    swaption_maturity = 2
    freq = 0.5
    coupon = 0.062
    rate = 0.06

    initial_curve = get_mock_yield_curve_const(rate=rate)
    kappa = 0.3

    swap_pricer = SwapPricer(initial_curve, kappa)
    swap = Swap(swaption_expiry, swaption_maturity, freq)
    swaption_pricer = SwaptionPricer(swap_pricer)

    swaption = Swaption(swaption_expiry, coupon, swap)

    x = np.arange(0, 31)
    y = np.ones(31) * 0.1

    lambda_t = interp1d(x, y, kind='previous')
    alpha_t = interp1d(x, y, kind='previous')
    b_t = interp1d(x, y * 0, kind='previous')

    local_volatility = LinearLocalVolatility(lambda_t, alpha_t, b_t)

    #local_volatility = LinearLocalVolatility.from_const(30, 0.1, 0.1, 0.1)

    t_min = 0
    t_max = swaption_expiry
    t_grid_size = 100
    x_grid_size = 401

    y_grid_size = 20

    x_min, x_max = calculate_x_boundaries2(t_max, local_volatility, alpha=3)
    y_min, y_max = calculate_u_boundaries(t_max,
                                          kappa,
                                          local_volatility,
                                          alpha=3)

    mesher = Mesher2d()
    mesher.create_mesher_2d(t_min, t_max, t_grid_size, x_min, x_max,
                            x_grid_size, y_min, y_max, y_grid_size)

    theta = 0.5
    adi_runner = AdiRunner(theta, kappa, initial_curve, local_volatility,
                           mesher)

    swaption_value0 = adi_runner.run_adi(swaption, swaption_pricer)

    x0 = extract_x0_result(swaption_value0, mesher.xgrid, mesher.ugrid)
    print("Swaption value at 0: ", x0)
示例#11
0
    def __init__(self, x, y, time_grid, number_samples, number_time_steps,
                 kappa, local_volatility: LinearLocalVolatility, measure,
                 random_number_generator_type, nr_scrambles):

        self.x = x
        self.y = y
        self.time_grid = time_grid
        self.number_samples = number_samples
        self.number_time_steps = number_time_steps
        self.kappa = kappa
        self.local_volatility = local_volatility

        self.x_bar = x.mean(axis=0)
        self.y_bar = y.mean(axis=0)
        self.n_scrambles = nr_scrambles

        self.x_std, self.x_error = self.calculate_std_error(
            x, self.n_scrambles)
        self.y_std, self.y_error = self.calculate_std_error(
            y, self.n_scrambles)

        self.measure = measure
        self.random_number_generator_type = random_number_generator_type

        self.meta_data = {
            'time grid': self.time_grid,
            "kappa": kappa,
            "lambda": float(local_volatility.lambda_t(0)),
            'beta': float(local_volatility.b_t(0)),
            "alpha": float(local_volatility.alpha_t(0)),
            "random_number_generator_type": random_number_generator_type
        }

        self.res = pd.DataFrame({
            'time grid': self.time_grid,
            "x bar mc": self.x_bar,
            "y bar mc": self.y_bar,
            "x std mc": self.x_std,
            "y std mc": self.y_std
        })
示例#12
0
def test_adi_swaption2():

    swaption_expiry = 5
    swaption_maturity = 10
    freq = 0.5

    rate = 0.06

    initial_curve = get_mock_yield_curve_const(rate=rate)
    kappa = 0.3

    swap_pricer = SwapPricer(initial_curve, kappa)
    swap = Swap(swaption_expiry, swaption_maturity, freq)
    swaption_pricer = SwaptionPricer(swap_pricer)

    coupon = swap_pricer.price(swap, 0, 0, 0)
    swaption = Swaption(swaption_expiry, coupon, swap)

    local_volatility = LinearLocalVolatility.from_const(30, 0.5, 0.1, 0.2)
    #local_volatility = LinearLocalVolatility.from_const(30, 0.1, 0.1, 0.1)

    t_min = 0
    t_max = swaption_expiry
    t_grid_size = 100
    x_grid_size = 401

    y_grid_size = 20

    x_min, x_max = calculate_x_boundaries2(t_max, local_volatility, alpha=3)
    y_min, y_max = calculate_u_boundaries(t_max,
                                          kappa,
                                          local_volatility,
                                          alpha=3)

    mesher = Mesher2d()
    mesher.create_mesher_2d(t_min, t_max, t_grid_size, x_min, x_max,
                            x_grid_size, y_min, y_max, y_grid_size)

    theta = 0.5
    adi_runner = AdiRunner(theta, kappa, initial_curve, local_volatility,
                           mesher)

    swaption_value0 = adi_runner.run_adi(swaption, swaption_pricer)

    x0 = extract_x0_result(swaption_value0, mesher.xgrid, mesher.ugrid)

    implied_vola = find_implied_black_vola(x0, swaption, swap_pricer,
                                           swap_pricer.bond_pricer)

    print("Swaption value at 0: ", x0, implied_vola)
示例#13
0
def test_piterbarg_y_bar():

    kappa = 0.001
    t = 15

    initial_curve = LiborCurve.from_constant_rate(0.06)
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    sigma_r = LinearLocalVolatility.from_const(t, 0.1, 0.1, 0)
    piterbarg_approx = PiterbargExpectationApproximator(sigma_r, swap_pricer)

    y_bar_actual = piterbarg_approx.calculate_ybar(t)
    y_bar_expected = np.exp(-2*kappa*t)*(np.exp(2*kappa*t) - 1)/(2*kappa)*0.0001

    np.testing.assert_approx_equal(y_bar_actual, y_bar_expected)
示例#14
0
def test_linear_local_volatility_approximation():

    kappa = 0.001
    t = 15

    initial_curve = LiborCurve.from_constant_rate(0.06)
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    sigma_r = LinearLocalVolatility.from_const(t, 0.1, 0.1, 0)

    piterbarg_approx = PiterbargExpectationApproximator(sigma_r, swap_pricer)
    swap = Swap(4, 5, 0.5)

    displaced_diffusion = DisplacedDiffusionParameterApproximator(sigma_r, swap_pricer, swap, piterbarg_approx)

    pass
示例#15
0
def test_piterbarg_ksi():

    kappa = 0.001
    t = 15

    initial_curve = LiborCurve.from_constant_rate(0.06)
    swap_pricer = SwapPricer(initial_curve, kappa=kappa)

    sigma_r = LinearLocalVolatility.from_const(t, 0.5, 0.5, 0.2)

    piterbarg_approx = PiterbargExpectationApproximator(sigma_r, swap_pricer)

    swap = Swap(4, 5, 0.5)
    swap_value = swap_pricer.price(swap, 0.01717964, 0.0025, 0.04)
    ksi = piterbarg_approx.calculate_ksi(0.04, swap_value, swap)

    np.testing.assert_approx_equal(ksi, 0.01717964, significant=4)
示例#16
0
def test_adi_bond():

    maturity = 10

    linear_local_volatility = LinearLocalVolatility.from_const(
        30, 0.1, 0.1, 0.1)
    #linear_local_volatility = LinearLocalVolatility.from_const(30, 0.1, 0.1, 0)

    theta = 0.5
    kappa = 0.3
    initial_curve = get_mock_yield_curve_const(rate=0.06)

    t_min = 0
    t_max = maturity
    t_grid_size = 200
    x_grid_size = 201

    y_grid_size = 20

    x_min, x_max = calculate_x_boundaries2(t_max,
                                           linear_local_volatility,
                                           alpha=2.5)
    y_min, y_max = calculate_u_boundaries(t_max,
                                          kappa,
                                          linear_local_volatility,
                                          alpha=2.5)

    mesher = Mesher2d()
    mesher.create_mesher_2d(t_min, t_max, t_grid_size, x_min, x_max,
                            x_grid_size, y_min, y_max, y_grid_size)

    adi_runner = AdiRunner(theta, kappa, initial_curve,
                           linear_local_volatility, mesher)

    bond = Bond(maturity)
    bond_pricer = BondPricer(initial_curve, kappa)

    bond_t0 = adi_runner.run_adi(bond, bond_pricer)
    bond_xyt0 = extract_x0_result(bond_t0, adi_runner.mesher.xgrid,
                                  adi_runner.mesher.ugrid)

    actual = bond_pricer.price(bond, 0, 0, 0)

    np.testing.assert_approx_equal(bond_xyt0, actual)
示例#17
0
def test_mc_annuity_measure():

    kappa = 0.001
    rate = 0.06
    initial_curve = get_mock_yield_curve_const(rate=rate)

    linear_local = LinearLocalVolatility.from_const(30, 0.1, 0.1, 0.1)

    number_samples = 200
    number_steps = 50

    local_volatility = linear_local

    swap_T0 = 4
    swap_TN = 5
    frequency = 0.5

    t_horizon = swap_T0
    dt = t_horizon / number_steps

    bond_pricer = BondPricer(initial_curve, kappa)
    annuity_pricer = AnnuityPricer(bond_pricer)
    swap = Swap(swap_T0, swap_TN, frequency)
    annuity = Annuity(swap.bond_list, frequency)

    x_simulator = ProcessSimulator(number_samples,
                                   number_steps,
                                   dt,
                                   annuity_pricer=annuity_pricer)

    res = x_simulator.simulate_xy(kappa=kappa,
                                  local_volatility=local_volatility,
                                  annuity_measure=annuity)

    mc_price = annuity_pricer.annuity_price(
        0, 0, 0, annuity) * 1 / annuity_pricer.annuity_price(
            t_horizon, res.x[:, -1], res.y[:, -1], annuity)

    avg_bond = np.mean(mc_price)
    std_mc = np.std(mc_price) / np.sqrt(number_samples)
    actual_price = np.exp(-rate * t_horizon)

    assert actual_price > avg_bond - 3 * std_mc and actual_price < avg_bond + 3 * std_mc
示例#18
0
    def minimize_func(x):
        print("run minimize")
        lambda_param = x[0]
        beta_param = x[1]
        sigma_r = LinearLocalVolatility.from_const(int(swap.TN), lambda_param,
                                                   curve_rate, beta_param)

        xy_calculator = XYApproximator(grid_size, swap_pricer, sigma_r, swap)
        integration_approx = DiscreteParameterAveraging(
            grid_size, swap_pricer, sigma_r, swap, xy_calculator)
        lambda_avg, beta_avg = integration_approx.calculate_average_param()

        error = 0

        for row_id, inp_data in market_data.iterrows():
            expiry = inp_data["Expiry"]
            coupon = inp_data["moneyness"] + atm_swap_price
            swaption = Swaption(expiry, coupon, swap)
            market_implied_vola = inp_data["implied black vola"]
            swaption_value, black_implied_vola = lognormalimpliedvola(
                swaption, swap_pricer, lambda_avg, beta_avg)
            error += (black_implied_vola - market_implied_vola)**2

        return error
示例#19
0
def mc_swaption_report():

    output_path = os.path.join(output_data_raw_monte_carlo, date_timestamp)
    output_file = os.path.join(output_path, "swaption_price_mc.hdf")
    file_path = get_nonexistant_path(output_file)

    #random_number_generator_type = "sobol"
    random_number_generator_type = "normal"

    curve_rate = 0.06
    kappa_grid = [0.03]

    initial_curve = get_mock_yield_curve_const(rate=curve_rate)

    vola_parameters = [(i, curve_rate, j) for i in [0.05, 0.2, 0.4, 0.5] for j in [0.05, 0.1, 0.3, 0.7]]

    vola_parameters = [(i, curve_rate, j) for i in [0.4] for j in [0.3]]

    vola_grid_df = pd.DataFrame(vola_parameters, columns=["lambda", "alpha", "beta"])

    coupon_grid = [0, +0.0025, -0.0025, +0.005, -0.005, +0.01, -0.01, 0.015, -0.015, 0.02, -0.02, 0.025, -0.025]
    #vola_grid_df = vola_grid_df.iloc[[10]]

    number_paths = np.power(2, 15)
    number_time_steps = np.power(2, 11)
    swap_ls = [(1, 6), (5, 10), (10, 20), (20, 30), (25, 30)]
    swap_ls = [(5, 10),  (10, 20), (20, 30)]

    swap_ls = [(5, 10)]
    #swap_ls = [(1, 11)]

    for number_paths in [np.power(2,12), np.power(2, 13), np.power(2, 14), np.power(2, 15), np.power(2, 16), np.power(2, 17)]:
        for swap_exp_mat in swap_ls:
            print("swap: ", swap_exp_mat)
            expiry, maturity = swap_exp_mat
            for kappa in kappa_grid:
                swap_pricer = SwapPricer(initial_curve, kappa)
                swaption_pricer = SwaptionPricer(swap_pricer)
                swap = Swap(expiry, maturity, 0.5)
                atm_swap_price = swap_pricer.price(swap, 0, 0, 0)
                strike_grid = [atm_swap_price+coupon for coupon in coupon_grid]
                for index, vola_grid_row in vola_grid_df.iterrows():
                    loca_vola = LinearLocalVolatility.from_const(maturity, vola_grid_row["lambda"],
                                                                 vola_grid_row["alpha"], vola_grid_row["beta"])
                    bond_measure = swap.bond_T0
                    process_simulator = ProcessSimulatorTerminalMeasure(number_paths, number_time_steps,
                                                                 expiry / number_time_steps,
                                                                 random_number_generator_type, bond_measure,
                                                                        swap_pricer.bond_pricer, nr_processes=6,
                                                                        n_scrambles=64)

                    result_obj = process_simulator.simulate_xy(kappa, loca_vola, parallel_simulation=True)

                    for strike in strike_grid:
                        swaption = Swaption(expiry, strike, swap)

                        swaption_value_paths = monte_carlo_pricer_terminal_measure(result_obj, swaption, swaption_pricer)
                        last_mc_time = result_obj.time_grid[-1]
                        # swaption_value_paths_cv = apply_control_variate(last_mc_time, result_obj.x[:,-1], result_obj.y[:,-1],
                        #                                 swaption_value_paths, swap.bond_TN, swap_pricer.bond_pricer, swap_pricer.initial_curve)
                        swaption_value_paths_cv2 = apply_control_variate_annuity(last_mc_time, result_obj.x[:, -1],
                                                                        result_obj.y[:, -1], swaption_value_paths,
                                                                        swap.annuity, swap_pricer.annuity_pricer,
                                                                         swap_pricer.annuity_pricer.bond_pricer.initial_curve)

                        swaption_value_mean = swaption_value_paths.mean()
                        std, swaption_value_error = result_obj.calculate_std_error(swaption_value_paths, result_obj.n_scrambles)

                        # swaption_value_mean_cv = swaption_value_paths_cv.mean()
                        # std, swaption_value_error_cv = result_obj.calculate_std_error(swaption_value_paths_cv, result_obj.n_scrambles)

                        swaption_value_mean_cv = swaption_value_paths_cv2.mean()
                        std, swaption_value_error_cv = result_obj.calculate_std_error(swaption_value_paths_cv2,
                                                                                      result_obj.n_scrambles)

                        bond_pricer = swap_pricer.bond_pricer
                        output_data = {"number_paths": number_paths, "number_time_steps": number_time_steps,
                                       "random_number_generator_type": random_number_generator_type, "expiry": expiry,
                                       "maturity": maturity, "strike": strike, "atm strike": atm_swap_price,
                                       "moneyness": strike-atm_swap_price, "vola_lambda": vola_grid_row["lambda"],
                                       "vola_alpha": vola_grid_row["alpha"], "vola_beta": vola_grid_row["beta"],
                                       "curve_rate": curve_rate, "kappa": kappa, "swaption value": swaption_value_mean,
                                       "swaption value error": swaption_value_error,
                                       "swaption value cv": swaption_value_mean_cv,
                                       "swaption value error cv": swaption_value_error_cv,

                                       "implied_vola": find_implied_black_vola(swaption_value_mean, swaption,
                                                                               swap_pricer, bond_pricer),
                                       "implied_vola_max": find_implied_black_vola(swaption_value_mean+swaption_value_error,
                                                                                   swaption, swap_pricer, bond_pricer),
                                       "implied_vola_min": find_implied_black_vola(swaption_value_mean-swaption_value_error,
                                                                                   swaption, swap_pricer, bond_pricer),
                                       "implied_vola_cv": find_implied_black_vola(swaption_value_mean_cv, swaption,
                                                                               swap_pricer, bond_pricer),
                                       "implied_vola_cv_max": find_implied_black_vola(swaption_value_mean_cv + swaption_value_error_cv, swaption,
                                                                               swap_pricer, bond_pricer),
                                       "implied_vola_cv_min": find_implied_black_vola(swaption_value_mean_cv - swaption_value_error_cv, swaption,
                                                                               swap_pricer, bond_pricer)}

                        output_df_new = pd.DataFrame(output_data, index=[0])

                        try:
                            ouput_df_old = pd.read_hdf(file_path, key="output_data")
                        except:
                            ouput_df_old = pd.DataFrame()

                        output_df_new = pd.concat([ouput_df_old, output_df_new])
                        output_df_new.to_hdf(file_path, key="output_data", complevel=9)
def calculate_swaption_prices():

    output_path = os.path.join(output_data_raw_approx, date_timestamp,
                               "result")
    output_file = os.path.join(output_path, "swaption_approximation.hdf")
    file_path = get_nonexistant_path(output_file)

    grid_size = 2**12 + 1
    swap_freq = 0.5
    curve_rate = 0.06

    initial_curve = LiborCurve.from_constant_rate(curve_rate)

    kappa_grid = [0.03]

    vola_parameters = [(i, curve_rate, j) for i in [0.6, 0.8]
                       for j in [0.05, 0.2]]
    vola_grid_df = pd.DataFrame(vola_parameters,
                                columns=["lambda", "alpha", "beta"])
    vola_grid_df = vola_grid_df.iloc[[0, 3]]

    #coupon_grid = [0, +0.0025, -0.0025, +0.005, -0.005, +0.01, -0.01, 0.015, -0.015, 0.02, -0.02, 0.025, -0.025]

    XYApproximator = PitergargDiscreteXY
    XYApproximator = RungeKuttaApproxXY

    swap_ls = [(20, 21)]
    coupon_grid = [0, +0.005, -0.005, +0.01, -0.01, 0.015, -0.015]
    #vola_grid_df = vola_grid_df.iloc[9:10]

    for swap_T0_TN in swap_ls:
        print(swap_T0_TN)
        T0, TN = swap_T0_TN
        for kappa in kappa_grid:
            swap_pricer = SwapPricer(initial_curve, kappa)
            swap = Swap(T0, TN, 1 / 2)
            for index, vola_grid_row in vola_grid_df.iterrows():
                sigma_r = LinearLocalVolatility.from_const(
                    swap.TN, vola_grid_row["lambda"], vola_grid_row["alpha"],
                    vola_grid_row["beta"])

                swap = Swap(T0, TN, swap_freq)

                atm_swap_price = swap_pricer.price(swap, 0, 0, 0)
                strike_grid = [
                    atm_swap_price + coupon for coupon in coupon_grid
                ]
                #strike_grid = [0.01, 0.015, 0.02, 0.025, 0.03]

                xy_calculator = XYApproximator(grid_size, swap_pricer, sigma_r,
                                               swap)
                integration_approx = DiscreteParameterAveraging(
                    grid_size, swap_pricer, sigma_r, swap, xy_calculator)
                lambda_avg, beta_avg = integration_approx.calculate_average_param(
                )

                for strike in strike_grid:
                    swaption = Swaption(T0, strike, swap)
                    swaption_value, black_implied_vola = lognormalimpliedvola(
                        swaption, swap_pricer, lambda_avg, beta_avg)

                    output_data = pd.DataFrame({
                        'expiry': [T0],
                        "maturity": [TN],
                        "atm strike":
                        atm_swap_price,
                        "swaption_value": [swaption_value],
                        "kappa": [kappa],
                        "vola_lambda": [vola_grid_row["lambda"]],
                        "vola_alpha": [vola_grid_row["alpha"]],
                        "vola_beta": [vola_grid_row['beta']],
                        "strike": [strike],
                        'moneyness': [strike - atm_swap_price],
                        "curve_rate": [curve_rate],
                        "implied_black_vola": [black_implied_vola],
                        'integration_grid': [grid_size],
                        "xy_approximation": [str(xy_calculator)]
                    })
                    try:
                        all_output_data = pd.read_hdf(file_path, key="data")
                    except:
                        all_output_data = pd.DataFrame()
                    all_output_data = pd.concat([all_output_data, output_data])
                    all_output_data.to_hdf(file_path, key="data", complevel=9)
示例#21
0
    return exp_u, var_u


def calculate_u_boundaries(maturity,
                           kappa,
                           volatility: LocalVolatility,
                           alpha=5):

    exp_u, var_u = calculate_u_moments(maturity, kappa, volatility)

    # y cannot be negative
    u_min = -alpha * np.sqrt(var_u)
    u_max = +alpha * np.sqrt(var_u)

    return u_min, u_max


if __name__ == "__main__":

    y = 0.0005
    kappa = 0.3
    maturity = 1
    eta_square = 0.01**2
    print(np.sqrt(eta_square * maturity) * 5)

    linear_local_vola = LinearLocalVolatility()
    print(calculate_x_boundaries(
        y,
        kappa,
        maturity,
    ))
示例#22
0
def adi_bond_report():

    output_path = os.path.join(output_data_raw_finite_difference,
                               date_timestamp)

    curve_rate = 0.01
    maturity_grid = [30]
    kappa_grid = [0.03]
    theta = 1 / 2

    initial_curve = get_mock_yield_curve_const(rate=curve_rate)

    vola_parameters = [(i, curve_rate, j) for i in [0.05, 0.1, 0.2, 0.4]
                       for j in [0.1, 0.3, 0.5, 0.7, 0.9]]
    vola_grid_df = pd.DataFrame(vola_parameters,
                                columns=["lambda", "alpha", "beta"])

    finite_difference_parameter = [(100, 150, 20), (300, 400, 80)]

    #finite_difference_parameter = [(100, 150, 20)]

    finite_difference_grid_df = pd.DataFrame(
        finite_difference_parameter,
        columns=["t_grid_size", "x_grid_size", "y_grid_size"])

    output_path = get_nonexistant_path(output_path)

    vola_grid_df = vola_grid_df.loc[(vola_grid_df["lambda"] == 0.4)
                                    & (vola_grid_df["beta"] == 0.35)]

    for maturity in maturity_grid:
        for kappa in kappa_grid:
            bond = Bond(maturity)
            bond_pricer = BondPricer(initial_curve, kappa)
            for index, vola_grid_row in vola_grid_df.iterrows():
                loca_vola = LinearLocalVolatility.from_const(
                    maturity, vola_grid_row["lambda"], vola_grid_row["alpha"],
                    vola_grid_row["beta"])
                for index, finite_difference_grid_row in finite_difference_grid_df.iterrows(
                ):

                    x_grid_size = finite_difference_grid_row["x_grid_size"]
                    y_grid_size = finite_difference_grid_row["y_grid_size"]
                    t_grid_size = finite_difference_grid_row["t_grid_size"]

                    t_min = 0
                    t_max = maturity

                    x_min, x_max = calculate_x_boundaries2(t_max,
                                                           loca_vola,
                                                           alpha=3)
                    x_min, x_max = calculate_x_boundaries3(t_max,
                                                           kappa,
                                                           loca_vola,
                                                           alpha=3)
                    u_min, u_max = calculate_u_boundaries(t_max,
                                                          kappa,
                                                          loca_vola,
                                                          alpha=4)

                    mesher = Mesher2d()
                    mesher.create_mesher_2d(t_min, t_max, t_grid_size, x_min,
                                            x_max, x_grid_size, u_min, u_max,
                                            y_grid_size)

                    adi_runner = AdiRunner(theta, kappa, initial_curve,
                                           loca_vola, mesher)

                    bond_t0 = pd.DataFrame(
                        adi_runner.run_adi(bond, bond_pricer))

                    output_file = os.path.join(output_path,
                                               "bond_price_fd.hdf")
                    file_path = get_nonexistant_path(output_file)

                    meta_data = {
                        "x_grid_size": int(x_grid_size),
                        "y_grid_size": int(y_grid_size),
                        "maturity": maturity,
                        "t_grid_size": int(t_grid_size),
                        "vola_lambda": vola_grid_row["lambda"],
                        "vola_alpha": vola_grid_row["alpha"],
                        "vola_beta": vola_grid_row["beta"],
                        "curve_rate": curve_rate,
                        "kappa": kappa
                    }

                    meta_data = pd.DataFrame(meta_data, index=[0])
                    bond_t0.to_hdf(file_path, key="data", complevel=5)
                    meta_data.to_hdf(file_path, key="metadata", complevel=5)

                    pd.DataFrame(mesher.xmesh).to_hdf(file_path,
                                                      key='xmesh',
                                                      complevel=5)
                    pd.DataFrame(mesher.umesh).to_hdf(file_path,
                                                      key='ymesh',
                                                      complevel=5)

                    pd.DataFrame(mesher.xgrid).to_hdf(file_path,
                                                      key='xgrid',
                                                      complevel=5)
                    pd.DataFrame(mesher.ugrid).to_hdf(file_path,
                                                      key='ygrid',
                                                      complevel=5)
示例#23
0
def adi_swaption_report():

    output_path = os.path.join(output_data_raw_finite_difference, date_timestamp)

    curve_rate = 0.06
    kappa_grid = [0.03]
    theta = 1/2

    initial_curve = get_mock_yield_curve_const(rate=curve_rate)

    finite_difference_parameter = [(100, 150, 10), (400, 800, 60)]

    finite_difference_parameter = [(150, 200, 80)]
    #finite_difference_parameter = [(400, 800, 60)]

    #finite_difference_parameter = [(800, 1000, 100)]
    finite_difference_parameter = [(50, 100, 10), (100, 150, 20), (150, 200, 40), (200, 300, 60), (300, 400, 80)]
    finite_difference_parameter = [(400, 600, 100)]
    #finite_difference_parameter = [(600, 800, 120)]
    #finite_difference_parameter = [(100, 150, 20), (150, 200, 40), (300, 400, 80), (400, 600, 100)]

    #finite_difference_parameter = [ (400, 600, 100)]

    finite_difference_parameter = [(100, 150, 20), (150, 200, 40), (300, 400, 80), (400, 600, 100)]
    #finite_difference_parameter = [ (400, 600, 100)]
    finite_difference_parameter = [(300, 400, 80)]
    #finite_difference_parameter = [(150, 200, 40)]

    finite_difference_grid_df = pd.DataFrame(finite_difference_parameter, columns=["t_grid_size", "x_grid_size", "y_grid_size"])
    output_path = get_nonexistant_path(output_path)
    vola_parameters = [(i, curve_rate, j) for i in [0.6, 0.8] for j in [0.05, 0.2]]
    vola_grid_df = pd.DataFrame(vola_parameters, columns=["lambda", "alpha", "beta"])

    #coupon_grid = [0, +0.0025, -0.0025, +0.005, -0.005, +0.01, -0.01, 0.015, -0.015, 0.02, -0.02, 0.025, -0.025]

    #swap_ls = [(1, 6), (5, 10), (10, 20), (20, 30), (25, 30)]

    #swap_ls = [(1,6), (5, 10), (10,20)]

    swap_ls = [(20, 21)]
    coupon_grid = [0, +0.005, -0.005, +0.01, -0.01, 0.015, -0.015]
    #coupon_grid = [0]

    #coupon_grid = [0]
    #swap_ls = [(5, 10)]
    #finite_difference_grid_df = finite_difference_grid_df[:-1]

    vola_grid_df = vola_grid_df.iloc[[0, 3]]

    for swap_exp_mat in swap_ls:
        expiry, maturity = swap_exp_mat
        for kappa in kappa_grid:
            swap_pricer = SwapPricer(initial_curve, kappa)
            swaption_pricer = SwaptionPricer(swap_pricer)
            swap = Swap(expiry, maturity, 0.5)
            atm_swap_price = swap_pricer.price(swap, 0, 0, 0)
            strike_grid = [atm_swap_price+coupon for coupon in coupon_grid]
            #strike_grid = [0.01, 0.015, 0.02, 0.025, 0.03]

            for strike in strike_grid:
                swaption = Swaption(expiry, strike, swap)
                for index, vola_grid_row in vola_grid_df.iterrows():
                    loca_vola = LinearLocalVolatility.from_const(maturity, vola_grid_row["lambda"], vola_grid_row["alpha"], vola_grid_row["beta"])
                    for index, finite_difference_grid_row in finite_difference_grid_df.iterrows():

                        x_grid_size = finite_difference_grid_row["x_grid_size"]
                        y_grid_size = finite_difference_grid_row["y_grid_size"]
                        t_grid_size = finite_difference_grid_row["t_grid_size"]

                        t_min = 0
                        t_max = expiry

                        x_min, x_max = calculate_x_boundaries2(t_max, loca_vola, alpha=3)
                        x_min, x_max = calculate_x_boundaries3(expiry, kappa, loca_vola, alpha=4)
                        y_min, y_max = calculate_u_boundaries(t_max, kappa, loca_vola, alpha=4)

                        mesher = Mesher2d()
                        mesher.create_mesher_2d(t_min, t_max, t_grid_size, x_min, x_max, x_grid_size, y_min, y_max,
                                                y_grid_size)

                        adi_runner = AdiRunner(theta, kappa, initial_curve, loca_vola, mesher)

                        swaption_t0 = pd.DataFrame(adi_runner.run_adi(swaption, swaption_pricer))

                        output_file = os.path.join(output_path, "swaption_price_fd.hdf")
                        file_path = get_nonexistant_path(output_file)

                        swaption_t0_x0_y0 = extract_x0_result(swaption_t0.values, mesher.xgrid, mesher.ugrid)
                        implied_black_vola = find_implied_black_vola(swaption_t0_x0_y0, swaption, swap_pricer, swap_pricer.bond_pricer)

                        meta_data = {"expiry": expiry, "maturity": maturity, "strike": strike,
                                     "atm strike": atm_swap_price, "moneyness": strike - atm_swap_price,
                                     "x_grid_size": int(x_grid_size), "y_grid_size": int(y_grid_size),
                                      "t_grid_size": int(t_grid_size),
                                     "vola_lambda": vola_grid_row["lambda"], "vola_alpha": vola_grid_row["alpha"],
                                     "vola_beta": vola_grid_row["beta"], "curve_rate": curve_rate, "kappa": kappa,
                                     "swaption_value": swaption_t0_x0_y0, "implied_black_vola": implied_black_vola}

                        meta_data = pd.DataFrame(meta_data, index=[0])
                        swaption_t0.to_hdf(file_path, key="data", complevel=5)
                        meta_data.to_hdf(file_path, key="metadata", complevel=5)

                        print(meta_data)

                        pd.DataFrame(mesher.xmesh).to_hdf(file_path, key='xmesh', complevel=5)
                        pd.DataFrame(mesher.umesh).to_hdf(file_path, key='ymesh', complevel=5)

                        pd.DataFrame(mesher.xgrid).to_hdf(file_path, key='xgrid', complevel=5)
                        pd.DataFrame(mesher.ugrid).to_hdf(file_path, key='ygrid', complevel=5)