def test_FinIborCapletHull():

    #  Hull Page 703, example 29.3
    todayDate = Date(20, 6, 2019)
    valuation_date = todayDate
    maturity_date = valuation_date.addTenor("2Y")
    libor_curve = DiscountCurveFlat(valuation_date,
                                    0.070,
                                    FrequencyTypes.QUARTERLY,
                                    DayCountTypes.THIRTY_E_360)

    k = 0.08
    capFloorType = FinCapFloorTypes.CAP
    capFloor = FinIborCapFloor(valuation_date,
                                maturity_date,
                                capFloorType,
                                k,
                                None,
                                FrequencyTypes.QUARTERLY,
                                DayCountTypes.THIRTY_E_360)

    # Value cap using a single flat cap volatility
    model = FinModelBlack(0.20)
    capFloor.value(valuation_date, libor_curve, model)

    # Value cap by breaking it down into caplets using caplet vols
    capletStartDate = valuation_date.addTenor("1Y")
    capletEndDate = capletStartDate.addTenor("3M")

    vCaplet = capFloor.valueCapletFloorLet(valuation_date,
                                           capletStartDate,
                                           capletEndDate,
                                           libor_curve,
                                           model)

    # Cannot match Hull due to dates being adjusted
    testCases.header("CORRECT PRICE", "MODEL_PRICE")
    testCases.print(517.29, vCaplet)
Esempio n. 2
0
def test_FinDayCount():

    testCases.header("DAY_COUNT_METHOD", "START", "END", "ALPHA")

    finFreq = FrequencyTypes.ANNUAL

    for day_count_method in DayCountTypes:

        start_date = Date(1, 1, 2019)
        next_date = start_date
        numDays = 20
        day_count = DayCount(day_count_method)

        for _ in range(0, numDays):
            next_date = next_date.add_days(7)
            dcf = day_count.year_frac(
                start_date, next_date, next_date, finFreq)

            testCases.print(
                str(day_count_method),
                str(start_date),
                str(next_date),
                dcf[0])
Esempio n. 3
0
def test_FinFXMktVolSurface1(capsys):
    # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
    # print("EURUSD EXAMPLE CLARK")

    valuation_date = Date(10, 4, 2020)

    forName = "EUR"
    domName = "USD"
    forCCRate = 0.03460  # EUR
    domCCRate = 0.02940  # USD

    dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

    currency_pair = forName + domName
    spot_fx_rate = 1.3465

    tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
    atm_vols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
    marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
    riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]

    notional_currency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA
    vol_functionType = VolFunctionTypes.CLARK

    fxMarket = FXVolSurface(valuation_date, spot_fx_rate, currency_pair,
                            notional_currency, dom_discount_curve,
                            for_discount_curve, tenors, atm_vols,
                            marketStrangle25DeltaVols, riskReversal25DeltaVols,
                            atmMethod, deltaMethod, vol_functionType)

    fxMarket.check_calibration(verboseCalibration, tol=1e-5)
    captured = capsys.readouterr()
    assert captured.out == ""
Esempio n. 4
0
def test_FinFXMktVolSurface3(capsys):
    # EURUSD Example from Paper by Uwe Wystup using Tables 4
    #        print("EURUSD EXAMPLE WYSTUP")

    valuation_date = Date(20, 1, 2009)

    forName = "EUR"
    domName = "USD"
    forCCRate = 0.020113  # EUR
    domCCRate = 0.003525  # USD

    dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

    currency_pair = forName + domName
    spot_fx_rate = 1.3088

    tenors = ['1M']
    atm_vols = [21.6215]
    marketStrangle25DeltaVols = [0.7375]
    riskReversal25DeltaVols = [-0.50]

    notional_currency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA

    fxMarket = FXVolSurface(valuation_date, spot_fx_rate, currency_pair,
                            notional_currency, dom_discount_curve,
                            for_discount_curve, tenors, atm_vols,
                            marketStrangle25DeltaVols, riskReversal25DeltaVols,
                            atmMethod, deltaMethod)

    fxMarket.check_calibration(verboseCalibration)
    captured = capsys.readouterr()
    assert captured.out == ""
Esempio n. 5
0
def test_FinFXMktVolSurface2(capsys):
    # Example from Book extract by Iain Clark using Tables 3.3 and 3.4
    # print("EURJPY EXAMPLE CLARK")

    valuation_date = Date(10, 4, 2020)

    forName = "EUR"
    domName = "JPY"
    forCCRate = 0.0294  # EUR
    domCCRate = 0.0171  # USD

    dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

    currency_pair = forName + domName
    spot_fx_rate = 90.72

    tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
    atm_vols = [21.50, 20.50, 19.85, 18.00, 15.95, 14.009]
    marketStrangle25DeltaVols = [0.35, 0.325, 0.300, 0.225, 0.175, 0.100]
    riskReversal25DeltaVols = [-8.350, -8.650, -8.950, -9.250, -9.550, -9.500]

    notional_currency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ

    fxMarket = FXVolSurface(valuation_date, spot_fx_rate, currency_pair,
                            notional_currency, dom_discount_curve,
                            for_discount_curve, tenors, atm_vols,
                            marketStrangle25DeltaVols, riskReversal25DeltaVols,
                            atmMethod, deltaMethod)

    fxMarket.check_calibration(verboseCalibration, tol=0.0005)
    captured = capsys.readouterr()
    assert captured.out == ""
Esempio n. 6
0
def test_FinFXMktVolSurface1(verboseCalibration):

    ###########################################################################

    if 1 == 1:

        # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
        # print("EURUSD EXAMPLE CLARK")

        valuation_date = Date(10, 4, 2020)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.03460  # EUR
        domCCRate = 0.02940  # USD

        dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
        for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

        currency_pair = forName + domName
        spot_fx_rate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atm_vols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
        marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
        riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]

        notional_currency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA
        vol_functionType = VolFunctionTypes.CLARK

        fxMarket = FXVolSurface(valuation_date, spot_fx_rate, currency_pair,
                                notional_currency, dom_discount_curve,
                                for_discount_curve, tenors, atm_vols,
                                marketStrangle25DeltaVols,
                                riskReversal25DeltaVols, atmMethod,
                                deltaMethod, vol_functionType)

        fxMarket.check_calibration(verboseCalibration)

        # EXPLORE AND TEST DIFFERENT CATEGORICAL PARAMETERS
        # for atmMethod in FinFXATMMethod:
        #     for deltaMethod in FinFXDeltaMethod:
        #         for vol_functionType in VolFunctionTypes:

        #             fxMarket = FinFXVolSurface(valuation_date,
        #                                        spot_fx_rate,
        #                                        currency_pair,
        #                                        notional_currency,
        #                                        dom_discount_curve,
        #                                        for_discount_curve,
        #                                        tenors,
        #                                        atm_vols,
        #                                        marketStrangle25DeltaVols,
        #                                        riskReversal25DeltaVols,
        #                                        atmMethod,
        #                                        deltaMethod,
        #                                        vol_functionType)

        #             fxMarket.check_calibration(verboseCalibration)

        if PLOT_GRAPHS:

            fxMarket.plot_vol_curves()

            dbns = fxMarket.implied_dbns(0.00001, 5.0, 10000)

            for i in range(0, len(dbns)):
                plt.plot(dbns[i]._x, dbns[i]._densitydx)
                plt.title(vol_functionType)
                print("SUM:", dbns[i].sum())
Esempio n. 7
0
def test_BondOptionZEROVOLConvergence():

    # Build discount curve
    settlement_date = Date(1, 9, 2019)
    rate = 0.05
    discount_curve = DiscountCurveFlat(
        settlement_date, rate, FrequencyTypes.ANNUAL)

    # Bond details
    issue_date = Date(1, 9, 2014)
    maturity_date = Date(1, 9, 2025)
    coupon = 0.06
    freq_type = FrequencyTypes.ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    # Option Details
    expiry_date = Date(1, 12, 2021)
    face = 100.0

    dfExpiry = discount_curve.df(expiry_date)
    fwdCleanValue = bond.clean_price_from_discount_curve(
        expiry_date, discount_curve)
    fwdFullValue = bond.full_price_from_discount_curve(
        expiry_date, discount_curve)
#    print("BOND FwdCleanBondPx", fwdCleanValue)
#    print("BOND FwdFullBondPx", fwdFullValue)
#    print("BOND Accrued:", bond._accrued_interest)

    spotCleanValue = bond.clean_price_from_discount_curve(
        settlement_date, discount_curve)

    testCases.header("STRIKE", "STEPS",
                     "CALL_INT", "CALL_INT_PV", "CALL_EUR", "CALL_AMER",
                     "PUT_INT", "PUT_INT_PV", "PUT_EUR", "PUT_AMER")

    num_time_steps = range(100, 1000, 100)
    strike_prices = [90, 100, 110, 120]

    for strike_price in strike_prices:

        callIntrinsic = max(spotCleanValue - strike_price, 0)
        putIntrinsic = max(strike_price - spotCleanValue, 0)
        callIntrinsicPV = max(fwdCleanValue - strike_price, 0) * dfExpiry
        putIntrinsicPV = max(strike_price - fwdCleanValue, 0) * dfExpiry

        for num_steps in num_time_steps:

            sigma = 0.0000001
            a = 0.1
            model = BKTree(sigma, a, num_steps)

            option_type = OptionTypes.EUROPEAN_CALL
            bond_option1 = BondOption(
                bond, expiry_date, strike_price, face, option_type)
            v1 = bond_option1.value(settlement_date, discount_curve, model)

            option_type = OptionTypes.AMERICAN_CALL
            bond_option2 = BondOption(
                bond, expiry_date, strike_price, face, option_type)
            v2 = bond_option2.value(settlement_date, discount_curve, model)

            option_type = OptionTypes.EUROPEAN_PUT
            bond_option3 = BondOption(
                bond, expiry_date, strike_price, face, option_type)
            v3 = bond_option3.value(settlement_date, discount_curve, model)

            option_type = OptionTypes.AMERICAN_PUT
            bond_option4 = BondOption(
                bond, expiry_date, strike_price, face, option_type)
            v4 = bond_option4.value(settlement_date, discount_curve, model)

            testCases.print(strike_price, num_steps,
                            callIntrinsic, callIntrinsicPV, v1, v2,
                            putIntrinsic, putIntrinsicPV, v3, v4)
Esempio n. 8
0
def test_BondOptionAmericanConvergenceTWO():

    # Build discount curve
    settlement_date = Date(1, 12, 2019)
    discount_curve = DiscountCurveFlat(settlement_date,
                                       0.05,
                                       FrequencyTypes.CONTINUOUS)

    # Bond details
    issue_date = Date(1, 9, 2014)
    maturity_date = Date(1, 9, 2025)
    coupon = 0.05
    freq_type = FrequencyTypes.ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)
    expiry_date = settlement_date.add_tenor("18m")
    face = 100.0

    spotValue = bond.full_price_from_discount_curve(
        settlement_date, discount_curve)
    testCases.header("LABEL", "VALUE")
    testCases.print("BOND PRICE", spotValue)

    testCases.header("TIME", "N", "EUR_CALL", "AMER_CALL",
                     "EUR_PUT", "AMER_PUT")

    sigma = 0.2
    a = 0.1
    bkModel = BKTree(sigma, a)
    K = 101.0

    vec_ec = []
    vec_ac = []
    vec_ep = []
    vec_ap = []

    if 1 == 1:
        K = 100.0
        bkModel = BKTree(sigma, a, 100)
        europeanCallBondOption = BondOption(bond, expiry_date, K, face,
                                            OptionTypes.EUROPEAN_CALL)

        v_ec = europeanCallBondOption.value(settlement_date, discount_curve,
                                            bkModel)
        testCases.header("LABEL", "VALUE")
        testCases.print("OPTION", v_ec)

    num_stepsVector = range(100, 100, 1)  # should be 100-400

    for num_steps in num_stepsVector:

        bkModel = BKTree(sigma, a, num_steps)

        start = time.time()

        europeanCallBondOption = BondOption(bond, expiry_date, K, face,
                                            OptionTypes.EUROPEAN_CALL)
        v_ec = europeanCallBondOption.value(settlement_date, discount_curve,
                                            bkModel)

        americanCallBondOption = BondOption(bond, expiry_date, K, face,
                                            OptionTypes.AMERICAN_CALL)
        v_ac = americanCallBondOption.value(settlement_date, discount_curve,
                                            bkModel)

        europeanPutBondOption = BondOption(bond, expiry_date, K, face,
                                           OptionTypes.EUROPEAN_PUT)
        v_ep = europeanPutBondOption.value(settlement_date, discount_curve,
                                           bkModel)

        americanPutBondOption = BondOption(bond, expiry_date, K, face,
                                           OptionTypes.AMERICAN_PUT)
        v_ap = americanPutBondOption.value(settlement_date, discount_curve,
                                           bkModel)

        end = time.time()
        period = end - start

        testCases.print(period, num_steps, v_ec, v_ac, v_ep, v_ap)

        vec_ec.append(v_ec)
        vec_ac.append(v_ac)
        vec_ep.append(v_ep)
        vec_ap.append(v_ap)

    if plotGraphs:

        plt.figure()
        plt.plot(num_stepsVector, vec_ec, label="European Call")
        plt.legend()

        plt.figure()
        plt.plot(num_stepsVector, vec_ac, label="American Call")
        plt.legend()

        plt.figure()
        plt.plot(num_stepsVector, vec_ep, label="European Put")
        plt.legend()

        plt.figure()
        plt.plot(num_stepsVector, vec_ap, label="American Put")
        plt.legend()
Esempio n. 9
0
def test_BKExampleTwo():
    # Valuation of a European option on a coupon bearing bond
    # This follows example in Fig 28.11 of John Hull's book but does not
    # have the exact same dt so there are some differences

    settlement_date = Date(1, 12, 2019)
    issue_date = Date(1, 12, 2018)
    expiry_date = settlement_date.add_tenor("18m")
    maturity_date = settlement_date.add_tenor("10Y")
    coupon = 0.05
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    coupon_times = []
    coupon_flows = []
    cpn = bond._coupon / bond._frequency
    num_flows = len(bond._flow_dates)

    for i in range(1, num_flows):
        pcd = bond._flow_dates[i - 1]
        ncd = bond._flow_dates[i]
        if pcd < settlement_date and ncd > settlement_date:
            flow_time = (pcd - settlement_date) / gDaysInYear
            coupon_times.append(flow_time)
            coupon_flows.append(cpn)

    for flow_date in bond._flow_dates:
        if flow_date > settlement_date:
            flow_time = (flow_date - settlement_date) / gDaysInYear
            coupon_times.append(flow_time)
            coupon_flows.append(cpn)

    coupon_times = np.array(coupon_times)
    coupon_flows = np.array(coupon_flows)

    strike_price = 105.0
    face = 100.0

    tmat = (maturity_date - settlement_date) / gDaysInYear
    texp = (expiry_date - settlement_date) / gDaysInYear
    times = np.linspace(0, tmat, 11)
    dates = settlement_date.add_years(times)
    dfs = np.exp(-0.05 * times)
    curve = DiscountCurve(settlement_date, dates, dfs)

    price = bond.clean_price_from_discount_curve(settlement_date, curve)
    testCases.header("LABEL", "VALUE")
    testCases.print("Fixed Income Price:", price)

    sigma = 0.20
    a = 0.05
    num_time_steps = 26

    model = BKTree(sigma, a, num_time_steps)
    model.build_tree(tmat, times, dfs)
    exercise_type = FinExerciseTypes.AMERICAN
    v = model.bond_option(texp, strike_price, face, coupon_times, coupon_flows,
                          exercise_type)

    # Test convergence
    num_steps_list = [100, 200, 300, 500, 1000]
    exercise_type = FinExerciseTypes.AMERICAN

    testCases.header("TIMESTEPS", "TIME", "VALUE")
    treeVector = []
    for num_time_steps in num_steps_list:
        start = time.time()
        model = BKTree(sigma, a, num_time_steps)
        model.build_tree(tmat, times, dfs)
        v = model.bond_option(texp, strike_price, face, coupon_times,
                              coupon_flows, exercise_type)
        end = time.time()
        period = end - start
        treeVector.append(v)
        testCases.print(num_time_steps, period, v)

#    plt.plot(num_steps_list, treeVector)

# Value in Hill converges to 0.699 with 100 time steps while I get 0.700

    if 1 == 0:
        print("RT")
        print_tree(model._rt, 5)
        print("Q")
        print_tree(model._Q, 5)
Esempio n. 10
0
def test_FinFXVanillaOptionHullExample():

    #   Example from Hull 4th edition page 284
    valuation_date = Date(1, 1, 2015)
    expiry_date = valuation_date.add_months(4)
    spot_fx_rate = 1.60
    volatility = 0.1411
    dom_interest_rate = 0.08
    forInterestRate = 0.11
    model = BlackScholes(volatility)
    dom_discount_curve = DiscountCurveFlat(valuation_date, dom_interest_rate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forInterestRate)

    num_paths_list = [10000, 20000, 40000, 80000, 160000, 320000]

    testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC")
    strike_fx_rate = 1.60

    for num_paths in num_paths_list:

        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")

        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)

        start = time.time()

        value_mc = call_option.value_mc(valuation_date, spot_fx_rate,
                                        dom_discount_curve, for_discount_curve,
                                        model, num_paths)

        end = time.time()
        duration = end - start
        testCases.print(num_paths, value, value_mc)

##########################################################################

    spot_fx_rates = np.arange(100, 200, 10)
    spot_fx_rates = spot_fx_rates / 100.0
    num_paths = 100000

    testCases.header("NUMPATHS", "CALL_VALUE_BS", "CALL_VALUE_MC")

    for spot_fx_rate in spot_fx_rates:

        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")

        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        start = time.time()
        value_mc = call_option.value_mc(valuation_date, spot_fx_rate,
                                        dom_discount_curve, for_discount_curve,
                                        model, num_paths)
        end = time.time()
        duration = end - start
        testCases.print(num_paths, value, value_mc)

##########################################################################

    spot_fx_rates = np.arange(100, 200, 10) / 100.0
    num_paths = 100000

    testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "PUT_VALUE_MC")

    for spot_fx_rate in spot_fx_rates:

        put_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                     OptionTypes.EUROPEAN_PUT, 1000000, "USD")

        value = put_option.value(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        start = time.time()
        value_mc = put_option.value_mc(valuation_date, spot_fx_rate,
                                       dom_discount_curve, for_discount_curve,
                                       model, num_paths)
        end = time.time()
        duration = end - start
        testCases.print(spot_fx_rate, value, value_mc)

##########################################################################

    spot_fx_rates = np.arange(100, 200, 10) / 100.0

    testCases.header("SPOT FX RATE", "CALL_VALUE_BS", "DELTA_BS", "VEGA_BS",
                     "THETA_BS", "RHO_BS")

    for spot_fx_rate in spot_fx_rates:
        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")
        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        delta = call_option.delta(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        vega = call_option.vega(valuation_date, spot_fx_rate,
                                dom_discount_curve, for_discount_curve, model)
        theta = call_option.theta(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        #  call_option.rho(valuation_date,stock_price, interest_rate,
        #  dividend_yield, modelType, model_params)
        rho = 999
        testCases.print(spot_fx_rate, value, delta, vega, theta, rho)

    testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "DELTA_BS", "VEGA_BS",
                     "THETA_BS", "RHO_BS")

    for spot_fx_rate in spot_fx_rates:
        put_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                     OptionTypes.EUROPEAN_PUT, 1000000, "USD")

        value = put_option.value(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        delta = put_option.delta(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        vega = put_option.vega(valuation_date, spot_fx_rate,
                               dom_discount_curve, for_discount_curve, model)
        theta = put_option.theta(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        # put_option.rho(valuation_date,stock_price, interest_rate, dividend_yield,
        # modelType, model_params)
        rho = 999
        testCases.print(spot_fx_rate, value, delta, vega, theta, rho)

##########################################################################

    testCases.header("SPOT FX RATE", "VALUE_BS", "VOL_IN", "IMPLD_VOL")

    spot_fx_rates = np.arange(100, 200, 10) / 100.0

    for spot_fx_rate in spot_fx_rates:
        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")

        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)['v']

        impliedVol = call_option.implied_volatility(valuation_date,
                                                    spot_fx_rate,
                                                    dom_discount_curve,
                                                    for_discount_curve, value)

        testCases.print(spot_fx_rate, value, volatility, impliedVol)
Esempio n. 11
0
def testFinIborCashSettledSwaption():

    testCases.header("LABEL", "VALUE")

    valuation_date = Date(1, 1, 2020)
    settlement_date = Date(1, 1, 2020)

    depoDCCType = DayCountTypes.THIRTY_E_360_ISDA
    depos = []
    depo = IborDeposit(settlement_date, "1W", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "1M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "3M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "6M", 0.0023, depoDCCType)
    depos.append(depo)

    # No convexity correction provided so I omit interest rate futures

    settlement_date = Date(2, 1, 2020)

    swaps = []
    accType = DayCountTypes.ACT_365F
    fixedFreqType = FrequencyTypes.SEMI_ANNUAL
    fixed_leg_type = SwapTypes.PAY

    swap = IborSwap(settlement_date, "3Y", fixed_leg_type, 0.00790,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "4Y", fixed_leg_type, 0.01200,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "5Y", fixed_leg_type, 0.01570,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "6Y", fixed_leg_type, 0.01865,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "7Y", fixed_leg_type, 0.02160,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "8Y", fixed_leg_type, 0.02350,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "9Y", fixed_leg_type, 0.02540,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "10Y", fixed_leg_type, 0.0273,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "15Y", fixed_leg_type, 0.0297,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "20Y", fixed_leg_type, 0.0316,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "25Y", fixed_leg_type, 0.0335,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "30Y", fixed_leg_type, 0.0354,
                    fixedFreqType, accType)
    swaps.append(swap)

    libor_curve = IborSingleCurve(valuation_date, depos, [], swaps,
                                  InterpTypes.LINEAR_ZERO_RATES)

    exercise_date = settlement_date.add_tenor("5Y")
    swapMaturityDate = exercise_date.add_tenor("5Y")
    swapFixedCoupon = 0.040852
    swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = DayCountTypes.THIRTY_E_360_ISDA
    swapFloatFrequencyType = FrequencyTypes.QUARTERLY
    swapFloatDayCountType = DayCountTypes.ACT_360
    swapNotional = 1000000
    fixed_leg_type = SwapTypes.PAY

    swaption = IborSwaption(settlement_date, exercise_date, swapMaturityDate,
                            fixed_leg_type, swapFixedCoupon,
                            swapFixedFrequencyType, swapFixedDayCountType,
                            swapNotional, swapFloatFrequencyType,
                            swapFloatDayCountType)

    model = Black(0.1533)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print("Swaption No-Arb Value:", v)

    fwdSwapRate1 = libor_curve.swap_rate(exercise_date, swapMaturityDate,
                                         swapFixedFrequencyType,
                                         swapFixedDayCountType)

    testCases.print("Curve Fwd Swap Rate:", fwdSwapRate1)

    fwdSwap = IborSwap(exercise_date, swapMaturityDate, fixed_leg_type,
                       swapFixedCoupon, swapFixedFrequencyType,
                       swapFixedDayCountType)

    fwdSwapRate2 = fwdSwap.swap_rate(settlement_date, libor_curve)
    testCases.print("Fwd Swap Swap Rate:", fwdSwapRate2)

    model = Black(0.1533)

    v = swaption.cash_settled_value(valuation_date, libor_curve, fwdSwapRate2,
                                    model)

    testCases.print("Swaption Cash Settled Value:", v)
def test_FinBinomialTree():

    stock_price = 50.0
    riskFreeRate = 0.06
    dividendYield = 0.04
    volatility = 0.40

    valuation_date = Date(1, 1, 2016)
    expiry_date = Date(1, 1, 2017)

    model = FinModelBlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, riskFreeRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

    num_stepsList = [100, 500, 1000, 2000, 5000]

    strikePrice = 50.0

    testCases.banner("================== EUROPEAN PUT =======================")

    putOption = FinEquityVanillaOption(expiry_date, strikePrice,
                                       FinOptionTypes.EUROPEAN_PUT)
    value = putOption.value(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    delta = putOption.delta(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    gamma = putOption.gamma(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    theta = putOption.theta(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta")
    testCases.print(value, delta, gamma, theta)

    payoff = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.EUROPEAN
    params = np.array([-1, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")

    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()
        results = tree.value(stock_price, discount_curve, dividendCurve,
                             volatility, num_steps, valuation_date, payoff,
                             expiry_date, payoff, exercise, params)
        end = time.time()
        duration = end - start
        testCases.print(num_steps, results, duration)

    testCases.banner("================== AMERICAN PUT =======================")

    payoff = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.AMERICAN
    params = np.array([-1, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")

    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()
        results = tree.value(stock_price, discount_curve, dividendCurve,
                             volatility, num_steps, valuation_date, payoff,
                             expiry_date, payoff, exercise, params)
        end = time.time()
        duration = end - start
        testCases.print(num_steps, results, duration)

    testCases.banner(
        "================== EUROPEAN CALL =======================")

    callOption = FinEquityVanillaOption(expiry_date, strikePrice,
                                        FinOptionTypes.EUROPEAN_CALL)
    value = callOption.value(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    delta = callOption.delta(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    gamma = callOption.gamma(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    theta = callOption.theta(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta")
    testCases.print(value, delta, gamma, theta)

    payoff = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.EUROPEAN
    params = np.array([1.0, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")
    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()

        results = tree.value(stock_price, discount_curve, dividendCurve,
                             volatility, num_steps, valuation_date, payoff,
                             expiry_date, payoff, exercise, params)

        end = time.time()
        duration = end - start
        testCases.print(num_steps, results, duration)

    testCases.banner(
        "================== AMERICAN CALL =======================")

    payoff = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.AMERICAN
    params = np.array([1.0, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")
    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()

        results = tree.value(stock_price, discount_curve, dividendCurve,
                             volatility, num_steps, valuation_date, payoff,
                             expiry_date, payoff, exercise, params)

        end = time.time()
        duration = end - start
        testCases.print(num_steps, results, duration)
Esempio n. 13
0
def test_HullWhiteExampleTwo():
    # HULL BOOK ZERO COUPON BOND EXAMPLE 28.1 SEE TABLE 28.3
    # Replication may not be exact as I am using dates rather than times

    zeroDays = [
        0, 3, 31, 62, 94, 185, 367, 731, 1096, 1461, 1826, 2194, 2558, 2922,
        3287, 3653
    ]

    zero_rates = [
        5.0, 5.01772, 4.98282, 4.97234, 4.96157, 4.99058, 5.09389, 5.79733,
        6.30595, 6.73464, 6.94816, 7.08807, 7.27527, 7.30852, 7.39790, 7.49015
    ]

    times = np.array(zeroDays) / 365.0
    zeros = np.array(zero_rates) / 100.0
    dfs = np.exp(-zeros * times)

    start_date = Date(1, 12, 2019)
    sigma = 0.01
    a = 0.1
    strike = 63.0
    face = 100.0

    expiry_date = start_date.add_tenor("3Y")
    maturity_date = start_date.add_tenor("9Y")

    texp = (expiry_date - start_date) / gDaysInYear
    tmat = (maturity_date - start_date) / gDaysInYear

    num_time_steps = None
    model = HWTree(sigma, a, num_time_steps)
    vAnal = model.option_on_zcb(texp, tmat, strike, face, times, dfs)

    # Test convergence
    num_steps_list = range(100, 500, 100)
    analVector = []
    treeVector = []

    testCases.banner("Comparing option on zero coupon bond analytical vs Tree")

    testCases.header("NUMTIMESTEP", "TIME", "VTREE_CALL", "VTREE_PUT",
                     "VANAL CALL", "VANAL_PUT", "CALLDIFF", "PUTDIFF")

    for num_time_steps in num_steps_list:

        start = time.time()

        model = HWTree(sigma, a, num_time_steps)
        model.build_tree(texp, times, dfs)
        vTree1 = model.option_on_zero_coupon_bond_tree(texp, tmat, strike,
                                                       face)

        model = HWTree(sigma, a, num_time_steps + 1)
        model.build_tree(texp, times, dfs)
        vTree2 = model.option_on_zero_coupon_bond_tree(texp, tmat, strike,
                                                       face)

        end = time.time()
        period = end - start
        treeVector.append(vTree1['put'])
        analVector.append(vAnal['put'])
        vTreeCall = (vTree1['call'] + vTree2['call']) / 2.0
        vTreePut = (vTree1['put'] + vTree2['put']) / 2.0
        diffC = vTreeCall - vAnal['call']
        diffP = vTreePut - vAnal['put']

        testCases.print(num_time_steps, period, vTreeCall, vAnal['call'],
                        vTreePut, vAnal['put'], diffC, diffP)
Esempio n. 14
0
def test_HullWhiteCallableBond():
    # Valuation of a European option on a coupon bearing bond

    settlement_date = Date(1, 12, 2019)
    issue_date = Date(1, 12, 2018)
    maturity_date = settlement_date.add_tenor("10Y")
    coupon = 0.05
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    coupon_times = []
    coupon_flows = []
    cpn = bond._coupon / bond._frequency

    for flow_date in bond._coupon_dates[1:]:

        if flow_date > settlement_date:
            flow_time = (flow_date - settlement_date) / gDaysInYear
            coupon_times.append(flow_time)
            coupon_flows.append(cpn)

    coupon_times = np.array(coupon_times)
    coupon_flows = np.array(coupon_flows)

    ###########################################################################
    # Set up the call and put times and prices
    ###########################################################################

    call_dates = []
    call_prices = []
    callPx = 120.0
    call_dates.append(settlement_date.add_tenor("2Y"))
    call_prices.append(callPx)
    call_dates.append(settlement_date.add_tenor("3Y"))
    call_prices.append(callPx)
    call_dates.append(settlement_date.add_tenor("4Y"))
    call_prices.append(callPx)
    call_dates.append(settlement_date.add_tenor("5Y"))
    call_prices.append(callPx)
    call_dates.append(settlement_date.add_tenor("6Y"))
    call_prices.append(callPx)
    call_dates.append(settlement_date.add_tenor("7Y"))
    call_prices.append(callPx)
    call_dates.append(settlement_date.add_tenor("8Y"))
    call_prices.append(callPx)

    call_times = []
    for dt in call_dates:
        t = (dt - settlement_date) / gDaysInYear
        call_times.append(t)

    put_dates = []
    put_prices = []
    putPx = 98.0
    put_dates.append(settlement_date.add_tenor("2Y"))
    put_prices.append(putPx)
    put_dates.append(settlement_date.add_tenor("3Y"))
    put_prices.append(putPx)
    put_dates.append(settlement_date.add_tenor("4Y"))
    put_prices.append(putPx)
    put_dates.append(settlement_date.add_tenor("5Y"))
    put_prices.append(putPx)
    put_dates.append(settlement_date.add_tenor("6Y"))
    put_prices.append(putPx)
    put_dates.append(settlement_date.add_tenor("7Y"))
    put_prices.append(putPx)
    put_dates.append(settlement_date.add_tenor("8Y"))
    put_prices.append(putPx)

    put_times = []
    for dt in put_dates:
        t = (dt - settlement_date) / gDaysInYear
        put_times.append(t)

    ###########################################################################

    tmat = (maturity_date - settlement_date) / gDaysInYear
    curve = DiscountCurveFlat(settlement_date, 0.05, FrequencyTypes.CONTINUOUS)

    dfs = []
    times = []

    for dt in bond._coupon_dates:
        if dt > settlement_date:
            t = (dt - settlement_date) / gDaysInYear
            df = curve.df(dt)
            times.append(t)
            dfs.append(df)

    dfs = np.array(dfs)
    times = np.array(times)

    ###########################################################################

    v1 = bond.clean_price_from_discount_curve(settlement_date, curve)

    sigma = 0.02  # basis point volatility
    a = 0.01

    # Test convergence
    num_steps_list = [100, 200, 500, 1000]
    tmat = (maturity_date - settlement_date) / gDaysInYear

    testCases.header("NUMSTEPS", "TIME", "BOND_ONLY", "CALLABLE_BOND")

    for num_time_steps in num_steps_list:

        start = time.time()
        model = HWTree(sigma, a, num_time_steps)
        model.build_tree(tmat, times, dfs)

        v2 = model.callable_puttable_bond_tree(coupon_times, coupon_flows,
                                               call_times, call_prices,
                                               put_times, put_prices, 100.0)

        end = time.time()
        period = end - start
        testCases.print(num_time_steps, period, v1, v2)
Esempio n. 15
0
def test_HullWhiteBondOption():
    # Valuation of a European option on a coupon bearing bond

    settlement_date = Date(1, 12, 2019)
    issue_date = Date(1, 12, 2018)
    expiry_date = settlement_date.add_tenor("18m")
    maturity_date = settlement_date.add_tenor("10Y")
    coupon = 0.05
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    coupon_times = []
    coupon_flows = []
    cpn = bond._coupon / bond._frequency

    num_flows = len(bond._coupon_dates)
    for i in range(1, num_flows):

        pcd = bond._coupon_dates[i - 1]
        ncd = bond._coupon_dates[i]

        if ncd > settlement_date:

            if len(coupon_times) == 0:
                flow_time = (pcd - settlement_date) / gDaysInYear
                coupon_times.append(flow_time)
                coupon_flows.append(cpn)

            flow_time = (ncd - settlement_date) / gDaysInYear
            coupon_times.append(flow_time)
            coupon_flows.append(cpn)

    coupon_times = np.array(coupon_times)
    coupon_flows = np.array(coupon_flows)

    strike_price = 100.0
    face = 100.0
    y = 0.05
    times = np.linspace(0, 10, 21)
    dfs = np.power(1 + y / 2, -times * 2)

    sigma = 0.0000001
    a = 0.1
    model = HWTree(sigma, a, None)

    #  Test convergence
    num_steps_list = range(50, 500, 50)
    texp = (expiry_date - settlement_date) / gDaysInYear

    vJam = model.european_bond_option_jamshidian(texp, strike_price, face,
                                                 coupon_times, coupon_flows,
                                                 times, dfs)

    testCases.banner(
        "Pricing bond option on tree that goes to bond maturity and one using european bond option tree that goes to expiry."
    )

    testCases.header("NUMSTEPS", "TIME", "EXPIRY_ONLY", "EXPIRY_TREE",
                     "JAMSHIDIAN")

    for num_time_steps in num_steps_list:

        start = time.time()
        model = HWTree(sigma, a, num_time_steps,
                       FinHWEuropeanCalcType.EXPIRY_ONLY)
        model.build_tree(texp, times, dfs)

        exercise_type = FinExerciseTypes.EUROPEAN

        v1 = model.bond_option(texp, strike_price, face, coupon_times,
                               coupon_flows, exercise_type)

        model = HWTree(sigma, a, num_time_steps,
                       FinHWEuropeanCalcType.EXPIRY_TREE)
        model.build_tree(texp, times, dfs)

        v2 = model.bond_option(texp, strike_price, face, coupon_times,
                               coupon_flows, exercise_type)

        end = time.time()
        period = end - start

        testCases.print(num_time_steps, period, v1, v2, vJam)

#    plt.plot(num_steps_list, treeVector)

    if 1 == 0:
        print("RT")
        print_tree(model._rt, 5)
        print("BOND")
        print_tree(model._bond_values, 5)
        print("OPTION")
        print_tree(model._option_values, 5)
def test_EquityDigitalOption():

    underlying_type = FinDigitalOptionTypes.CASH_OR_NOTHING

    valuation_date = Date(1, 1, 2015)
    expiry_date = Date(1, 1, 2016)
    stock_price = 100.0
    volatility = 0.30
    interest_rate = 0.05
    dividend_yield = 0.01
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    model = BlackScholes(volatility)
    import time

    call_option_values = []
    call_option_valuesMC = []
    num_paths_list = [
        10000, 20000, 40000, 80000, 160000, 320000, 640000, 1280000, 2560000
    ]

    testCases.header("NumLoops", "ValueBS", "ValueMC", "TIME")

    for num_paths in num_paths_list:

        call_option = EquityDigitalOption(expiry_date, 100.0,
                                          OptionTypes.EUROPEAN_CALL,
                                          underlying_type)
        value = call_option.value(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model)
        start = time.time()
        value_mc = call_option.value_mc(valuation_date, stock_price,
                                        discount_curve, dividend_curve, model,
                                        num_paths)
        end = time.time()
        duration = end - start
        testCases.print(num_paths, value, value_mc, duration)

        call_option_values.append(value)
        call_option_valuesMC.append(value_mc)

#    plt.figure(figsize=(10,8))
#    plt.plot(num_paths_list, call_option_values, color = 'b', label="Call Option")
#    plt.plot(num_paths_list, call_option_valuesMC, color = 'r', label = "Call Option MC")
#    plt.xlabel("Num Loops")
#    plt.legend(loc='best')

##########################################################################

    stock_prices = range(50, 150, 50)
    call_option_values = []
    call_optionDeltas = []
    call_optionVegas = []
    call_optionThetas = []

    for stock_price in stock_prices:
        call_option = EquityDigitalOption(expiry_date, 100.0,
                                          OptionTypes.EUROPEAN_CALL,
                                          underlying_type)
        value = call_option.value(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model)
        delta = call_option.delta(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model)
        vega = call_option.vega(valuation_date, stock_price, discount_curve,
                                dividend_curve, model)
        theta = call_option.theta(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model)
        call_option_values.append(value)
        call_optionDeltas.append(delta)
        call_optionVegas.append(vega)
        call_optionThetas.append(theta)

    put_option_values = []
    put_optionDeltas = []
    put_optionVegas = []
    put_optionThetas = []

    for stock_price in stock_prices:
        put_option = EquityDigitalOption(expiry_date, 100.0,
                                         OptionTypes.EUROPEAN_PUT,
                                         underlying_type)
        value = put_option.value(valuation_date, stock_price, discount_curve,
                                 dividend_curve, model)
        delta = put_option.delta(valuation_date, stock_price, discount_curve,
                                 dividend_curve, model)
        vega = put_option.vega(valuation_date, stock_price, discount_curve,
                               dividend_curve, model)
        theta = put_option.theta(valuation_date, stock_price, discount_curve,
                                 dividend_curve, model)
        put_option_values.append(value)
        put_optionDeltas.append(delta)
        put_optionVegas.append(vega)
        put_optionThetas.append(theta)
Esempio n. 17
0
def test_IborSwaptionQLExample():

    valuation_date = Date(4, 3, 2014)
    settlement_date = Date(4, 3, 2014)

    depoDCCType = DayCountTypes.THIRTY_E_360_ISDA
    depos = []
    depo = IborDeposit(settlement_date, "1W", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "1M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "3M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "6M", 0.0023, depoDCCType)
    depos.append(depo)

    # No convexity correction provided so I omit interest rate futures

    swaps = []
    accType = DayCountTypes.ACT_365F
    fixedFreqType = FrequencyTypes.SEMI_ANNUAL
    fixed_leg_type = SwapTypes.PAY

    swap = IborSwap(settlement_date, "3Y", fixed_leg_type, 0.00790,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "4Y", fixed_leg_type, 0.01200,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "5Y", fixed_leg_type, 0.01570,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "6Y", fixed_leg_type, 0.01865,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "7Y", fixed_leg_type, 0.02160,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "8Y", fixed_leg_type, 0.02350,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "9Y", fixed_leg_type, 0.02540,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "10Y", fixed_leg_type, 0.0273,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "15Y", fixed_leg_type, 0.0297,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "20Y", fixed_leg_type, 0.0316,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "25Y", fixed_leg_type, 0.0335,
                    fixedFreqType, accType)
    swaps.append(swap)
    swap = IborSwap(settlement_date, "30Y", fixed_leg_type, 0.0354,
                    fixedFreqType, accType)
    swaps.append(swap)

    libor_curve = IborSingleCurve(valuation_date, depos, [], swaps,
                                  InterpTypes.LINEAR_ZERO_RATES)

    exercise_date = settlement_date.add_tenor("5Y")
    swapMaturityDate = exercise_date.add_tenor("5Y")
    swapFixedCoupon = 0.040852
    swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = DayCountTypes.THIRTY_E_360_ISDA
    swapFloatFrequencyType = FrequencyTypes.QUARTERLY
    swapFloatDayCountType = DayCountTypes.ACT_360
    swapNotional = 1000000
    swaptionType = SwapTypes.PAY

    swaption = IborSwaption(settlement_date, exercise_date, swapMaturityDate,
                            swaptionType, swapFixedCoupon,
                            swapFixedFrequencyType, swapFixedDayCountType,
                            swapNotional, swapFloatFrequencyType,
                            swapFloatDayCountType)

    testCases.header("MODEL", "VALUE")

    model = Black(0.1533)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print(model.__class__, v)

    model = BlackShifted(0.1533, -0.008)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print(model.__class__, v)

    model = SABR(0.132, 0.5, 0.5, 0.5)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print(model.__class__, v)

    model = SABRShifted(0.352, 0.5, 0.15, 0.15, -0.005)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print(model.__class__, v)

    model = HWTree(0.010000000, 0.00000000001)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print(model.__class__, v)
Esempio n. 18
0
def test_CDSIndexAdjustSpreads():

    tradeDate = Date(1, 8, 2007)
    step_in_date = tradeDate.add_days(1)
    valuation_date = tradeDate

    libor_curve = build_Ibor_Curve(tradeDate)

    maturity3Y = tradeDate.next_cds_date(36)
    maturity5Y = tradeDate.next_cds_date(60)
    maturity7Y = tradeDate.next_cds_date(84)
    maturity10Y = tradeDate.next_cds_date(120)

    path = dirname(__file__)
    filename = "CDX_NA_IG_S7_SPREADS.csv"
    full_filename_path = join(path, "data", filename)
    f = open(full_filename_path, 'r')

    data = f.readlines()
    issuer_curves = []

    for row in data[1:]:

        splitRow = row.split(",")
        spd3Y = float(splitRow[1]) / 10000.0
        spd5Y = float(splitRow[2]) / 10000.0
        spd7Y = float(splitRow[3]) / 10000.0
        spd10Y = float(splitRow[4]) / 10000.0
        recovery_rate = float(splitRow[5])

        cds3Y = CDS(step_in_date, maturity3Y, spd3Y)
        cds5Y = CDS(step_in_date, maturity5Y, spd5Y)
        cds7Y = CDS(step_in_date, maturity7Y, spd7Y)
        cds10Y = CDS(step_in_date, maturity10Y, spd10Y)
        cds_contracts = [cds3Y, cds5Y, cds7Y, cds10Y]

        issuer_curve = CDSCurve(valuation_date, cds_contracts, libor_curve,
                                recovery_rate)

        issuer_curves.append(issuer_curve)

    ##########################################################################
    # Now determine the average spread of the index
    ##########################################################################

    cdsIndex = CDSIndexPortfolio()

    averageSpd3Y = cdsIndex.average_spread(valuation_date, step_in_date,
                                           maturity3Y, issuer_curves) * 10000.0

    averageSpd5Y = cdsIndex.average_spread(valuation_date, step_in_date,
                                           maturity5Y, issuer_curves) * 10000.0

    averageSpd7Y = cdsIndex.average_spread(valuation_date, step_in_date,
                                           maturity7Y, issuer_curves) * 10000.0

    averageSpd10Y = cdsIndex.average_spread(
        valuation_date, step_in_date, maturity10Y, issuer_curves) * 10000.0

    testCases.header("LABEL", "VALUE")
    testCases.print("AVERAGE SPD 3Y", averageSpd3Y)
    testCases.print("AVERAGE SPD 5Y", averageSpd5Y)
    testCases.print("AVERAGE SPD 7Y", averageSpd7Y)
    testCases.print("AVERAGE SPD 10Y", averageSpd10Y)

    ##########################################################################
    # Now determine the intrinsic spread of the index to the same maturity dates
    # As the single name CDS contracts
    ##########################################################################

    cdsIndex = CDSIndexPortfolio()

    intrinsicSpd3Y = cdsIndex.intrinsic_spread(
        valuation_date, step_in_date, maturity3Y, issuer_curves) * 10000.0

    intrinsicSpd5Y = cdsIndex.intrinsic_spread(
        valuation_date, step_in_date, maturity5Y, issuer_curves) * 10000.0

    intrinsicSpd7Y = cdsIndex.intrinsic_spread(
        valuation_date, step_in_date, maturity7Y, issuer_curves) * 10000.0

    intrinsicSpd10Y = cdsIndex.intrinsic_spread(
        valuation_date, step_in_date, maturity10Y, issuer_curves) * 10000.0

    ##########################################################################
    ##########################################################################

    testCases.header("LABEL", "VALUE")
    testCases.print("INTRINSIC SPD 3Y", intrinsicSpd3Y)
    testCases.print("INTRINSIC SPD 5Y", intrinsicSpd5Y)
    testCases.print("INTRINSIC SPD 7Y", intrinsicSpd7Y)
    testCases.print("INTRINSIC SPD 10Y", intrinsicSpd10Y)

    ##########################################################################
    ##########################################################################

    index_coupons = [0.002, 0.0037, 0.0050, 0.0063]
    indexUpfronts = [0.0, 0.0, 0.0, 0.0]
    indexMaturityDates = [
        Date(20, 12, 2009),
        Date(20, 12, 2011),
        Date(20, 12, 2013),
        Date(20, 12, 2016)
    ]
    indexRecoveryRate = 0.40

    tolerance = 1e-7

    import time
    start = time.time()

    indexPortfolio = CDSIndexPortfolio()
    adjustedIssuerCurves = indexPortfolio.spread_adjust_intrinsic(
        valuation_date, issuer_curves, index_coupons, indexUpfronts,
        indexMaturityDates, indexRecoveryRate, tolerance)

    end = time.time()
    testCases.header("TIME")
    testCases.print(end - start)

    cdsIndex = CDSIndexPortfolio()

    intrinsicSpd3Y = cdsIndex.intrinsic_spread(valuation_date, step_in_date,
                                               indexMaturityDates[0],
                                               adjustedIssuerCurves) * 10000.0

    intrinsicSpd5Y = cdsIndex.intrinsic_spread(valuation_date, step_in_date,
                                               indexMaturityDates[1],
                                               adjustedIssuerCurves) * 10000.0

    intrinsicSpd7Y = cdsIndex.intrinsic_spread(valuation_date, step_in_date,
                                               indexMaturityDates[2],
                                               adjustedIssuerCurves) * 10000.0

    intrinsicSpd10Y = cdsIndex.intrinsic_spread(valuation_date, step_in_date,
                                                indexMaturityDates[3],
                                                adjustedIssuerCurves) * 10000.0

    # If the adjustment works then this should equal the index spreads
    testCases.header("LABEL", "VALUE")
    testCases.print("ADJUSTED INTRINSIC SPD 3Y:", intrinsicSpd3Y)
    testCases.print("ADJUSTED INTRINSIC SPD 5Y:", intrinsicSpd5Y)
    testCases.print("ADJUSTED INTRINSIC SPD 7Y", intrinsicSpd7Y)
    testCases.print("ADJUSTED INTRINSIC SPD 10Y", intrinsicSpd10Y)
Esempio n. 19
0
def testIborSwaptionMatlabExamples():

    # We value a European swaption using Black's model and try to replicate a
    # ML example at https://fr.mathworks.com/help/fininst/swaptionbyblk.html

    testCases.header("=======================================")
    testCases.header("MATLAB EXAMPLE WITH FLAT TERM STRUCTURE")
    testCases.header("=======================================")

    valuation_date = Date(1, 1, 2010)
    libor_curve = DiscountCurveFlat(valuation_date, 0.06,
                                    FrequencyTypes.CONTINUOUS,
                                    DayCountTypes.THIRTY_E_360)

    settlement_date = Date(1, 1, 2011)
    exercise_date = Date(1, 1, 2016)
    maturity_date = Date(1, 1, 2019)

    fixed_coupon = 0.062
    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    # Pricing a PAY
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    model = Black(0.20)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 2.071

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

    ###############################################################################

    testCases.header("===================================")
    testCases.header("MATLAB EXAMPLE WITH TERM STRUCTURE")
    testCases.header("===================================")

    valuation_date = Date(1, 1, 2010)

    dates = [
        Date(1, 1, 2011),
        Date(1, 1, 2012),
        Date(1, 1, 2013),
        Date(1, 1, 2014),
        Date(1, 1, 2015)
    ]

    zero_rates = [0.03, 0.034, 0.037, 0.039, 0.040]

    contFreq = FrequencyTypes.CONTINUOUS
    interp_type = InterpTypes.LINEAR_ZERO_RATES
    day_count_type = DayCountTypes.THIRTY_E_360

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = Date(1, 1, 2011)
    exercise_date = Date(1, 1, 2012)
    maturity_date = Date(1, 1, 2017)
    fixed_coupon = 0.03

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360
    float_frequency_type = FrequencyTypes.SEMI_ANNUAL
    float_day_count_type = DayCountTypes.THIRTY_E_360
    notional = 1000.0

    # Pricing a put
    swaptionType = SwapTypes.RECEIVE
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional,
                            float_frequency_type, float_day_count_type)

    model = Black(0.21)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 0.5771

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

    ###############################################################################

    testCases.header("===================================")
    testCases.header("MATLAB EXAMPLE WITH SHIFTED BLACK")
    testCases.header("===================================")

    valuation_date = Date(1, 1, 2016)

    dates = [
        Date(1, 1, 2017),
        Date(1, 1, 2018),
        Date(1, 1, 2019),
        Date(1, 1, 2020),
        Date(1, 1, 2021)
    ]

    zero_rates = np.array([-0.02, 0.024, 0.047, 0.090, 0.12]) / 100.0

    contFreq = FrequencyTypes.ANNUAL
    interp_type = InterpTypes.LINEAR_ZERO_RATES
    day_count_type = DayCountTypes.THIRTY_E_360

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = Date(1, 1, 2016)
    exercise_date = Date(1, 1, 2017)
    maturity_date = Date(1, 1, 2020)
    fixed_coupon = -0.003

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    float_frequency_type = FrequencyTypes.SEMI_ANNUAL
    float_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 1000.0

    # Pricing a PAY
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional,
                            float_frequency_type, float_day_count_type)

    model = BlackShifted(0.31, 0.008)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 12.8301

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

    ###############################################################################

    testCases.header("===================================")
    testCases.header("MATLAB EXAMPLE WITH HULL WHITE")
    testCases.header("===================================")

    # https://fr.mathworks.com/help/fininst/swaptionbyhw.html

    valuation_date = Date(1, 1, 2007)

    dates = [
        Date(1, 1, 2007),
        Date(1, 7, 2007),
        Date(1, 1, 2008),
        Date(1, 7, 2008),
        Date(1, 1, 2009),
        Date(1, 7, 2009),
        Date(1, 1, 2010),
        Date(1, 7, 2010),
        Date(1, 1, 2011),
        Date(1, 7, 2011),
        Date(1, 1, 2012)
    ]

    zero_rates = np.array([0.075] * 11)
    interp_type = InterpTypes.FLAT_FWD_RATES
    day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    contFreq = FrequencyTypes.SEMI_ANNUAL

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = valuation_date
    exercise_date = Date(1, 1, 2010)
    maturity_date = Date(1, 1, 2012)
    fixed_coupon = 0.04

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    swaptionType = SwapTypes.RECEIVE
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    model = HWTree(0.05, 0.01)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 2.9201

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

    ###############################################################################

    testCases.header("====================================")
    testCases.header("MATLAB EXAMPLE WITH BLACK KARASINSKI")
    testCases.header("====================================")

    # https://fr.mathworks.com/help/fininst/swaptionbybk.html
    valuation_date = Date(1, 1, 2007)

    dates = [
        Date(1, 1, 2007),
        Date(1, 7, 2007),
        Date(1, 1, 2008),
        Date(1, 7, 2008),
        Date(1, 1, 2009),
        Date(1, 7, 2009),
        Date(1, 1, 2010),
        Date(1, 7, 2010),
        Date(1, 1, 2011),
        Date(1, 7, 2011),
        Date(1, 1, 2012)
    ]

    zero_rates = np.array([0.07] * 11)

    interp_type = InterpTypes.FLAT_FWD_RATES
    day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    contFreq = FrequencyTypes.SEMI_ANNUAL

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = valuation_date
    exercise_date = Date(1, 1, 2011)
    maturity_date = Date(1, 1, 2012)

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    model = BKTree(0.1, 0.05, 200)

    fixed_coupon = 0.07
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 0.3634

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

    fixed_coupon = 0.0725
    swaptionType = SwapTypes.RECEIVE
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 0.4798

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

    ###############################################################################

    testCases.header("====================================")
    testCases.header("MATLAB EXAMPLE WITH BLACK-DERMAN-TOY")
    testCases.header("====================================")

    # https://fr.mathworks.com/help/fininst/swaptionbybdt.html

    valuation_date = Date(1, 1, 2007)

    dates = [
        Date(1, 1, 2007),
        Date(1, 7, 2007),
        Date(1, 1, 2008),
        Date(1, 7, 2008),
        Date(1, 1, 2009),
        Date(1, 7, 2009),
        Date(1, 1, 2010),
        Date(1, 7, 2010),
        Date(1, 1, 2011),
        Date(1, 7, 2011),
        Date(1, 1, 2012)
    ]

    zero_rates = np.array([0.06] * 11)

    interp_type = InterpTypes.FLAT_FWD_RATES
    day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    contFreq = FrequencyTypes.ANNUAL

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = valuation_date
    exercise_date = Date(1, 1, 2012)
    maturity_date = Date(1, 1, 2015)

    fixed_frequency_type = FrequencyTypes.ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    fixed_coupon = 0.062
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    model = BDTTree(0.20, 200)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 2.0592

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)
Esempio n. 20
0
def test_FinFXOptionSABR():

    # UNFINISHED
    # There is no FXAmericanOption class. It is embedded in the FXVanillaOption
    # class. This test just compares it to the European

    valuation_date = Date(13, 2, 2018)
    expiry_date = Date(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1CCRate = 0.030  # EUR
    ccy2CCRate = 0.025  # USD

    spot_fx_rate = 1.20
    strike_fx_rate = 1.250
    volatility = 0.10

    notional = 1000000.0

    dom_discount_curve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = BlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0

    spot_fx_rates = np.arange(50, 200, 10)/100.0

    testCases.header("OPTION", "FX_RATE", "VALUE_BS", "VOL_IN", "DIFF")

    for spot_fx_rate in spot_fx_rates:

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.EUROPEAN_CALL,
                                     notional,
                                     "USD")

        valueEuropean = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.AMERICAN_CALL,
                                     1000000,
                                     "USD")

        valueAmerican = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        diff = (valueAmerican - valueEuropean)

        testCases.print("CALL:",
                        "%9.6f" % spot_fx_rate,
                        "%9.7f" % valueEuropean,
                        "%9.7f" % valueAmerican,
                        "%9.7f" % diff)

    testCases.header("OPTION", "FX_RATE", "VALUE_BS", "VOL_IN", "DIFF")

    for spot_fx_rate in spot_fx_rates:

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.EUROPEAN_PUT,
                                     1000000,
                                     "USD")

        valueEuropean = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.AMERICAN_PUT,
                                     1000000,
                                     "USD")

        valueAmerican = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        diff = (valueAmerican - valueEuropean)
        testCases.print("PUT:",
                        "%9.6f" % spot_fx_rate,
                        "%9.7f" % valueEuropean,
                        "%9.7f" % valueAmerican,
                        "%9.7f" % diff)
Esempio n. 21
0
def test_FinCDSBasket():

    tradeDate = Date(1, 3, 2007)
    step_in_date = tradeDate.add_days(1)
    valuation_date = tradeDate.add_days(1)

    libor_curve = build_Ibor_Curve(tradeDate)

    basketMaturity = Date(20, 12, 2011)

    cdsIndex = CDSIndexPortfolio()

    ##########################################################################

    testCases.banner(
        "===================================================================")
    testCases.banner(
        "====================== INHOMOGENEOUS CURVE =========================="
    )
    testCases.banner(
        "===================================================================")

    num_credits = 5
    spd3Y = 0.0012
    spd5Y = 0.0025
    spd7Y = 0.0034
    spd10Y = 0.0046

    testCases.header("LABELS", "VALUE")

    if 1 == 0:
        issuer_curves = loadHomogeneousSpreadCurves(valuation_date,
                                                    libor_curve, spd3Y, spd5Y,
                                                    spd7Y, spd10Y, num_credits)
    else:
        issuer_curves = loadHeterogeneousSpreadCurves(valuation_date,
                                                      libor_curve)
        issuer_curves = issuer_curves[0:num_credits]

    intrinsicSpd = cdsIndex.intrinsic_spread(
        valuation_date, step_in_date, basketMaturity, issuer_curves) * 10000.0

    testCases.print("INTRINSIC SPD BASKET MATURITY", intrinsicSpd)

    totalSpd = cdsIndex.total_spread(valuation_date, step_in_date,
                                     basketMaturity, issuer_curves) * 10000.0

    testCases.print("SUMMED UP SPD BASKET MATURITY", totalSpd)

    minSpd = cdsIndex.min_spread(valuation_date, step_in_date, basketMaturity,
                                 issuer_curves) * 10000.0

    testCases.print("MINIMUM SPD BASKET MATURITY", minSpd)

    maxSpd = cdsIndex.max_spread(valuation_date, step_in_date, basketMaturity,
                                 issuer_curves) * 10000.0

    testCases.print("MAXIMUM SPD BASKET MATURITY", maxSpd)

    seed = 1967
    basket = CDSBasket(valuation_date, basketMaturity)

    testCases.banner(
        "===================================================================")
    testCases.banner(
        "======================= GAUSSIAN COPULA ===========================")
    testCases.banner(
        "===================================================================")

    testCases.header("TIME", "Trials", "RHO", "NTD", "SPRD", "SPRD_HOMO")

    for ntd in range(1, num_credits + 1):
        for beta in [0.0, 0.5]:
            rho = beta * beta
            beta_vector = np.ones(num_credits) * beta
            corr_matrix = corr_matrix_generator(rho, num_credits)
            for num_trials in [1000]:  # [1000,5000,10000,20000,50000,100000]:
                start = time.time()

                v1 = basket.value_gaussian_mc(valuation_date, ntd,
                                              issuer_curves, corr_matrix,
                                              libor_curve, num_trials, seed)

                v2 = basket.value_1f_gaussian_homo(valuation_date, ntd,
                                                   issuer_curves, beta_vector,
                                                   libor_curve)

                end = time.time()
                period = (end - start)
                testCases.print(period, num_trials, rho, ntd, v1[2] * 10000,
                                v2[3] * 10000)

    testCases.banner(
        "===================================================================")
    testCases.banner(
        "==================== STUDENT'S-T CONVERGENCE ======================")
    testCases.banner(
        "===================================================================")

    testCases.header("TIME", "TRIALS", "RHO", "DOF", "NTD", "SPRD")

    for beta in [0.0, 0.5]:
        rho = beta**2
        corr_matrix = corr_matrix_generator(rho, num_credits)
        for ntd in range(1, num_credits + 1):
            for doF in [3, 6]:
                start = time.time()

                v = basket.value_student_t_mc(valuation_date, ntd,
                                              issuer_curves, corr_matrix, doF,
                                              libor_curve, num_trials, seed)

                end = time.time()
                period = (end - start)
                testCases.print(period, num_trials, rho, doF, ntd,
                                v[2] * 10000)

            start = time.time()
            v = basket.value_gaussian_mc(valuation_date, ntd, issuer_curves,
                                         corr_matrix, libor_curve, num_trials,
                                         seed)
            end = time.time()
            period = (end - start)

            testCases.print(period, num_trials, rho, "GC", ntd, v[2] * 10000)

    testCases.banner(
        "===================================================================")
    testCases.banner(
        "=================== STUDENT'S T WITH DOF = 5 ======================")
    testCases.banner(
        "===================================================================")
    doF = 5
    testCases.header("TIME", "NUMTRIALS", "RHO", "NTD", "SPD")
    for beta in [0.0, 0.5]:
        rho = beta**2
        corr_matrix = corr_matrix_generator(rho, num_credits)
        for ntd in range(1, num_credits + 1):
            for num_trials in [1000]:
                start = time.time()

                v = basket.value_student_t_mc(valuation_date, ntd,
                                              issuer_curves, corr_matrix, doF,
                                              libor_curve, num_trials, seed)
                end = time.time()
                period = (end - start)
                testCases.print(period, num_trials, rho, ntd, v[2] * 10000)
Esempio n. 22
0
def test_Bond():
    import pandas as pd
    path = os.path.join(os.path.dirname(__file__), './data/giltBondPrices.txt')
    bondDataFrame = pd.read_csv(path, sep='\t')
    bondDataFrame['mid'] = 0.5 * (bondDataFrame['bid'] + bondDataFrame['ask'])

    freq_type = FrequencyTypes.SEMI_ANNUAL
    settlement_date = Date(19, 9, 2012)
    face = ONE_MILLION

    for accrual_type in DayCountTypes:

        testCases.header("MATURITY", "COUPON", "CLEAN_PRICE", "ACCD_DAYS",
                         "ACCRUED", "YTM")

        for _, bond in bondDataFrame.iterrows():
            dateString = bond['maturity']
            matDatetime = dt.datetime.strptime(dateString, '%d-%b-%y')
            maturityDt = fromDatetime(matDatetime)
            issueDt = Date(maturityDt._d, maturityDt._m, 2000)

            coupon = bond['coupon'] / 100.0
            clean_price = bond['mid']
            bond = Bond(issueDt, maturityDt,
                        coupon, freq_type, accrual_type, 100)

            ytm = bond.yield_to_maturity(settlement_date, clean_price)
            accrued_interest= bond._accruedInterest
            accd_days = bond._accrued_days

            testCases.print("%18s" % maturityDt, "%8.4f" % coupon,
                            "%10.4f" % clean_price, "%6.0f" % accd_days,
                            "%10.4f" % accrued_interest, "%8.4f" % ytm)

    ###########################################################################
    #  EXAMPLE FROM http://bondtutor.com/btchp4/topic6/topic6.htm

    accrualConvention = DayCountTypes.ACT_ACT_ICMA
    y = 0.062267
    settlement_date = Date(19, 4, 1994)
    issue_date = Date(15, 7, 1990)
    maturity_date = Date(15, 7, 1997)
    coupon = 0.085
    face = ONE_MILLION
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issue_date, maturity_date,
                coupon, freq_type, accrualConvention, face)

    testCases.header("FIELD", "VALUE")
    full_price = bond.full_price_from_ytm(settlement_date, y)
    testCases.print("Full Price = ", full_price)
    clean_price = bond.clean_price_from_ytm(settlement_date, y)
    testCases.print("Clean Price = ", clean_price)
    accrued_interest= bond._accruedInterest
    testCases.print("Accrued = ", accrued_interest)
    ytm = bond.yield_to_maturity(settlement_date, clean_price)
    testCases.print("Yield to Maturity = ", ytm)

    bump = 1e-4
    priceBumpedUp = bond.full_price_from_ytm(settlement_date, y + bump)
    testCases.print("Price Bumped Up:", priceBumpedUp)

    priceBumpedDn = bond.full_price_from_ytm(settlement_date, y - bump)
    testCases.print("Price Bumped Dn:", priceBumpedDn)

    durationByBump = -(priceBumpedUp - full_price) / bump
    testCases.print("Duration by Bump = ", durationByBump)

    duration = bond.dollar_duration(settlement_date, y)
    testCases.print("Dollar Duration = ", duration)
    testCases.print("Duration Difference:", duration - durationByBump)

    modified_duration = bond.modified_duration(settlement_date, y)
    testCases.print("Modified Duration = ", modified_duration)

    macauley_duration = bond.macauley_duration(settlement_date, y)
    testCases.print("Macauley Duration = ", macauley_duration)

    conv = bond.convexity_from_ytm(settlement_date, y)
    testCases.print("Convexity = ", conv)

    # ASSET SWAP SPREAD

    # When the libor curve is the flat bond curve then the ASW is zero by
    # definition
    flatCurve = DiscountCurveFlat(settlement_date,
                                  ytm,
                                  FrequencyTypes.SEMI_ANNUAL)

    testCases.header("FIELD", "VALUE")

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    asw = bond.asset_swap_spread(settlement_date, clean_price, flatCurve)
    testCases.print("Discounted on Bond Curve ASW:", asw * 10000)

    # When the libor curve is the Libor curve then the ASW is positive
    libor_curve = buildIborCurve(settlement_date)
    asw = bond.asset_swap_spread(settlement_date, clean_price, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, clean_price, libor_curve)
    testCases.print("Discounted on LIBOR Curve ASW:", asw * 10000)
    testCases.print("Discounted on LIBOR Curve OAS:", oas * 10000)

    p = 90.0
    asw = bond.asset_swap_spread(settlement_date, p, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, p, libor_curve)
    testCases.print("Deep discount bond at 90 ASW:", asw * 10000)
    testCases.print("Deep discount bond at 90 OAS:", oas * 10000)

    p = 100.0
    asw = bond.asset_swap_spread(settlement_date, p, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, p, libor_curve)
    testCases.print("Par bond at 100 ASW:", asw * 10000)
    testCases.print("Par bond at 100 OAS:", oas * 10000)

    p = 120.0
    asw = bond.asset_swap_spread(settlement_date, p, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, p, libor_curve)
    testCases.print("Above par bond at 120 ASW:", asw * 10000)
    testCases.print("Above par bond at 120 OAS:", oas * 10000)

    ##########################################################################
    # https://data.bloomberglp.com/bat/sites/3/2017/07/SF-2017_Paul-Fjeldsted.pdf
    # Page 10 TREASURY NOTE SCREENSHOT
    ##########################################################################

    testCases.banner("BLOOMBERG US TREASURY EXAMPLE")
    settlement_date = Date(21, 7, 2017)
    issue_date = Date(15, 5, 2010)
    maturity_date = Date(15, 5, 2027)
    coupon = 0.02375
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    face = 100.0

    bond = Bond(issue_date,
                maturity_date,
                coupon,
                freq_type,
                accrual_type,
                face)

    testCases.header("FIELD", "VALUE")
    clean_price = 99.7808417

    yld = bond.current_yield(clean_price)
    testCases.print("Current Yield = ", yld)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.UK_DMO)
    testCases.print("UK DMO Yield To Maturity = ", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_STREET)
    testCases.print("US STREET Yield To Maturity = ", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_TREASURY)
    testCases.print("US TREASURY Yield To Maturity = ", ytm)

    full_price = bond.full_price_from_ytm(settlement_date, ytm)
    testCases.print("Full Price = ", full_price)

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    testCases.print("Clean Price = ", clean_price)

    accrued_interest= bond._accruedInterest
    testCases.print("Accrued = ", accrued_interest)

    accddays = bond._accrued_days
    testCases.print("Accrued Days = ", accddays)

    duration = bond.dollar_duration(settlement_date, ytm)
    testCases.print("Dollar Duration = ", duration)

    modified_duration = bond.modified_duration(settlement_date, ytm)
    testCases.print("Modified Duration = ", modified_duration)

    macauley_duration = bond.macauley_duration(settlement_date, ytm)
    testCases.print("Macauley Duration = ", macauley_duration)

    conv = bond.convexity_from_ytm(settlement_date, ytm)
    testCases.print("Convexity = ", conv)

    ##########################################################################
    # Page 11 APPLE NOTE SCREENSHOT
    ##########################################################################

    testCases.banner("BLOOMBERG APPLE CORP BOND EXAMPLE")
    settlement_date = Date(21, 7, 2017)
    issue_date = Date(13, 5, 2012)
    maturity_date = Date(13, 5, 2022)
    coupon = 0.027
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.THIRTY_E_360_ISDA
    face = 100.0

    bond = Bond(issue_date, maturity_date,
                coupon, freq_type, accrual_type, face)

    testCases.header("FIELD", "VALUE")
    clean_price = 101.581564

    yld = bond.current_yield(clean_price)
    testCases.print("Current Yield", yld)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.UK_DMO)
    testCases.print("UK DMO Yield To Maturity", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_STREET)
    testCases.print("US STREET Yield To Maturity", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_TREASURY)
    testCases.print("US TREASURY Yield To Maturity", ytm)

    full_price = bond.full_price_from_ytm(settlement_date, ytm)
    testCases.print("Full Price", full_price)

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    testCases.print("Clean Price", clean_price)

    accddays = bond._accrued_days
    testCases.print("Accrued Days", accddays)

    accrued_interest= bond._accruedInterest
    testCases.print("Accrued", accrued_interest)

    duration = bond.dollar_duration(settlement_date, ytm)
    testCases.print("Dollar Duration", duration)

    modified_duration = bond.modified_duration(settlement_date, ytm)
    testCases.print("Modified Duration", modified_duration)

    macauley_duration = bond.macauley_duration(settlement_date, ytm)
    testCases.print("Macauley Duration", macauley_duration)

    conv = bond.convexity_from_ytm(settlement_date, ytm)
    testCases.print("Convexity", conv)
Esempio n. 23
0
def test_FinSchedule():

    ###########################################################################
    # BACKWARD SCHEDULES TESTING DIFFERENT FREQUENCIES
    ###########################################################################

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    termination_dateAdjust = True

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("BACKWARD SEMI-ANNUAL FREQUENCY", schedule)

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.QUARTERLY
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("BACKWARD QUARTERLY FREQUENCY", schedule)

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.MONTHLY
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("BACKWARD MONTHLY FREQUENCY", schedule)

    ###########################################################################
    # FORWARD SCHEDULES TESTING DIFFERENT FREQUENCIES
    ###########################################################################

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.ANNUAL
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.FORWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("FORWARD ANNUAL", schedule)

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type)

    dumpSchedule("FORWARD SEMI-ANNUAL", schedule)

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.MONTHLY
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("FORWARD MONTHLY", schedule)

    ###########################################################################
    # BACKWARD SHORT STUB AT FRONT
    ###########################################################################

    d1 = Date(20, 8, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.QUARTERLY
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)
    dumpSchedule("BACKWARD GEN WITH SHORT END STUB", schedule)

    ###########################################################################
    # BACKWARD SUPER SHORT STUB AT FRONT
    ###########################################################################

    d1 = Date(19, 9, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.QUARTERLY
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("BACKWARD GEN WITH VERY SHORT END STUB", schedule)

    ###########################################################################
    # FORWARD SHORT STUB AT END
    ###########################################################################

    d1 = Date(20, 8, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.FORWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("FORWARD GEN WITH END STUB", schedule)

    d1 = Date(19, 9, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.QUARTERLY
    calendar_type = CalendarTypes.TARGET
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.FORWARD

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type)

    dumpSchedule("FORWARD GEN WITH VERY SHORT END STUB", schedule)

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    termination_dateAdjust = True

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust)

    dumpSchedule("TERMINATION DATE ADJUSTED", schedule)

    d1 = Date(20, 6, 2018)
    d2 = Date(20, 6, 2020)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    termination_dateAdjust = True
    eomFlag = True

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust, eomFlag)

    dumpSchedule("END OF MONTH - NOT EOM TERM DATE - USING MOD FOLL", schedule)

    d1 = Date(30, 6, 2018)
    d2 = Date(30, 6, 2020)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    calendar_type = CalendarTypes.WEEKEND
    bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    termination_dateAdjust = True
    eomFlag = True

    schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type,
                        date_gen_rule_type, termination_dateAdjust, eomFlag)

    dumpSchedule("END OF MONTH - EOM TERM DATE - USING MOD FOLL", schedule)
Esempio n. 24
0
def buildFullIssuerCurve1(mktSpreadBump, irBump):

    # https://www.markit.com/markit.jsp?jsppage=pv.jsp
    # YIELD CURVE 8-AUG-2019 SNAP AT 1600

    tradeDate = Date(9, 8, 2019)
    valuation_date = tradeDate.add_days(1)

    m = 1.0  # 0.00000000000

    dcType = DayCountTypes.ACT_360
    depos = []
    depo1 = IborDeposit(valuation_date, "1D", m * 0.0220, dcType)
    depos.append(depo1)

    spot_days = 2
    settlement_date = valuation_date.add_days(spot_days)

    maturity_date = settlement_date.add_months(1)
    depo1 = IborDeposit(settlement_date, maturity_date, m * 0.022009, dcType)

    maturity_date = settlement_date.add_months(2)
    depo2 = IborDeposit(settlement_date, maturity_date, m * 0.022138, dcType)

    maturity_date = settlement_date.add_months(3)
    depo3 = IborDeposit(settlement_date, maturity_date, m * 0.021810, dcType)

    maturity_date = settlement_date.add_months(6)
    depo4 = IborDeposit(settlement_date, maturity_date, m * 0.020503, dcType)

    maturity_date = settlement_date.add_months(12)
    depo5 = IborDeposit(settlement_date, maturity_date, m * 0.019930, dcType)

    depos.append(depo1)
    depos.append(depo2)
    depos.append(depo3)
    depos.append(depo4)
    depos.append(depo5)

    fras = []

    swaps = []
    dcType = DayCountTypes.THIRTY_E_360_ISDA
    fixedFreq = FrequencyTypes.SEMI_ANNUAL

    maturity_date = settlement_date.add_months(24)
    swap1 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.015910 + irBump, fixedFreq, dcType)
    swaps.append(swap1)

    maturity_date = settlement_date.add_months(36)
    swap2 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.014990 + irBump, fixedFreq, dcType)
    swaps.append(swap2)

    maturity_date = settlement_date.add_months(48)
    swap3 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.014725 + irBump, fixedFreq, dcType)
    swaps.append(swap3)

    maturity_date = settlement_date.add_months(60)
    swap4 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.014640 + irBump, fixedFreq, dcType)
    swaps.append(swap4)

    maturity_date = settlement_date.add_months(72)
    swap5 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.014800 + irBump, fixedFreq, dcType)
    swaps.append(swap5)

    maturity_date = settlement_date.add_months(84)
    swap6 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.014995 + irBump, fixedFreq, dcType)
    swaps.append(swap6)

    maturity_date = settlement_date.add_months(96)
    swap7 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.015180 + irBump, fixedFreq, dcType)
    swaps.append(swap7)

    maturity_date = settlement_date.add_months(108)
    swap8 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.015610 + irBump, fixedFreq, dcType)
    swaps.append(swap8)

    maturity_date = settlement_date.add_months(120)
    swap9 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.015880 + irBump, fixedFreq, dcType)
    swaps.append(swap9)

    maturity_date = settlement_date.add_months(144)
    swap10 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                      m * 0.016430 + irBump, fixedFreq, dcType)
    swaps.append(swap10)

    libor_curve = IborSingleCurve(valuation_date, depos, fras, swaps)

    cdsMarketContracts = []

    cdsCoupon = 0.04 + mktSpreadBump

    maturity_date = valuation_date.next_cds_date(6)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(12)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(24)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(36)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(48)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(60)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(84)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(120)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    maturity_date = valuation_date.next_cds_date(180)
    cds = CDS(valuation_date, maturity_date, cdsCoupon)
    cdsMarketContracts.append(cds)

    recovery_rate = 0.40

    issuer_curve = CDSCurve(valuation_date, cdsMarketContracts, libor_curve,
                            recovery_rate)

    return libor_curve, issuer_curve
Esempio n. 25
0
def test_BondOption():

    settlement_date = Date(1, 12, 2019)
    issue_date = Date(1, 12, 2018)
    maturity_date = settlement_date.add_tenor("10Y")
    coupon = 0.05
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    tmat = (maturity_date - settlement_date) / gDaysInYear
    times = np.linspace(0, tmat, 20)
    dates = settlement_date.add_years(times)
    dfs = np.exp(-0.05*times)
    discount_curve = DiscountCurve(settlement_date, dates, dfs)

    expiry_date = settlement_date.add_tenor("18m")
    strike_price = 105.0
    face = 100.0

    ###########################################################################

    strikes = [80, 85, 90, 95, 100, 105, 110, 115, 120]

    option_type = OptionTypes.EUROPEAN_CALL

    testCases.header("LABEL", "VALUE")

    price = bond.full_price_from_discount_curve(
        settlement_date, discount_curve)
    testCases.print("Fixed Income Price:", price)

    num_time_steps = 20

    testCases.header("OPTION TYPE AND MODEL", "STRIKE", "VALUE")

    for strike_price in strikes:

        sigma = 0.20
        a = 0.1

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a, num_time_steps)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN CALL - BK", strike_price, v)

    for strike_price in strikes:

        sigma = 0.20
        a = 0.05

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a, num_time_steps)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN CALL - BK", strike_price, v)

    ###########################################################################

    option_type = OptionTypes.AMERICAN_CALL

    price = bond.full_price_from_discount_curve(
        settlement_date, discount_curve)
    testCases.header("LABEL", "VALUE")
    testCases.print("Fixed Income Price:", price)

    testCases.header("OPTION TYPE AND MODEL", "STRIKE", "VALUE")

    for strike_price in strikes:

        sigma = 0.01
        a = 0.1

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN CALL - BK", strike_price, v)

    for strike_price in strikes:

        sigma = 0.20
        a = 0.05

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN CALL - BK", strike_price, v)

    ###########################################################################

    option_type = OptionTypes.EUROPEAN_PUT

    price = bond.full_price_from_discount_curve(
        settlement_date, discount_curve)

    for strike_price in strikes:

        sigma = 0.01
        a = 0.1

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN PUT - BK", strike_price, v)

    for strike_price in strikes:

        sigma = 0.20
        a = 0.05

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN PUT - BK", strike_price, v)

    ###########################################################################

    option_type = OptionTypes.AMERICAN_PUT

    price = bond.full_price_from_discount_curve(
        settlement_date, discount_curve)

    for strike_price in strikes:

        sigma = 0.02
        a = 0.1

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN PUT - BK", strike_price, v)

    for strike_price in strikes:

        sigma = 0.20
        a = 0.05

        bond_option = BondOption(
            bond, expiry_date, strike_price, face, option_type)
        model = BKTree(sigma, a)
        v = bond_option.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN PUT - BK", strike_price, v)
Esempio n. 26
0
def test_full_priceCDS1():

    mktSpread = 0.040

    testCases.header("Example", "Markit 9 Aug 2019")

    libor_curve, issuer_curve = buildFullIssuerCurve1(0.0, 0.0)

    # This is the 10 year contract at an off market coupon
    maturity_date = Date(20, 6, 2029)
    cdsCoupon = 0.0150
    notional = ONE_MILLION
    long_protection = True
    tradeDate = Date(9, 8, 2019)
    valuation_date = tradeDate.add_days(1)
    effective_date = valuation_date

    cds_contract = CDS(effective_date, maturity_date, cdsCoupon, notional,
                       long_protection)

    cdsRecovery = 0.40

    testCases.header("LABEL", "VALUE")
    spd = cds_contract.par_spread(valuation_date, issuer_curve,
                                  cdsRecovery) * 10000.0
    testCases.print("PAR_SPREAD", spd)

    v = cds_contract.value(valuation_date, issuer_curve, cdsRecovery)
    testCases.print("FULL_VALUE", v['full_pv'])
    testCases.print("CLEAN_VALUE", v['clean_pv'])

    p = cds_contract.clean_price(valuation_date, issuer_curve, cdsRecovery)
    testCases.print("CLEAN_PRICE", p)

    # MARKIT PRICE IS 168517

    accrued_days = cds_contract.accrued_days()
    testCases.print("ACCRUED_DAYS", accrued_days)

    accrued_interest = cds_contract.accrued_interest()
    testCases.print("ACCRUED_COUPON", accrued_interest)

    prot_pv = cds_contract.protection_leg_pv(valuation_date, issuer_curve,
                                             cdsRecovery)
    testCases.print("PROTECTION_PV", prot_pv)

    premPV = cds_contract.premium_leg_pv(valuation_date, issuer_curve,
                                         cdsRecovery)
    testCases.print("PREMIUM_PV", premPV)

    fullRPV01, cleanRPV01 = cds_contract.risky_pv01(valuation_date,
                                                    issuer_curve)
    testCases.print("FULL_RPV01", fullRPV01)
    testCases.print("CLEAN_RPV01", cleanRPV01)

    # cds_contract.print_flows(issuer_curve)

    bump = 1.0 / 10000.0  # 1 bp

    libor_curve, issuer_curve = buildFullIssuerCurve1(bump, 0)
    v_bump = cds_contract.value(valuation_date, issuer_curve, cdsRecovery)
    dv = v_bump['full_pv'] - v['full_pv']
    testCases.print("CREDIT_DV01", dv)

    # Interest Rate Bump
    libor_curve, issuer_curve = buildFullIssuerCurve1(0, bump)
    v_bump = cds_contract.value(valuation_date, issuer_curve, cdsRecovery)
    dv = v_bump['full_pv'] - v['full_pv']
    testCases.print("INTEREST_DV01", dv)

    t = (maturity_date - valuation_date) / gDaysInYear
    z = libor_curve.df(maturity_date)
    r = -np.log(z) / t

    v_approx = cds_contract.value_fast_approx(valuation_date, r, mktSpread,
                                              cdsRecovery)

    testCases.print("FULL APPROX VALUE", v_approx[0])
    testCases.print("CLEAN APPROX VALUE", v_approx[1])
    testCases.print("APPROX CREDIT DV01", v_approx[2])
    testCases.print("APPROX INTEREST DV01", v_approx[3])
def test_FinOptionImpliedDbn():

    if 1 == 1:

        # Example from Book extract by Iain Clark using Tables 3.3 and 3.4
        # print("EURUSD EXAMPLE CLARK")

        valuation_date = Date(10, 4, 2020)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.03460  # EUR
        domCCRate = 0.02940  # USD

        dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
        for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

        currency_pair = forName + domName
        spot_fx_rate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atm_vols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
        marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
        riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]

        notional_currency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA

        fxMarket = FXVolSurface(valuation_date, spot_fx_rate, currency_pair,
                                notional_currency, dom_discount_curve,
                                for_discount_curve, tenors, atm_vols,
                                marketStrangle25DeltaVols,
                                riskReversal25DeltaVols, atmMethod,
                                deltaMethod)

        #        fxMarket.check_calibration(True)

        PLOT_GRAPHS = False
        if PLOT_GRAPHS:
            fxMarket.plot_vol_curves()

        for iTenor in range(0, len(fxMarket._tenors)):

            F = fxMarket._F0T[iTenor]
            texp = fxMarket._texp[iTenor]

            startFX = F * 0.05
            endFX = F * 5.0

            num_steps = 10000
            dFX = (endFX - startFX) / num_steps

            domDF = dom_discount_curve._df(texp)
            forDF = for_discount_curve._df(texp)

            rd = -np.log(domDF) / texp
            rf = -np.log(forDF) / texp

            params = fxMarket._parameters[iTenor]

            strikes = []
            vols = []

            for iK in range(0, num_steps):
                strike = startFX + iK * dFX
                vol = vol_function_clark(params, F, strike, texp)
                strikes.append(strike)
                vols.append(vol)

            strikes = np.array(strikes)
            vols = np.array(vols)
Esempio n. 28
0
def buildFullIssuerCurve2(mktSpreadBump, irBump):

    # https://www.markit.com/markit.jsp?jsppage=pv.jsp
    # YIELD CURVE 20 August 2020 SNAP AT 1600

    m = 1.0

    valuation_date = Date(24, 8, 2020)
    settlement_date = Date(24, 8, 2020)
    dcType = DayCountTypes.ACT_360
    depos = []

    maturity_date = settlement_date.add_months(1)
    depo1 = IborDeposit(settlement_date, maturity_date, m * 0.001709, dcType)

    maturity_date = settlement_date.add_months(2)
    depo2 = IborDeposit(settlement_date, maturity_date, m * 0.002123, dcType)

    maturity_date = settlement_date.add_months(3)
    depo3 = IborDeposit(settlement_date, maturity_date, m * 0.002469, dcType)

    maturity_date = settlement_date.add_months(6)
    depo4 = IborDeposit(settlement_date, maturity_date, m * 0.003045, dcType)

    maturity_date = settlement_date.add_months(12)
    depo5 = IborDeposit(settlement_date, maturity_date, m * 0.004449, dcType)

    depos.append(depo1)
    depos.append(depo2)
    depos.append(depo3)
    depos.append(depo4)
    depos.append(depo5)

    swaps = []
    dcType = DayCountTypes.THIRTY_E_360_ISDA
    fixedFreq = FrequencyTypes.SEMI_ANNUAL

    maturity_date = settlement_date.add_months(24)
    swap1 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.002155 + irBump, fixedFreq, dcType)
    swaps.append(swap1)

    maturity_date = settlement_date.add_months(36)
    swap2 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.002305 + irBump, fixedFreq, dcType)
    swaps.append(swap2)

    maturity_date = settlement_date.add_months(48)
    swap3 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.002665 + irBump, fixedFreq, dcType)
    swaps.append(swap3)

    maturity_date = settlement_date.add_months(60)
    swap4 = IborSwap(settlement_date, maturity_date, SwapTypes.PAY,
                     m * 0.003290 + irBump, fixedFreq, dcType)
    swaps.append(swap4)

    libor_curve = IborSingleCurve(valuation_date, depos, [], swaps)

    cdsCoupon = 0.01 + mktSpreadBump

    cdsMarketContracts = []
    effective_date = Date(21, 8, 2020)
    cds = CDS(effective_date, "6M", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = CDS(effective_date, "1Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = CDS(effective_date, "2Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = CDS(effective_date, "3Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = CDS(effective_date, "4Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = CDS(effective_date, "5Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = CDS(effective_date, "7Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = CDS(effective_date, "10Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    recovery_rate = 0.40

    issuer_curve = CDSCurve(settlement_date, cdsMarketContracts, libor_curve,
                            recovery_rate)

    testCases.header("DATE", "DISCOUNT_FACTOR", "SURV_PROB")
    years = np.linspace(0.0, 10.0, 20)
    dates = settlement_date.add_years(years)
    for dt in dates:
        df = libor_curve.df(dt)
        q = issuer_curve.survival_prob(dt)
        testCases.print("%16s" % dt, "%12.8f" % df, "%12.8f" % q)

    return libor_curve, issuer_curve
def test_FinSwaptionVolSurface1(verboseCalibration):

    ###########################################################################

    if 1 == 1:

        # https://fr.mathworks.com/help/fininst/pricing-a-swaption-using-the-sabr-model.html

        valuation_date = Date(12, 6, 2013)

        # These are 3M, 1Y, 2Y, 3Y, 4Y, 5Y, 7Y, 10Y
        exerciseDates = [Date(12, 9, 2013), Date(12, 6, 2014),
                         Date(12, 6, 2015), Date(12, 6, 2016),
                         Date(12, 6, 2017), Date(12, 6, 2018),
                         Date(12, 6, 2020), Date(12, 6, 2023)]

        # First dimension is the strike, then the expiry date
        marketVolatilities = [[57.6, 53.7, 49.4, 45.6, 44.1, 41.1, 35.2, 32.0],
                              [46.6, 46.9, 44.8, 41.6, 39.8, 37.4, 33.4, 31.0],
                              [35.9, 39.3, 39.6, 37.9, 37.2, 34.7, 30.5, 28.9],
                              [34.1, 36.5, 37.8, 36.6, 35.0, 31.9, 28.1, 26.6],
                              [41.0, 41.3, 39.5, 37.8, 36.0, 32.6, 29.0, 26.0],
                              [45.8, 43.4, 41.9, 39.2, 36.9, 33.2, 29.6, 26.3],
                              [50.3, 46.9, 44.0, 40.0, 37.5, 33.8, 30.2, 27.3]]
        
        marketVolatilities = np.array(marketVolatilities) / 100.0

        # First dimension is the strike, then the expiry date
        marketStrikes = [[1.00, 1.25, 1.68, 2.00, 2.26, 2.41, 2.58, 2.62],
                         [1.50, 1.75, 2.18, 2.50, 2.76, 2.91, 3.08, 3.12],
                         [2.00, 2.25, 2.68, 3.00, 3.26, 3.41, 3.58, 3.62],
                         [2.50, 2.75, 3.18, 3.50, 3.76, 3.91, 4.08, 4.12],
                         [3.00, 3.25, 3.68, 4.00, 4.26, 4.41, 4.58, 4.62],
                         [3.50, 3.75, 4.18, 4.50, 4.76, 4.91, 5.08, 5.12],
                         [4.00, 4.25, 4.68, 5.00, 5.26, 5.41, 5.58, 5.62]]
        
        marketStrikes = np.array(marketStrikes) / 100.0
        
        fwdSwapRates = marketStrikes[3]
        atmVols = marketVolatilities[3]

        rfrRate = 0.020  # USD
        discount_curve = DiscountCurveFlat(valuation_date, rfrRate)

        divRate = 0.010  # USD
        dividendCurve = DiscountCurveFlat(valuation_date, divRate)

        volFunctionType = FinVolFunctionTypes.SABR_BETA_HALF

        swaptionSurface = FinSwaptionVolSurface(valuation_date,
                                                exerciseDates,
                                                fwdSwapRates,
                                                marketStrikes,
                                                marketVolatilities,
                                                volFunctionType)

        tol = 1e-4
        swaptionSurface.checkCalibration(False, tol)

        if 1==1: # PLOT_GRAPHS:

            swaptionSurface.plotVolCurves()
Esempio n. 30
0
def test_full_priceCDSModelCheck():

    testCases.print("Example", "MARKIT CHECK 19 Aug 2020")

    libor_curve, issuer_curve = buildFullIssuerCurve2(0.0, 0.0)

    # This is the 10 year contract at an off market coupon
    maturity_date = Date(20, 6, 2025)
    cdsCoupon = 0.050
    notional = ONE_MILLION
    long_protection = True
    tradeDate = Date(20, 8, 2020)
    effective_date = Date(21, 8, 2020)
    valuation_date = tradeDate

    cds_contract = CDS(effective_date, maturity_date, cdsCoupon, notional,
                       long_protection)

    cdsRecovery = 0.40

    testCases.header("LABEL", "VALUE")
    spd = cds_contract.par_spread(valuation_date, issuer_curve,
                                  cdsRecovery) * 10000.0
    testCases.print("PAR_SPREAD", spd)

    v = cds_contract.value(valuation_date, issuer_curve, cdsRecovery)
    testCases.print("FULL_VALUE", v['full_pv'])
    testCases.print("CLEAN_VALUE", v['clean_pv'])

    p = cds_contract.clean_price(valuation_date, issuer_curve, cdsRecovery)
    testCases.print("CLEAN_PRICE", p)

    accrued_days = cds_contract.accrued_days()
    testCases.print("ACCRUED_DAYS", accrued_days)

    accrued_interest = cds_contract.accrued_interest()
    testCases.print("ACCRUED_COUPON", accrued_interest)

    prot_pv = cds_contract.protection_leg_pv(valuation_date, issuer_curve,
                                             cdsRecovery)
    testCases.print("PROTECTION_PV", prot_pv)

    premPV = cds_contract.premium_leg_pv(valuation_date, issuer_curve,
                                         cdsRecovery)
    testCases.print("PREMIUM_PV", premPV)

    rpv01 = cds_contract.risky_pv01(valuation_date, issuer_curve)
    testCases.print("FULL_RPV01", rpv01['full_rpv01'])
    testCases.print("CLEAN_RPV01", rpv01['clean_rpv01'])

    credit_dv01 = cds_contract.credit_dv01(valuation_date, issuer_curve,
                                           cdsRecovery)
    testCases.print("CREDIT DV01", credit_dv01)

    interest_dv01 = cds_contract.interest_dv01(valuation_date, issuer_curve,
                                               cdsRecovery)
    testCases.print("INTEREST DV01", interest_dv01)

    # Consider fast approximation
    t = (maturity_date - valuation_date) / gDaysInYear
    z = libor_curve.df(maturity_date)
    r = -np.log(z) / t

    mktSpread = 0.01
    v_approx = cds_contract.value_fast_approx(valuation_date, r, mktSpread,
                                              cdsRecovery)

    testCases.header("FAST VALUATIONS", "VALUE")

    testCases.print("FULL APPROX VALUE", v_approx[0])
    testCases.print("CLEAN APPROX VALUE", v_approx[1])
    testCases.print("APPROX CREDIT DV01", v_approx[2])
    testCases.print("APPROX INTEREST DV01", v_approx[3])