Exemple #1
0
def test_FinDateTenors():

    start_date = Date(23, 2, 2018)

    testCases.header("TENOR", "DATE")
    tenor = "5d"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "7D"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "1W"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "4W"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "1M"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "24M"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "2Y"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "10y"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "0m"
    testCases.print(tenor, start_date.addTenor(tenor))

    tenor = "20Y"
    testCases.print(tenor, start_date.addTenor(tenor))
Exemple #2
0
def test_DateTenors():

    startDate = Date(23, 2, 2018)

    tenor = "5d"
    print(tenor, startDate.addTenor(tenor))

    tenor = "7D"
    print(tenor, startDate.addTenor(tenor))

    tenor = "1W"
    print(tenor, startDate.addTenor(tenor))

    tenor = "4W"
    print(tenor, startDate.addTenor(tenor))

    tenor = "1M"
    print(tenor, startDate.addTenor(tenor))

    tenor = "24M"
    print(tenor, startDate.addTenor(tenor))

    tenor = "2Y"
    print(tenor, startDate.addTenor(tenor))

    tenor = "10y"
    print(tenor, startDate.addTenor(tenor))

    tenor = "0m"
    print(tenor, startDate.addTenor(tenor))

    tenor = "20Y"
    print(tenor, startDate.addTenor(tenor))
def test_BondMortgage():

    principal = 130000
    start_date = Date(23, 2, 2018)
    end_date = start_date.addTenor("10Y")
    mortgage = Mortgage(start_date, end_date, principal)

    rate = 0.035
    mortgage.generateFlows(rate, BondMortgageTypes.REPAYMENT)

    num_flows = len(mortgage._schedule._adjusted_dates)

    testCases.header("PAYMENT DATE", "INTEREST", "PRINCIPAL", "OUTSTANDING",
                     "TOTAL")

    for i in range(0, num_flows):
        testCases.print(mortgage._schedule._adjusted_dates[i],
                        mortgage._interestFlows[i],
                        mortgage._principalFlows[i],
                        mortgage._principalRemaining[i],
                        mortgage._totalFlows[i])

    mortgage.generateFlows(rate, BondMortgageTypes.INTEREST_ONLY)

    testCases.header("PAYMENT DATE", "INTEREST", "PRINCIPAL", "OUTSTANDING",
                     "TOTAL")

    for i in range(0, num_flows):
        testCases.print(mortgage._schedule._adjusted_dates[i],
                        mortgage._interestFlows[i],
                        mortgage._principalFlows[i],
                        mortgage._principalRemaining[i],
                        mortgage._totalFlows[i])
def test_FinScheduleAlignmentEff31():
    """ EOM schedule so all unadjusted dates fall on month end."""

    eomFlag = True
    valuation_date = Date(29, 7, 2006)
    effDate = valuation_date.addTenor("2D")
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    calendar_type = CalendarTypes.UNITED_STATES
    adjustTerminationDate = True

    matDate1 = effDate.addTenor("4Y")
    matDate2 = effDate.addTenor("50Y")

    #    print(matDate1, matDate2)

    sched1 = Schedule(effDate, matDate1, freq_type, calendar_type,
                      bus_day_adjust_type, date_gen_rule_type,
                      adjustTerminationDate, eomFlag)

    sched2 = Schedule(effDate, matDate2, freq_type, calendar_type,
                      bus_day_adjust_type, date_gen_rule_type,
                      adjustTerminationDate, eomFlag)

    #    print(sched1._adjusted_dates)
    #    print(sched2._adjusted_dates[:len(sched1._adjusted_dates)])

    compare = (sched1._adjusted_dates[-1] == sched2._adjusted_dates[
        len(sched1._adjusted_dates) - 1])
    assert (compare == True)
def test_FinScheduleAlignmentLeapYearEOM():
    """ Effective date on leap year."""

    valuation_date = Date(26, 2, 2006)
    effDate = valuation_date.addTenor("2D")
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    calendar_type = CalendarTypes.UNITED_STATES
    adjustTerminationDate = True

    matDate1 = effDate.addTenor("4Y")
    matDate2 = effDate.addTenor("50Y")
    eomFlag = True

    sched1 = Schedule(effDate, matDate1, freq_type, calendar_type,
                      bus_day_adjust_type, date_gen_rule_type,
                      adjustTerminationDate, eomFlag)

    sched2 = Schedule(effDate, matDate2, freq_type, calendar_type,
                      bus_day_adjust_type, date_gen_rule_type,
                      adjustTerminationDate, eomFlag)

    #    print(sched1._adjusted_dates)
    #    print(sched2._adjusted_dates[:len(sched1._adjusted_dates)])

    compare = (sched1._adjusted_dates[-1] == sched2._adjusted_dates[
        len(sched1._adjusted_dates) - 1])
    assert (compare == eomFlag)
def test_FinScheduleAlignment(eomFlag):

    valuation_date = Date(29, 3, 2005)
    effDate = valuation_date.addTenor("2d")
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    calendar_type = CalendarTypes.UNITED_STATES
    adjustTerminationDate = False

    matDate1 = effDate.addTenor("4Y")
    matDate2 = effDate.addTenor("50Y")

    #    print(matDate1)
    #    print(matDate2)

    myCal = Calendar(calendar_type)

    adjustedMatDate1 = myCal.adjust(matDate1, bus_day_adjust_type)
    adjustedMatDate2 = myCal.adjust(matDate2, bus_day_adjust_type)

    #    print(adjustedMatDate1)
    #    print(adjustedMatDate2)

    sched1 = Schedule(effDate, adjustedMatDate1, freq_type, calendar_type,
                      bus_day_adjust_type, date_gen_rule_type,
                      adjustTerminationDate, eomFlag)

    #    print(sched1)

    sched2 = Schedule(effDate, adjustedMatDate2, freq_type, calendar_type,
                      bus_day_adjust_type, date_gen_rule_type,
                      adjustTerminationDate, eomFlag)

    compare = (sched1._adjusted_dates[-1] == sched2._adjusted_dates[
        len(sched1._adjusted_dates) - 1])
    assert (compare == eomFlag)
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.addTenor("18m")
    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
    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 flowDate in bond._flow_dates:
        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)

    strikePrice = 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.addYears(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
    numTimeSteps = 26

    model = FinModelRatesBK(sigma, a, numTimeSteps)
    model.buildTree(tmat, times, dfs)
    exerciseType = FinExerciseTypes.AMERICAN
    v = model.bondOption(texp, strikePrice, face, coupon_times, coupon_flows,
                         exerciseType)

    # Test convergence
    num_stepsList = [100, 200, 300, 500, 1000]
    exerciseType = FinExerciseTypes.AMERICAN

    testCases.header("TIMESTEPS", "TIME", "VALUE")
    treeVector = []
    for numTimeSteps in num_stepsList:
        start = time.time()
        model = FinModelRatesBK(sigma, a, numTimeSteps)
        model.buildTree(tmat, times, dfs)
        v = model.bondOption(texp, strikePrice, face, coupon_times,
                             coupon_flows, exerciseType)
        end = time.time()
        period = end - start
        treeVector.append(v)
        testCases.print(numTimeSteps, period, v)

#    plt.plot(num_stepsList, treeVector)

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

    if 1 == 0:
        print("RT")
        printTree(model._rt, 5)
        print("Q")
        printTree(model._Q, 5)
Exemple #8
0
def test_BondOption():

    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)

    times = np.linspace(0, 10.0, 21)
    dfs = np.exp(-0.05 * times)
    dates = settlement_date.addYears(times)
    discount_curve = DiscountCurve(settlement_date, dates, dfs)

    expiry_date = settlement_date.addTenor("18m")
    strikePrice = 105.0
    face = 100.0

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

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

    optionType = FinOptionTypes.EUROPEAN_CALL

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

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

    numTimeSteps = 100

    testCases.banner("HW EUROPEAN CALL")
    testCases.header("STRIKE", "VALUE")

    for strikePrice in strikes:

        sigma = 0.01
        a = 0.1

        bondOption = BondOption(bond, expiry_date, strikePrice, face,
                                optionType)

        model = FinModelRatesHW(sigma, a, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print(strikePrice, v)

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

    optionType = FinOptionTypes.AMERICAN_CALL

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

    testCases.banner("HW AMERICAN CALL")
    testCases.header("STRIKE", "VALUE")

    for strikePrice in strikes:

        sigma = 0.01
        a = 0.1

        bondOption = BondOption(bond, expiry_date, strikePrice, face,
                                optionType)

        model = FinModelRatesHW(sigma, a)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print(strikePrice, v)

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

    optionType = FinOptionTypes.EUROPEAN_PUT
    testCases.banner("HW EUROPEAN PUT")
    testCases.header("STRIKE", "VALUE")

    price = bond.clean_price_from_discount_curve(settlement_date,
                                                 discount_curve)

    for strikePrice in strikes:

        sigma = 0.01
        a = 0.1

        bondOption = BondOption(bond, expiry_date, strikePrice, face,
                                optionType)

        model = FinModelRatesHW(sigma, a)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print(strikePrice, v)

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

    optionType = FinOptionTypes.AMERICAN_PUT
    testCases.banner("HW AMERICAN PUT")
    testCases.header("STRIKE", "VALUE")

    price = bond.clean_price_from_discount_curve(settlement_date,
                                                 discount_curve)

    for strikePrice in strikes:

        sigma = 0.02
        a = 0.1

        bondOption = BondOption(bond, expiry_date, strikePrice, face,
                                optionType)

        model = FinModelRatesHW(sigma, a)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print(strikePrice, v)
Exemple #9
0
def test_BondOptionAmericanConvergenceTWO():

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

    # Bond details
    issue_date = Date(1, 12, 2015)
    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)
    expiry_date = settlement_date.addTenor("18m")
    face = 100.0

    spotValue = bond.clean_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.01
    a = 0.1
    hwModel = FinModelRatesHW(sigma, a)
    K = 102.0

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

    num_stepsVector = range(100, 500, 100)

    for num_steps in num_stepsVector:
        hwModel = FinModelRatesHW(sigma, a, num_steps)

        start = time.time()

        europeanCallBondOption = BondOption(bond, expiry_date, K, face,
                                            FinOptionTypes.EUROPEAN_CALL)

        v_ec = europeanCallBondOption.value(settlement_date, discount_curve,
                                            hwModel)

        americanCallBondOption = BondOption(bond, expiry_date, K, face,
                                            FinOptionTypes.AMERICAN_CALL)

        v_ac = americanCallBondOption.value(settlement_date, discount_curve,
                                            hwModel)

        europeanPutBondOption = BondOption(bond, expiry_date, K, face,
                                           FinOptionTypes.EUROPEAN_PUT)

        v_ep = europeanPutBondOption.value(settlement_date, discount_curve,
                                           hwModel)

        americanPutBondOption = BondOption(bond, expiry_date, K, face,
                                           FinOptionTypes.AMERICAN_PUT)

        v_ap = americanPutBondOption.value(settlement_date, discount_curve,
                                           hwModel)

        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_ac, label="American Call")
        plt.legend()

        plt.figure()
        plt.plot(num_stepsVector, vec_ap, label="American Put")
        plt.legend()
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]

    zeroRates = [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(zeroRates) / 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.addTenor("3Y")
    maturity_date = start_date.addTenor("9Y")

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

    numTimeSteps = None
    model = FinModelRatesHW(sigma, a, numTimeSteps)
    vAnal = model.optionOnZCB(texp, tmat, strike, face, times, dfs)

    # Test convergence
    num_stepsList = 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 numTimeSteps in num_stepsList:

        start = time.time()

        model = FinModelRatesHW(sigma, a, numTimeSteps)
        model.buildTree(texp, times, dfs)
        vTree1 = model.optionOnZeroCouponBond_Tree(texp, tmat, strike, face)

        model = FinModelRatesHW(sigma, a, numTimeSteps+1)
        model.buildTree(texp, times, dfs)
        vTree2 = model.optionOnZeroCouponBond_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(numTimeSteps, period, vTreeCall, vAnal['call'],
                        vTreePut, vAnal['put'], diffC, diffP)
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)
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.addTenor("18m")
    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

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

    strikePrice = 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 = FinModelRatesHW(sigma, a, None)

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

    vJam = model.europeanBondOptionJamshidian(texp, strikePrice, 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 numTimeSteps in num_stepsList:

        start = time.time()
        model = FinModelRatesHW(sigma, a, numTimeSteps, FinHWEuropeanCalcType.EXPIRY_ONLY)
        model.buildTree(texp, times, dfs)

        exerciseType = FinExerciseTypes.EUROPEAN

        v1 = model.bondOption(texp, strikePrice, face,
                              coupon_times, coupon_flows, exerciseType)

        model = FinModelRatesHW(sigma, a, numTimeSteps, FinHWEuropeanCalcType.EXPIRY_TREE)
        model.buildTree(texp, times, dfs)

        v2 = model.bondOption(texp, strikePrice, face,
                              coupon_times, coupon_flows, exerciseType)

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

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

#    plt.plot(num_stepsList, treeVector)

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

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

    # Bond details
    issue_date = Date(1, 9, 2015)
    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 = settlement_date.addTenor("18m") # FinDate(1, 12, 2021)
#    print("EXPIRY:", expiry_date)
    face = 100.0

    dfExpiry = discount_curve.df(expiry_date)
    spotCleanValue = bond.clean_price_from_discount_curve(settlement_date, discount_curve)
    fwdCleanValue = bond.clean_price_from_discount_curve(expiry_date, discount_curve)
#    print("BOND SpotCleanBondPx", spotCleanValue)
#    print("BOND FwdCleanBondPx", fwdCleanValue)
#    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, 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 num_steps in numTimeSteps:

            sigma = 0.0000001
            model = FinModelRatesBDT(sigma, 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)
Exemple #14
0
def test_BondOption():

    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)

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

    expiry_date = settlement_date.addTenor("18m")
    strikePrice = 105.0
    face = 100.0

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

    strikes = [80, 90, 100, 110, 120]

    optionType = FinOptionTypes.EUROPEAN_CALL

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

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

    numTimeSteps = 100

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

    for strikePrice in strikes:

        sigma = 0.20

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN CALL - BK", strikePrice, v)

    for strikePrice in strikes:

        sigma = 0.20

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN CALL - BK", strikePrice, v)

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

    optionType = FinOptionTypes.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 strikePrice in strikes:

        sigma = 0.20

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN CALL - BK", strikePrice, v)

    for strikePrice in strikes:

        sigma = 0.20

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN CALL - BK", strikePrice, v)

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

    optionType = FinOptionTypes.EUROPEAN_PUT

    price = bond.full_price_from_discount_curve(settlement_date, discount_curve)

    for strikePrice in strikes:

        sigma = 0.01

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN PUT - BK", strikePrice, v)

    for strikePrice in strikes:

        sigma = 0.20

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("EUROPEAN PUT - BK", strikePrice, v)

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

    optionType = FinOptionTypes.AMERICAN_PUT

    price = bond.full_price_from_discount_curve(settlement_date, discount_curve)

    for strikePrice in strikes:

        sigma = 0.02

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN PUT - BK", strikePrice, v)

    for strikePrice in strikes:

        sigma = 0.20

        bondOption = BondOption(bond, expiry_date, strikePrice, face, optionType)
        model = FinModelRatesBDT(sigma, numTimeSteps)
        v = bondOption.value(settlement_date, discount_curve, model)
        testCases.print("AMERICAN PUT - BK", strikePrice, v)
Exemple #15
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 = FinIborDeposit(settlement_date, "1W", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinIborDeposit(settlement_date, "1M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinIborDeposit(settlement_date, "3M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinIborDeposit(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_legType = FinSwapTypes.PAY

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

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

    exerciseDate = settlement_date.addTenor("5Y")
    swapMaturityDate = exerciseDate.addTenor("5Y")
    swapFixedCoupon = 0.040852
    swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = DayCountTypes.THIRTY_E_360_ISDA
    swapFloatFrequencyType = FrequencyTypes.QUARTERLY
    swapFloatDayCountType = DayCountTypes.ACT_360
    swapNotional = 1000000
    fixed_legType = FinSwapTypes.PAY

    swaption = FinIborSwaption(settlement_date, exerciseDate, swapMaturityDate,
                               fixed_legType, swapFixedCoupon,
                               swapFixedFrequencyType, swapFixedDayCountType,
                               swapNotional, swapFloatFrequencyType,
                               swapFloatDayCountType)

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

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

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

    fwdSwap = FinIborSwap(exerciseDate, swapMaturityDate, fixed_legType,
                          swapFixedCoupon, swapFixedFrequencyType,
                          swapFixedDayCountType)

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

    model = FinModelBlack(0.1533)

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

    testCases.print("Swaption Cash Settled Value:", v)
Exemple #16
0
def test_FinIborSwaptionQLExample():

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

    depoDCCType = DayCountTypes.THIRTY_E_360_ISDA
    depos = []
    depo = FinIborDeposit(settlement_date, "1W", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinIborDeposit(settlement_date, "1M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinIborDeposit(settlement_date, "3M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinIborDeposit(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_legType = FinSwapTypes.PAY

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

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

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

    swaption = FinIborSwaption(settlement_date, exerciseDate, swapMaturityDate,
                               swaptionType, swapFixedCoupon,
                               swapFixedFrequencyType, swapFixedDayCountType,
                               swapNotional, swapFloatFrequencyType,
                               swapFloatDayCountType)

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

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

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

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

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

    model = FinModelRatesHW(0.010000000, 0.00000000001)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print(model.__class__, v)