Example #1
0
def test_FinFlatCurve():

    curveDate = FinDate(1, 1, 2019)
    months = range(1, 60, 3)
    dates = curveDate.addMonths(months)
    testCases.header("COMPOUNDING", "DFS")
    compounding = FinFrequencyTypes.CONTINUOUS

    flatCurve = FinDiscountCurveFlat(curveDate, 0.05, compounding)
    dfs = flatCurve.df(dates)
    testCases.print(compounding, dfs)

    compounding = FinFrequencyTypes.ANNUAL
    flatCurve = FinDiscountCurveFlat(curveDate, 0.05, compounding)
    dfs = flatCurve.df(dates)
    testCases.print(compounding, dfs)

    compounding = FinFrequencyTypes.SEMI_ANNUAL
    flatCurve = FinDiscountCurveFlat(curveDate, 0.05, compounding)
    dfs = flatCurve.df(dates)
    testCases.print(compounding, dfs)

    compounding = FinFrequencyTypes.QUARTERLY
    flatCurve = FinDiscountCurveFlat(curveDate, 0.05, compounding)
    dfs = flatCurve.df(dates)
    testCases.print(compounding, dfs)

    compounding = FinFrequencyTypes.MONTHLY
    flatCurve = FinDiscountCurveFlat(curveDate, 0.05, compounding)
    dfs = flatCurve.df(dates)
    testCases.print(compounding, dfs)
Example #2
0
def test_FinBondOptionZEROVOLConvergence():

    # Build discount curve
    settlementDate = FinDate(1, 12, 2019)  # CHANGED
    rate = 0.05
    discountCurve = FinDiscountCurveFlat(settlementDate, rate,
                                         FinFrequencyTypes.ANNUAL)

    # Bond details
    issueDate = FinDate(1, 9, 2015)
    maturityDate = FinDate(1, 9, 2025)
    coupon = 0.06
    freqType = FinFrequencyTypes.ANNUAL
    accrualType = FinDayCountTypes.ACT_ACT_ICMA
    bond = FinBond(issueDate, maturityDate, coupon, freqType, accrualType)

    # Option Details
    expiryDate = settlementDate.addTenor("18m")  # FinDate(1, 12, 2021)
    #    print("EXPIRY:", expiryDate)
    face = 100.0

    dfExpiry = discountCurve.df(expiryDate)
    spotCleanValue = bond.cleanPriceFromDiscountCurve(settlementDate,
                                                      discountCurve)
    fwdCleanValue = bond.cleanPriceFromDiscountCurve(expiryDate, discountCurve)
    #    print("BOND SpotCleanBondPx", spotCleanValue)
    #    print("BOND FwdCleanBondPx", fwdCleanValue)
    #    print("BOND Accrued:", bond._accruedInterest)

    spotCleanValue = bond.cleanPriceFromDiscountCurve(settlementDate,
                                                      discountCurve)

    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, 200)
    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 numSteps in numTimeSteps:

            sigma = 0.0000001
            model = FinModelRatesBDT(sigma, numSteps)

            optionType = FinOptionTypes.EUROPEAN_CALL
            bondOption1 = FinBondOption(bond, expiryDate, strikePrice, face,
                                        optionType)
            v1 = bondOption1.value(settlementDate, discountCurve, model)

            optionType = FinOptionTypes.AMERICAN_CALL
            bondOption2 = FinBondOption(bond, expiryDate, strikePrice, face,
                                        optionType)
            v2 = bondOption2.value(settlementDate, discountCurve, model)

            optionType = FinOptionTypes.EUROPEAN_PUT
            bondOption3 = FinBondOption(bond, expiryDate, strikePrice, face,
                                        optionType)
            v3 = bondOption3.value(settlementDate, discountCurve, model)

            optionType = FinOptionTypes.AMERICAN_PUT
            bondOption4 = FinBondOption(bond, expiryDate, strikePrice, face,
                                        optionType)
            v4 = bondOption4.value(settlementDate, discountCurve, model)

            testCases.print(strikePrice, numSteps, callIntrinsic,
                            callIntrinsicPV, v1, v2, putIntrinsic,
                            putIntrinsicPV, v3, v4)
def test_HullWhiteCallableBond():
    # Valuation of a European option on a coupon bearing bond

    settlementDate = FinDate(1, 12, 2019)
    issueDate = FinDate(1, 12, 2018)
    maturityDate = settlementDate.addTenor("10Y")
    coupon = 0.05
    frequencyType = FinFrequencyTypes.SEMI_ANNUAL
    accrualType = FinDayCountTypes.ACT_ACT_ICMA
    bond = FinBond(issueDate, maturityDate, coupon, frequencyType, accrualType)

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

    for flowDate in bond._flowDates[1:]:

        if flowDate > settlementDate:
            flowTime = (flowDate - settlementDate) / gDaysInYear
            couponTimes.append(flowTime)
            couponFlows.append(cpn)

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

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

    callDates = []
    callPrices = []
    callPx = 120.0
    callDates.append(settlementDate.addTenor("2Y"))
    callPrices.append(callPx)
    callDates.append(settlementDate.addTenor("3Y"))
    callPrices.append(callPx)
    callDates.append(settlementDate.addTenor("4Y"))
    callPrices.append(callPx)
    callDates.append(settlementDate.addTenor("5Y"))
    callPrices.append(callPx)
    callDates.append(settlementDate.addTenor("6Y"))
    callPrices.append(callPx)
    callDates.append(settlementDate.addTenor("7Y"))
    callPrices.append(callPx)
    callDates.append(settlementDate.addTenor("8Y"))
    callPrices.append(callPx)

    callTimes = []
    for dt in callDates:
        t = (dt - settlementDate) / gDaysInYear
        callTimes.append(t)

    putDates = []
    putPrices = []
    putPx = 98.0
    putDates.append(settlementDate.addTenor("2Y"))
    putPrices.append(putPx)
    putDates.append(settlementDate.addTenor("3Y"))
    putPrices.append(putPx)
    putDates.append(settlementDate.addTenor("4Y"))
    putPrices.append(putPx)
    putDates.append(settlementDate.addTenor("5Y"))
    putPrices.append(putPx)
    putDates.append(settlementDate.addTenor("6Y"))
    putPrices.append(putPx)
    putDates.append(settlementDate.addTenor("7Y"))
    putPrices.append(putPx)
    putDates.append(settlementDate.addTenor("8Y"))
    putPrices.append(putPx)

    putTimes = []
    for dt in putDates:
        t = (dt - settlementDate) / gDaysInYear
        putTimes.append(t)

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

    tmat = (maturityDate - settlementDate) / gDaysInYear
    curve = FinDiscountCurveFlat(settlementDate, 0.05,
                                 FinFrequencyTypes.CONTINUOUS)

    dfs = []
    times = []

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

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

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

    v1 = bond.cleanPriceFromDiscountCurve(settlementDate, curve)

    sigma = 0.02  # basis point volatility
    a = 0.01

    # Test convergence
    numStepsList = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
    tmat = (maturityDate - settlementDate) / gDaysInYear

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

    for numTimeSteps in numStepsList:

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

        v2 = model.callablePuttableBond_Tree(couponTimes, couponFlows,
                                             callTimes, callPrices, putTimes,
                                             putPrices, 100.0)

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