Example #1
0
def test_BlackKarasinskiExampleTwo():
    # 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

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

    bond.calculateFlowDates(settlementDate)
    couponTimes = []
    couponFlows = []
    cpn = bond._coupon / bond._frequency
    for flowDate in bond._flowDates:
        flowTime = (flowDate - settlementDate) / gDaysInYear
        couponTimes.append(flowTime)
        couponFlows.append(cpn)

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

    strikePrice = 105.0
    face = 100.0

    tmat = (maturityDate - settlementDate) / gDaysInYear
    texp = (expiryDate - settlementDate) / gDaysInYear
    times = np.linspace(0, tmat, 20)
    dfs = np.exp(-0.05 * times)
    curve = FinDiscountCurve(settlementDate, times, dfs)

    price = bond.fullPriceFromDiscountCurve(settlementDate, curve)
    print("Fixed Income Price:", price)

    sigma = 0.20
    a = 0.05

    # Test convergence
    numStepsList = [100]  #,101,200,300,400,500,600,700,800,900,1000]
    isAmerican = True

    treeVector = []
    for numTimeSteps in numStepsList:
        start = time.time()
        model = FinModelRatesBlackKarasinski(a, sigma)
        model.buildTree(tmat, int(numTimeSteps), times, dfs)
        v = model.bondOption(texp, strikePrice, face, couponTimes, couponFlows,
                             isAmerican)
        end = time.time()
        period = end - start
        treeVector.append(v[0])
        print(numTimeSteps, v, period)
Example #2
0
def test_HullWhiteBondOption():
    # Valuation of a European option on a coupon bearing bond

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

    bond.calculateFlowDates(settlementDate)
    couponTimes = []
    couponFlows = []
    cpn = bond._coupon / bond._frequency
    for flowDate in bond._flowDates[1:]:
        flowTime = (flowDate - settlementDate) / gDaysInYear
        couponTimes.append(flowTime)
        couponFlows.append(cpn)
    couponTimes = np.array(couponTimes)
    couponFlows = np.array(couponFlows)

    strikePrice = 105.0
    face = 100.0

    tmat = (maturityDate - settlementDate) / gDaysInYear
    times = np.linspace(0, tmat, 20)
    dfs = np.exp(-0.05 * times)
    curve = FinDiscountCurve(settlementDate, times, dfs)

    price = bond.fullPriceFromDiscountCurve(settlementDate, curve)
    print("Spot Bond Price:", price)

    price = bond.fullPriceFromDiscountCurve(expiryDate, curve)
    print("Fwd Bond Price:", price)

    sigma = 0.01
    a = 0.1

    # Test convergence
    numStepsList = [100, 200, 300, 400, 500]
    texp = (expiryDate - settlementDate) / gDaysInYear

    print("NUMSTEPS", "FAST TREE", "FULLTREE", "TIME")

    for numTimeSteps in numStepsList:
        start = time.time()
        model = FinModelRatesHullWhite(a, sigma)
        model.buildTree(texp, numTimeSteps, times, dfs)

        americanExercise = False
        v1 = model.americanBondOption_Tree(texp, strikePrice, face,
                                           couponTimes, couponFlows,
                                           americanExercise)

        v2 = model.europeanBondOption_Tree(texp, strikePrice, face,
                                           couponTimes, couponFlows)

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

        print(numTimeSteps, v1, v2, period)

#    plt.plot(numStepsList, treeVector)

    if 1 == 0:
        print("RT")
        printTree(model._rt, 5)
        print("BOND")
        printTree(model._bondValues, 5)
        print("OPTION")
        printTree(model._optionValues, 5)

    v = model.europeanBondOption_Jamshidian(texp, strikePrice, face,
                                            couponTimes, couponFlows, times,
                                            dfs)

    print("EUROPEAN BOND JAMSHIDIAN DECOMP", v)
Example #3
0
def test_HullWhiteCallableBond():
    # Valuation of a European option on a coupon bearing bond

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

    bond.calculateFlowDates(settlementDate)
    couponTimes = []
    couponFlows = []
    cpn = bond._coupon / bond._frequency
    for flowDate in bond._flowDates[1:]:
        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("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("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
    times = np.linspace(0, tmat, 20)
    dfs = np.exp(-0.05 * times)
    curve = FinDiscountCurve(settlementDate, times, dfs)

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

    v1 = bond.fullPriceFromDiscountCurve(settlementDate, curve)

    sigma = 0.02  # basis point volatility
    a = 0.1

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

    print("NUMSTEPS", "BOND_ONLY", "CALLABLE_BOND", "TIME")

    for numTimeSteps in numStepsList:
        start = time.time()
        model = FinModelRatesHullWhite(a, sigma)
        model.buildTree(tmat, numTimeSteps, times, dfs)

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

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

    if 1 == 0:
        print("RT")
        printTree(model._rt, 5)
        print("BOND")
        printTree(model._bondValues, 5)
        print("OPTION")
        printTree(model._optionValues, 5)