Пример #1
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._accruedInterest)

    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")

    numTimeSteps = range(100, 1000, 100)
    strikePrices = [90, 100, 110, 120]

    for strikePrice in strikePrices:

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

        for num_steps in numTimeSteps:

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

            optionType = FinOptionTypes.EUROPEAN_CALL
            bondOption1 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v1 = bondOption1.value(settlement_date, discount_curve, model)

            optionType = FinOptionTypes.AMERICAN_CALL
            bondOption2 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v2 = bondOption2.value(settlement_date, discount_curve, model)

            optionType = FinOptionTypes.EUROPEAN_PUT
            bondOption3 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v3 = bondOption3.value(settlement_date, discount_curve, model)

            optionType = FinOptionTypes.AMERICAN_PUT
            bondOption4 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v4 = bondOption4.value(settlement_date, discount_curve, model)

            testCases.print(strikePrice, num_steps, callIntrinsic,
                            callIntrinsicPV, v1, v2, putIntrinsic,
                            putIntrinsicPV, v3, v4)
Пример #2
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.addTenor("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 flowDate in bond._flow_dates[1:]:
        
        if flowDate > settlement_date:
            flow_time = (flowDate - 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.addTenor("2Y")); call_prices.append(callPx)
    call_dates.append(settlement_date.addTenor("3Y")); call_prices.append(callPx)
    call_dates.append(settlement_date.addTenor("4Y")); call_prices.append(callPx)
    call_dates.append(settlement_date.addTenor("5Y")); call_prices.append(callPx)
    call_dates.append(settlement_date.addTenor("6Y")); call_prices.append(callPx)
    call_dates.append(settlement_date.addTenor("7Y")); call_prices.append(callPx)
    call_dates.append(settlement_date.addTenor("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.addTenor("2Y")); put_prices.append(putPx)
    put_dates.append(settlement_date.addTenor("3Y")); put_prices.append(putPx)
    put_dates.append(settlement_date.addTenor("4Y")); put_prices.append(putPx)
    put_dates.append(settlement_date.addTenor("5Y")); put_prices.append(putPx)
    put_dates.append(settlement_date.addTenor("6Y")); put_prices.append(putPx)
    put_dates.append(settlement_date.addTenor("7Y")); put_prices.append(putPx)
    put_dates.append(settlement_date.addTenor("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._flow_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_stepsList = [100, 200, 500, 1000]
    tmat = (maturity_date - settlement_date)/gDaysInYear

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

    for numTimeSteps in num_stepsList:

        start = time.time()
        model = FinModelRatesHW(sigma, a, numTimeSteps)
        model.buildTree(tmat, times, dfs)

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

        end = time.time()
        period = end-start
        testCases.print(numTimeSteps, period, v1, v2)