Exemple #1
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)
Exemple #2
0
def test_BondOptionDerivaGem():

    # See https://github.com/domokane/FinancePy/issues/98

    settlement_date = Date(1, 12, 2019)

    rate = 0.05
    dcType = DayCountTypes.THIRTY_360_BOND
    fixedFreq = FrequencyTypes.SEMI_ANNUAL
    discount_curve = DiscountCurveFlat(settlement_date, rate, fixedFreq,
                                       dcType)

    issue_date = Date(1, 12, 2018)
    expiry_date = settlement_date.add_tenor("18m")
    maturity_date = settlement_date.add_tenor("10Y")

    coupon = 0.05
    freqType = FrequencyTypes.SEMI_ANNUAL
    accrualType = DayCountTypes.THIRTY_360_BOND
    bond = Bond(issue_date, maturity_date, coupon, freqType, accrualType)
    strike_price = 100.0
    face = 100.0

    europeanCallBondOption = BondOption(bond, expiry_date, strike_price, face,
                                        OptionTypes.EUROPEAN_CALL)
    cp = bond.clean_price_from_discount_curve(expiry_date, discount_curve)
    fp = bond.full_price_from_discount_curve(expiry_date, discount_curve)
    #    print("Fixed Income Clean Price: %9.3f"% cp)
    #    print("Fixed Income Full  Price: %9.3f"% fp)

    num_steps = 500
    sigma = 0.0125
    a = 0.1
    modelHW = HWTree(sigma, a, num_steps)

    ec = europeanCallBondOption.value(settlement_date, discount_curve, modelHW)

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

    couponTimes = []
    couponFlows = []
    cpn = bond._coupon / bond._frequency

    numFlows = len(bond._flow_dates)
    for i in range(0, numFlows):

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

        if ncd > settlement_date:

            if len(couponTimes) == 0:
                flowTime = (pcd - settlement_date) / gDaysInYear
                couponTimes.append(flowTime)
                couponFlows.append(cpn)

            flowTime = (ncd - settlement_date) / gDaysInYear
            couponTimes.append(flowTime)
            couponFlows.append(cpn)

    couponTimes = np.array(couponTimes)
    couponFlows = np.array(couponFlows)

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

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

    #  Test convergence
    texp = (expiry_date - settlement_date) / gDaysInYear
    tmat = (maturity_date - settlement_date) / gDaysInYear

    # Jamshidian approach
    vjam = model.european_bond_option_jamshidian(texp, strike_price, face,
                                                 couponTimes, couponFlows,
                                                 times, dfs)
    # print("Jamshidian:", vjam)

    model._num_time_steps = 100
    model.build_tree(tmat, times, dfs)
    exerciseType = FinExerciseTypes.EUROPEAN

    vHW = model.bond_option(texp, strike_price, face, couponTimes, couponFlows,
                            exerciseType)