Example #1
0
def testBlackModelCheck():

    # Checking Andersen paper using Black's model
    # Used to check swaption price below - we have Ts = 1 and Te = 4
    # Expect a price around 122 cents which is what I find.

    valuation_date = Date(1, 1, 2020)
    libor_curve = DiscountCurveFlat(valuation_date, 0.06,
                                    FrequencyTypes.SEMI_ANNUAL)

    settlement_date = Date(1, 1, 2020)
    exercise_date = Date(1, 1, 2021)
    maturity_date = Date(1, 1, 2024)

    fixed_coupon = 0.06
    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    # Pricing a PAY
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    model = Black(0.20)
    v = swaption.value(valuation_date, libor_curve, model)
    testCases.header("LABEL", "VALUE")
    testCases.print("BLACK'S MODEL PRICE:", v * 100)
def test_IborCapletHull():

    #  Hull Page 703, example 29.3
    todayDate = Date(20, 6, 2019)
    valuation_date = todayDate
    maturity_date = valuation_date.add_tenor("2Y")
    libor_curve = DiscountCurveFlat(valuation_date, 0.070,
                                    FrequencyTypes.QUARTERLY,
                                    DayCountTypes.THIRTY_E_360)

    k = 0.08
    capFloorType = FinCapFloorTypes.CAP
    capFloor = IborCapFloor(valuation_date, maturity_date, capFloorType, k,
                            None, FrequencyTypes.QUARTERLY,
                            DayCountTypes.THIRTY_E_360)

    # Value cap using a single flat cap volatility
    model = Black(0.20)
    capFloor.value(valuation_date, libor_curve, model)

    # Value cap by breaking it down into caplets using caplet vols
    capletStartDate = valuation_date.add_tenor("1Y")
    capletEndDate = capletStartDate.add_tenor("3M")

    vCaplet = capFloor.value_caplet_floor_let(valuation_date, capletStartDate,
                                              capletEndDate, libor_curve,
                                              model)

    # Cannot match Hull due to dates being adjusted
    testCases.header("CORRECT PRICE", "MODEL_PRICE")
    testCases.print(517.29, vCaplet)
def testIborSwaptionModels():

    ##########################################################################
    # COMPARISON OF MODELS
    ##########################################################################

    valuation_date = Date(1, 1, 2011)
    libor_curve = test_ibor_depositsAndSwaps(valuation_date)

    exercise_date = Date(1, 1, 2012)
    swapMaturityDate = Date(1, 1, 2017)

    swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = DayCountTypes.ACT_365F

    strikes = np.linspace(0.02, 0.08, 5)

    testCases.header("LAB", "STRIKE", "BLK", "BLK_SHFT", "SABR", "SABR_SHFT",
                     "HW", "BK")

    model1 = Black(0.00001)
    model2 = BlackShifted(0.00001, 0.0)
    model3 = SABR(0.013, 0.5, 0.5, 0.5)
    model4 = SABRShifted(0.013, 0.5, 0.5, 0.5, -0.008)
    model5 = HWTree(0.00001, 0.00001)
    model6 = BKTree(0.01, 0.01)

    settlement_date = valuation_date.add_weekdays(2)

    for k in strikes:
        swaptionType = SwapTypes.PAY
        swaption = IborSwaption(settlement_date, exercise_date,
                                swapMaturityDate, swaptionType, k,
                                swapFixedFrequencyType, swapFixedDayCountType)

        swap1 = swaption.value(valuation_date, libor_curve, model1)
        swap2 = swaption.value(valuation_date, libor_curve, model2)
        swap3 = swaption.value(valuation_date, libor_curve, model3)
        swap4 = swaption.value(valuation_date, libor_curve, model4)
        swap5 = swaption.value(valuation_date, libor_curve, model5)
        swap6 = swaption.value(valuation_date, libor_curve, model6)
        testCases.print("PAY", k, swap1, swap2, swap3, swap4, swap5, swap6)

    testCases.header("LABEL", "STRIKE", "BLK", "BLK_SHFTD", "SABR",
                     "SABR_SHFTD", "HW", "BK")

    for k in strikes:
        swaptionType = SwapTypes.RECEIVE
        swaption = IborSwaption(settlement_date, exercise_date,
                                swapMaturityDate, swaptionType, k,
                                swapFixedFrequencyType, swapFixedDayCountType)

        swap1 = swaption.value(valuation_date, libor_curve, model1)
        swap2 = swaption.value(valuation_date, libor_curve, model2)
        swap3 = swaption.value(valuation_date, libor_curve, model3)
        swap4 = swaption.value(valuation_date, libor_curve, model4)
        swap5 = swaption.value(valuation_date, libor_curve, model5)
        swap6 = swaption.value(valuation_date, libor_curve, model6)
        testCases.print("REC", k, swap1, swap2, swap3, swap4, swap5, swap6)
def test_IborCapFloorQLExample():

    valuation_date = Date(14, 6, 2016)

    dates = [
        Date(14, 6, 2016),
        Date(14, 9, 2016),
        Date(14, 12, 2016),
        Date(14, 6, 2017),
        Date(14, 6, 2019),
        Date(14, 6, 2021),
        Date(15, 6, 2026),
        Date(16, 6, 2031),
        Date(16, 6, 2036),
        Date(14, 6, 2046)
    ]

    rates = [
        0.000000, 0.006616, 0.007049, 0.007795, 0.009599, 0.011203, 0.015068,
        0.017583, 0.018998, 0.020080
    ]

    freq_type = FrequencyTypes.ANNUAL
    day_count_type = DayCountTypes.ACT_ACT_ISDA

    discount_curve = DiscountCurveZeros(valuation_date, dates, rates,
                                        freq_type, day_count_type,
                                        InterpTypes.LINEAR_ZERO_RATES)

    start_date = Date(14, 6, 2016)
    end_date = Date(14, 6, 2026)
    calendar_type = CalendarTypes.UNITED_STATES
    bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING
    freq_type = FrequencyTypes.QUARTERLY
    date_gen_rule_type = DateGenRuleTypes.FORWARD
    lastFixing = 0.0065560
    notional = 1000000
    day_count_type = DayCountTypes.ACT_360
    option_type = FinCapFloorTypes.CAP
    strike_rate = 0.02

    cap = IborCapFloor(start_date, end_date, option_type, strike_rate,
                       lastFixing, freq_type, day_count_type, notional,
                       calendar_type, bus_day_adjust_type, date_gen_rule_type)

    blackVol = 0.547295
    model = Black(blackVol)

    start = time.time()
    numRepeats = 10
    for i in range(0, numRepeats):
        v = cap.value(valuation_date, discount_curve, model)

    end = time.time()
    period = end - start
def testIborSwaptionMatlabExamples():

    # We value a European swaption using Black's model and try to replicate a
    # ML example at https://fr.mathworks.com/help/fininst/swaptionbyblk.html

    testCases.header("=======================================")
    testCases.header("MATLAB EXAMPLE WITH FLAT TERM STRUCTURE")
    testCases.header("=======================================")

    valuation_date = Date(1, 1, 2010)
    libor_curve = DiscountCurveFlat(valuation_date, 0.06,
                                    FrequencyTypes.CONTINUOUS,
                                    DayCountTypes.THIRTY_E_360)

    settlement_date = Date(1, 1, 2011)
    exercise_date = Date(1, 1, 2016)
    maturity_date = Date(1, 1, 2019)

    fixed_coupon = 0.062
    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    # Pricing a PAY
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    model = Black(0.20)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 2.071

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

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

    testCases.header("===================================")
    testCases.header("MATLAB EXAMPLE WITH TERM STRUCTURE")
    testCases.header("===================================")

    valuation_date = Date(1, 1, 2010)

    dates = [
        Date(1, 1, 2011),
        Date(1, 1, 2012),
        Date(1, 1, 2013),
        Date(1, 1, 2014),
        Date(1, 1, 2015)
    ]

    zero_rates = [0.03, 0.034, 0.037, 0.039, 0.040]

    contFreq = FrequencyTypes.CONTINUOUS
    interp_type = InterpTypes.LINEAR_ZERO_RATES
    day_count_type = DayCountTypes.THIRTY_E_360

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = Date(1, 1, 2011)
    exercise_date = Date(1, 1, 2012)
    maturity_date = Date(1, 1, 2017)
    fixed_coupon = 0.03

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360
    float_frequency_type = FrequencyTypes.SEMI_ANNUAL
    float_day_count_type = DayCountTypes.THIRTY_E_360
    notional = 1000.0

    # Pricing a put
    swaptionType = SwapTypes.RECEIVE
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional,
                            float_frequency_type, float_day_count_type)

    model = Black(0.21)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 0.5771

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

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

    testCases.header("===================================")
    testCases.header("MATLAB EXAMPLE WITH SHIFTED BLACK")
    testCases.header("===================================")

    valuation_date = Date(1, 1, 2016)

    dates = [
        Date(1, 1, 2017),
        Date(1, 1, 2018),
        Date(1, 1, 2019),
        Date(1, 1, 2020),
        Date(1, 1, 2021)
    ]

    zero_rates = np.array([-0.02, 0.024, 0.047, 0.090, 0.12]) / 100.0

    contFreq = FrequencyTypes.ANNUAL
    interp_type = InterpTypes.LINEAR_ZERO_RATES
    day_count_type = DayCountTypes.THIRTY_E_360

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = Date(1, 1, 2016)
    exercise_date = Date(1, 1, 2017)
    maturity_date = Date(1, 1, 2020)
    fixed_coupon = -0.003

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    float_frequency_type = FrequencyTypes.SEMI_ANNUAL
    float_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 1000.0

    # Pricing a PAY
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional,
                            float_frequency_type, float_day_count_type)

    model = BlackShifted(0.31, 0.008)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 12.8301

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

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

    testCases.header("===================================")
    testCases.header("MATLAB EXAMPLE WITH HULL WHITE")
    testCases.header("===================================")

    # https://fr.mathworks.com/help/fininst/swaptionbyhw.html

    valuation_date = Date(1, 1, 2007)

    dates = [
        Date(1, 1, 2007),
        Date(1, 7, 2007),
        Date(1, 1, 2008),
        Date(1, 7, 2008),
        Date(1, 1, 2009),
        Date(1, 7, 2009),
        Date(1, 1, 2010),
        Date(1, 7, 2010),
        Date(1, 1, 2011),
        Date(1, 7, 2011),
        Date(1, 1, 2012)
    ]

    zero_rates = np.array([0.075] * 11)
    interp_type = InterpTypes.FLAT_FWD_RATES
    day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    contFreq = FrequencyTypes.SEMI_ANNUAL

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = valuation_date
    exercise_date = Date(1, 1, 2010)
    maturity_date = Date(1, 1, 2012)
    fixed_coupon = 0.04

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    swaptionType = SwapTypes.RECEIVE
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    model = HWTree(0.05, 0.01)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 2.9201

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

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

    testCases.header("====================================")
    testCases.header("MATLAB EXAMPLE WITH BLACK KARASINSKI")
    testCases.header("====================================")

    # https://fr.mathworks.com/help/fininst/swaptionbybk.html
    valuation_date = Date(1, 1, 2007)

    dates = [
        Date(1, 1, 2007),
        Date(1, 7, 2007),
        Date(1, 1, 2008),
        Date(1, 7, 2008),
        Date(1, 1, 2009),
        Date(1, 7, 2009),
        Date(1, 1, 2010),
        Date(1, 7, 2010),
        Date(1, 1, 2011),
        Date(1, 7, 2011),
        Date(1, 1, 2012)
    ]

    zero_rates = np.array([0.07] * 11)

    interp_type = InterpTypes.FLAT_FWD_RATES
    day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    contFreq = FrequencyTypes.SEMI_ANNUAL

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = valuation_date
    exercise_date = Date(1, 1, 2011)
    maturity_date = Date(1, 1, 2012)

    fixed_frequency_type = FrequencyTypes.SEMI_ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    model = BKTree(0.1, 0.05, 200)

    fixed_coupon = 0.07
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 0.3634

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

    fixed_coupon = 0.0725
    swaptionType = SwapTypes.RECEIVE
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 0.4798

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)

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

    testCases.header("====================================")
    testCases.header("MATLAB EXAMPLE WITH BLACK-DERMAN-TOY")
    testCases.header("====================================")

    # https://fr.mathworks.com/help/fininst/swaptionbybdt.html

    valuation_date = Date(1, 1, 2007)

    dates = [
        Date(1, 1, 2007),
        Date(1, 7, 2007),
        Date(1, 1, 2008),
        Date(1, 7, 2008),
        Date(1, 1, 2009),
        Date(1, 7, 2009),
        Date(1, 1, 2010),
        Date(1, 7, 2010),
        Date(1, 1, 2011),
        Date(1, 7, 2011),
        Date(1, 1, 2012)
    ]

    zero_rates = np.array([0.06] * 11)

    interp_type = InterpTypes.FLAT_FWD_RATES
    day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    contFreq = FrequencyTypes.ANNUAL

    libor_curve = DiscountCurveZeros(valuation_date, dates, zero_rates,
                                     contFreq, day_count_type, interp_type)

    settlement_date = valuation_date
    exercise_date = Date(1, 1, 2012)
    maturity_date = Date(1, 1, 2015)

    fixed_frequency_type = FrequencyTypes.ANNUAL
    fixed_day_count_type = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    fixed_coupon = 0.062
    swaptionType = SwapTypes.PAY
    swaption = IborSwaption(settlement_date, exercise_date, maturity_date,
                            swaptionType, fixed_coupon, fixed_frequency_type,
                            fixed_day_count_type, notional)

    model = BDTTree(0.20, 200)
    v_finpy = swaption.value(valuation_date, libor_curve, model)
    v_matlab = 2.0592

    testCases.header("LABEL", "VALUE")
    testCases.print("FP Price:", v_finpy)
    testCases.print("MATLAB Prix:", v_matlab)
    testCases.print("DIFF:", v_finpy - v_matlab)
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 = IborDeposit(settlement_date, "1W", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "1M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(settlement_date, "3M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = IborDeposit(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_leg_type = SwapTypes.PAY

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

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

    exercise_date = settlement_date.add_tenor("5Y")
    swapMaturityDate = exercise_date.add_tenor("5Y")
    swapFixedCoupon = 0.040852
    swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = DayCountTypes.THIRTY_E_360_ISDA
    swapFloatFrequencyType = FrequencyTypes.QUARTERLY
    swapFloatDayCountType = DayCountTypes.ACT_360
    swapNotional = 1000000
    fixed_leg_type = SwapTypes.PAY

    swaption = IborSwaption(settlement_date, exercise_date, swapMaturityDate,
                            fixed_leg_type, swapFixedCoupon,
                            swapFixedFrequencyType, swapFixedDayCountType,
                            swapNotional, swapFloatFrequencyType,
                            swapFloatDayCountType)

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

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

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

    fwdSwap = IborSwap(exercise_date, swapMaturityDate, fixed_leg_type,
                       swapFixedCoupon, swapFixedFrequencyType,
                       swapFixedDayCountType)

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

    model = Black(0.1533)

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

    testCases.print("Swaption Cash Settled Value:", v)
def test_IborSwaptionQLExample():

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

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

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

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

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

    swaption = IborSwaption(settlement_date, exercise_date, swapMaturityDate,
                            swaptionType, swapFixedCoupon,
                            swapFixedFrequencyType, swapFixedDayCountType,
                            swapNotional, swapFloatFrequencyType,
                            swapFloatDayCountType)

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

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

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

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

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

    model = HWTree(0.010000000, 0.00000000001)
    v = swaption.value(settlement_date, libor_curve, model)
    testCases.print(model.__class__, v)
Example #8
0
def test_IborBermudanSwaptionBKModel():
    """ Replicate examples in paper by Leif Andersen which can be found at
    file:///C:/Users/Dominic/Downloads/SSRN-id155208.pdf """

    valuation_date = Date(1, 1, 2011)
    settlement_date = valuation_date
    exercise_date = settlement_date.add_years(1)
    swapMaturityDate = settlement_date.add_years(4)

    swapFixedCoupon = 0.060
    swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = DayCountTypes.ACT_365F

    libor_curve = DiscountCurveFlat(valuation_date, 0.0625,
                                    FrequencyTypes.SEMI_ANNUAL,
                                    DayCountTypes.ACT_365F)

    fwdPAYSwap = IborSwap(exercise_date, swapMaturityDate, SwapTypes.PAY,
                          swapFixedCoupon, swapFixedFrequencyType,
                          swapFixedDayCountType)

    fwdSwapValue = fwdPAYSwap.value(settlement_date, libor_curve, libor_curve)

    testCases.header("LABEL", "VALUE")
    testCases.print("FWD SWAP VALUE", fwdSwapValue)

    # fwdPAYSwap.print_fixed_leg_pv()

    # Now we create the European swaptions
    fixed_leg_type = SwapTypes.PAY
    europeanSwaptionPay = IborSwaption(settlement_date, exercise_date,
                                       swapMaturityDate, fixed_leg_type,
                                       swapFixedCoupon, swapFixedFrequencyType,
                                       swapFixedDayCountType)

    fixed_leg_type = SwapTypes.RECEIVE
    europeanSwaptionRec = IborSwaption(settlement_date, exercise_date,
                                       swapMaturityDate, fixed_leg_type,
                                       swapFixedCoupon, swapFixedFrequencyType,
                                       swapFixedDayCountType)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BLACK'S MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("======= ZERO VOLATILITY ========")
    model = Black(0.0000001)
    testCases.print("Black Model", model._volatility)

    valuePay = europeanSwaptionPay.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK PAY VALUE ZERO VOL:", valuePay)

    valueRec = europeanSwaptionRec.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK REC VALUE ZERO VOL:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner("======= 20%% BLACK VOLATILITY ========")

    model = Black(0.20)
    testCases.print("Black Model", model._volatility)

    valuePay = europeanSwaptionPay.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BK MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("=======================================================")
    testCases.banner("=======================================================")
    testCases.banner("==================== BK MODEL =========================")
    testCases.banner("=======================================================")
    testCases.banner("=======================================================")

    testCases.banner("======= 0% VOLATILITY EUROPEAN SWAPTION BK MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.000000001
    a = 0.01
    num_time_steps = 100
    model = BKTree(sigma, a, num_time_steps)

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY EUROPEAN SWAPTION BK MODEL ========")

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = BKTree(sigma, a, num_time_steps)

    testCases.banner("BK MODEL SWAPTION CLASS EUROPEAN EXERCISE")

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

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

    # Now we create the Bermudan swaptions but only allow European exercise
    fixed_leg_type = SwapTypes.PAY
    exercise_type = FinExerciseTypes.EUROPEAN

    bermudan_swaption_pay = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_leg_type = SwapTypes.RECEIVE
    exercise_type = FinExerciseTypes.EUROPEAN

    bermudan_swaption_rec = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = BKTree(sigma, a, num_time_steps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.2
    a = 0.01
    model = BKTree(sigma, a, num_time_steps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    # Now we create the Bermudan swaptions but allow Bermudan exercise
    ###########################################################################

    fixed_leg_type = SwapTypes.PAY
    exercise_type = FinExerciseTypes.BERMUDAN

    bermudan_swaption_pay = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_leg_type = SwapTypes.RECEIVE
    exercise_type = FinExerciseTypes.BERMUDAN

    bermudan_swaption_rec = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= ZERO VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = BKTree(sigma, a, num_time_steps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = BKTree(sigma, a, num_time_steps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BDT MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("=======================================================")
    testCases.banner("=======================================================")
    testCases.banner("======================= BDT MODEL =====================")
    testCases.banner("=======================================================")
    testCases.banner("=======================================================")

    testCases.banner("====== 0% VOLATILITY EUROPEAN SWAPTION BDT MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.00001
    num_time_steps = 200
    model = BDTTree(sigma, num_time_steps)

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner("===== 20% VOLATILITY EUROPEAN SWAPTION BDT MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = BDTTree(sigma, num_time_steps)

    testCases.banner("BDT MODEL SWAPTION CLASS EUROPEAN EXERCISE")

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

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

    # Now we create the Bermudan swaptions but only allow European exercise
    fixed_leg_type = SwapTypes.PAY
    exercise_type = FinExerciseTypes.EUROPEAN

    bermudan_swaption_pay = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_leg_type = SwapTypes.RECEIVE
    bermudan_swaption_rec = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    model = BDTTree(sigma, num_time_steps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.2
    model = BDTTree(sigma, num_time_steps)

    testCases.banner("BDT MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    # Now we create the Bermudan swaptions but allow Bermudan exercise
    ###########################################################################

    fixed_leg_type = SwapTypes.PAY
    exercise_type = FinExerciseTypes.BERMUDAN

    bermudan_swaption_pay = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_leg_type = SwapTypes.RECEIVE
    bermudan_swaption_rec = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= ZERO VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = BDTTree(sigma, num_time_steps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = BDTTree(sigma, num_time_steps)

    #    print("BDT MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BDT MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("=======================================================")
    testCases.banner("=======================================================")
    testCases.banner("======================= HW MODEL ======================")
    testCases.banner("=======================================================")
    testCases.banner("=======================================================")

    testCases.banner("====== 0% VOLATILITY EUROPEAN SWAPTION HW MODEL ======")

    sigma = 0.0000001
    a = 0.1
    num_time_steps = 200
    model = HWTree(sigma, a, num_time_steps)

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner("===== 20% VOLATILITY EUROPEAN SWAPTION BDT MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.01
    a = 0.01
    model = HWTree(sigma, a, num_time_steps)

    testCases.banner("HW MODEL SWAPTION CLASS EUROPEAN EXERCISE")

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

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

    # Now we create the Bermudan swaptions but only allow European exercise
    fixed_leg_type = SwapTypes.PAY
    exercise_type = FinExerciseTypes.EUROPEAN

    bermudan_swaption_pay = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_leg_type = SwapTypes.RECEIVE
    bermudan_swaption_rec = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE HW MODEL ========"
    )

    sigma = 0.000001
    model = HWTree(sigma, a, num_time_steps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 100bp VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE HW MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.01
    model = HWTree(sigma, a, num_time_steps)

    testCases.banner("BDT MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    # Now we create the Bermudan swaptions but allow Bermudan exercise
    ###########################################################################

    fixed_leg_type = SwapTypes.PAY
    exercise_type = FinExerciseTypes.BERMUDAN

    bermudan_swaption_pay = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_leg_type = SwapTypes.RECEIVE
    bermudan_swaption_rec = IborBermudanSwaption(
        settlement_date, exercise_date, swapMaturityDate, fixed_leg_type,
        exercise_type, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= ZERO VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE HW MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = HWTree(sigma, a, num_time_steps)

    testCases.banner("HW MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 100bps VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE HW MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.01
    a = 0.01
    model = HWTree(sigma, a, num_time_steps)

    testCases.banner("HW MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudan_swaption_pay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW PAY VALUE:", valuePay)

    valueRec = bermudan_swaption_rec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)
Example #9
0
def test_FinIborCapFloor():

    todayDate = Date(20, 6, 2019)
    valuation_date = todayDate
    start_date = todayDate.add_weekdays(2)
    maturity_date = start_date.add_tenor("1Y")
    libor_curve = test_ibor_depositsAndSwaps(todayDate)

    # The capfloor has begun
    # lastFixing = 0.028

    ##########################################################################
    # COMPARISON OF MODELS
    ##########################################################################

    strikes = np.linspace(0.02, 0.08, 5)

    testCases.header("LABEL", "STRIKE", "BLK", "BLK_SHFTD", "SABR",
                     "SABR_SHFTD", "HW", "BACH")

    model1 = Black(0.20)
    model2 = BlackShifted(0.25, 0.0)
    model3 = SABR(0.013, 0.5, 0.5, 0.5)
    model4 = SABRShifted(0.013, 0.5, 0.5, 0.5, -0.008)
    model5 = HWTree(0.30, 0.01)
    model6 = Bachelier(0.01)

    for k in strikes:
        capFloorType = FinCapFloorTypes.CAP
        capfloor = IborCapFloor(start_date, maturity_date, capFloorType, k)
        cvalue1 = capfloor.value(valuation_date, libor_curve, model1)
        cvalue2 = capfloor.value(valuation_date, libor_curve, model2)
        cvalue3 = capfloor.value(valuation_date, libor_curve, model3)
        cvalue4 = capfloor.value(valuation_date, libor_curve, model4)
        cvalue5 = capfloor.value(valuation_date, libor_curve, model5)
        cvalue6 = capfloor.value(valuation_date, libor_curve, model6)
        testCases.print("CAP", k, cvalue1, cvalue2,
                        cvalue3, cvalue4, cvalue5, cvalue6)

    testCases.header("LABEL", "STRIKE", "BLK", "BLK_SHFTD", "SABR",
                     "SABR_SHFTD", "HW", "BACH")

    for k in strikes:
        capFloorType = FinCapFloorTypes.FLOOR
        capfloor = IborCapFloor(start_date, maturity_date, capFloorType, k)
        fvalue1 = capfloor.value(valuation_date, libor_curve, model1)
        fvalue2 = capfloor.value(valuation_date, libor_curve, model2)
        fvalue3 = capfloor.value(valuation_date, libor_curve, model3)
        fvalue4 = capfloor.value(valuation_date, libor_curve, model4)
        fvalue5 = capfloor.value(valuation_date, libor_curve, model5)
        fvalue6 = capfloor.value(valuation_date, libor_curve, model6)
        testCases.print("FLR", k, fvalue1, fvalue2,
                        fvalue3, fvalue4, fvalue5, fvalue6)

###############################################################################
# PUT CALL CHECK
###############################################################################

    testCases.header("LABEL", "STRIKE", "BLK", "BLK_SHFTD", "SABR",
                     "SABR SHFTD", "HW", "BACH")

    for k in strikes:
        capFloorType = FinCapFloorTypes.CAP
        capfloor = IborCapFloor(start_date, maturity_date, capFloorType, k)
        cvalue1 = capfloor.value(valuation_date, libor_curve, model1)
        cvalue2 = capfloor.value(valuation_date, libor_curve, model2)
        cvalue3 = capfloor.value(valuation_date, libor_curve, model3)
        cvalue4 = capfloor.value(valuation_date, libor_curve, model4)
        cvalue5 = capfloor.value(valuation_date, libor_curve, model5)
        cvalue6 = capfloor.value(valuation_date, libor_curve, model6)

        capFloorType = FinCapFloorTypes.FLOOR
        capfloor = IborCapFloor(start_date, maturity_date, capFloorType, k)
        fvalue1 = capfloor.value(valuation_date, libor_curve, model1)
        fvalue2 = capfloor.value(valuation_date, libor_curve, model2)
        fvalue3 = capfloor.value(valuation_date, libor_curve, model3)
        fvalue4 = capfloor.value(valuation_date, libor_curve, model4)
        fvalue5 = capfloor.value(valuation_date, libor_curve, model5)
        fvalue6 = capfloor.value(valuation_date, libor_curve, model6)

        pcvalue1 = cvalue1 - fvalue1
        pcvalue2 = cvalue2 - fvalue2
        pcvalue3 = cvalue3 - fvalue3
        pcvalue4 = cvalue4 - fvalue4
        pcvalue5 = cvalue5 - fvalue5
        pcvalue6 = cvalue6 - fvalue6

        testCases.print("PUT_CALL", k, pcvalue1, pcvalue2, pcvalue3,
                        pcvalue4, pcvalue5, pcvalue6)
Example #10
0
def test_FinIborCapFloorVolCurve():
    """ Aim here is to price cap and caplets using cap and caplet vols and to
    demonstrate they are the same - NOT SURE THAT HULLS BOOKS FORMULA WORKS FOR
    OPTIONS. """

    todayDate = Date(20, 6, 2019)
    valuation_date = todayDate
    maturity_date = valuation_date.add_tenor("3Y")
    day_count_type = DayCountTypes.THIRTY_E_360
    frequency = FrequencyTypes.ANNUAL

    k = 0.04
    capFloorType = FinCapFloorTypes.CAP
    capFloor = IborCapFloor(valuation_date,
                            maturity_date,
                            capFloorType,
                            k,
                            None,
                            frequency,
                            day_count_type)

    capVolDates = Schedule(valuation_date,
                           valuation_date.add_tenor("10Y"),
                           frequency)._generate()

    flat_rate = 0.04
    libor_curve = DiscountCurveFlat(valuation_date,
                                    flat_rate,
                                    frequency,
                                    day_count_type)

    flat = False
    if flat is True:
        capVolatilities = [20.0] * 11
        capVolatilities[0] = 0.0
    else:
        capVolatilities = [0.00, 15.50, 18.25, 17.91, 17.74, 17.27,
                           16.79, 16.30, 16.01, 15.76, 15.54]

    capVolatilities = np.array(capVolatilities)/100.0
    capVolatilities[0] = 0.0

    volCurve = IborCapVolCurve(valuation_date,
                               capVolDates,
                               capVolatilities,
                               day_count_type)

#    print(volCurve._capletGammas)

    # Value cap using a single flat cap volatility
    tcap = (maturity_date - valuation_date) / gDaysInYear
    vol = volCurve.cap_vol(maturity_date)
    model = Black(vol)
    valueCap = capFloor.value(valuation_date, libor_curve, model)
#    print("CAP T", tcap, "VOL:", vol, "VALUE OF CAP:", valueCap)

    # Value cap by breaking it down into caplets using caplet vols
    vCaplets = 0.0
    capletStartDate = capFloor._capFloorLetDates[1]
    testCases.header("START", "END", "VOL", "VALUE")

    for capletEndDate in capFloor._capFloorLetDates[2:]:
        vol = volCurve.caplet_vol(capletEndDate)
        modelCaplet = Black(vol)
        vCaplet = capFloor.value_caplet_floor_let(valuation_date,
                                                  capletStartDate,
                                                  capletEndDate,
                                                  libor_curve,
                                                  modelCaplet)

        vCaplets += vCaplet
        testCases.print("%12s" % capletStartDate,
                        "%s" % capletEndDate,
                        "%9.5f" % (vol*100.0),
                        "%9.5f" % vCaplet)

        capletStartDate = capletEndDate

    testCases.header("LABEL", "VALUE")
    testCases.print("CAPLETS->CAP: ", vCaplets)
    swaps.append(swap1)
    swaps.append(swap2)
    swaps.append(swap3)

    libor_curve = IborSingleCurve(valuation_date, depos, fras, swaps)

    return libor_curve


todayDate = Date(20, 6, 2019)
valuation_date = todayDate
start_date = todayDate.add_weekdays(2)
maturity_date = start_date.add_tenor("1Y")
libor_curve = build_curve(todayDate)

model1 = Black(0.20)
model2 = BlackShifted(0.25, 0.0)
model3 = SABR(0.013, 0.5, 0.5, 0.5)
model4 = SABRShifted(0.013, 0.5, 0.5, 0.5, -0.008)
model5 = HWTree(0.30, 0.01)
model6 = Bachelier(0.01)


def test_cap():
    capFloorType = FinCapFloorTypes.CAP

    k = 0.02
    capfloor = IborCapFloor(start_date, maturity_date, capFloorType, k)
    cvalue1 = capfloor.value(valuation_date, libor_curve, model1)
    cvalue2 = capfloor.value(valuation_date, libor_curve, model2)
    cvalue3 = capfloor.value(valuation_date, libor_curve, model3)
Example #12
0
def test_Black():

    forward = 0.034
    strike = 0.050
    riskFreeIR = 0.00
    time_to_expiry = 2.0
    volatility = 0.20

    testCases.header("ITEM", "CALL", "PUT")

    call_optionType = FinOptionTypes.EUROPEAN_CALL
    put_optionType = FinOptionTypes.EUROPEAN_PUT

    df = np.exp(-riskFreeIR * time_to_expiry)
    model = Black(volatility)

    dp = 12  # Precision

    try:

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

        valueCall = model.value(forward, strike, time_to_expiry, df,
                                call_optionType)
        valuePut = model.value(forward, strike, time_to_expiry, df,
                               put_optionType)

        assert round((valueCall - valuePut), dp) == round(df*(forward - strike), dp), \
            "The method called 'value()' doesn't comply with Call-Put parity"

        testCases.print("VALUE", valueCall, valuePut)

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

        deltaCall = model.delta(forward, strike, time_to_expiry, df,
                                call_optionType)
        deltaPut = model.delta(forward, strike, time_to_expiry, df,
                               put_optionType)

        assert round((1/df) * (deltaCall - deltaPut), dp) == 1.0, \
            "The method called 'delta()' doesn't comply with Call-put parity"

        testCases.print("DELTA", deltaCall, deltaPut)

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

        gammaCall = model.gamma(forward, strike, time_to_expiry, df,
                                call_optionType)
        gammaPut = model.gamma(forward, strike, time_to_expiry, df,
                               put_optionType)

        assert round(gammaCall - gammaPut, dp) == 0.0, \
            "The method called 'gamma()' doesn't comply with Call-Put parity"

        testCases.print("GAMMA", gammaCall, gammaPut)

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

        thetaCall = model.theta(forward, strike, time_to_expiry, df,
                                call_optionType)
        thetaPut = model.theta(forward, strike, time_to_expiry, df,
                               put_optionType)

        assert round((thetaCall - thetaPut), dp) == round((riskFreeIR * time_to_expiry) * (forward - strike) * df, dp), \
            "The method called 'theta()' doesn't comply with Call-Put parity"

        testCases.print("THETA", thetaCall, thetaPut)

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

        vegaCall = model.vega(forward, strike, time_to_expiry, df,
                              call_optionType)
        vegaPut = model.vega(forward, strike, time_to_expiry, df,
                             put_optionType)

        assert round(vegaCall - vegaPut, dp) == 0.0, \
            "The method called 'vega()' doesn't comply with Call-Put parity"

        testCases.print("VEGA", vegaCall, vegaPut)

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

    except AssertionError as err:
        raise err
Example #13
0
from financepy.utils.global_types import OptionTypes
from financepy.models.black import Black
import sys
import numpy as np

forward = 0.034
strike = 0.050
riskFreeIR = 0.00
time_to_expiry = 2.0
volatility = 0.20

call_optionType = OptionTypes.EUROPEAN_CALL
put_optionType = OptionTypes.EUROPEAN_PUT

df = np.exp(-riskFreeIR * time_to_expiry)
model = Black(volatility)

dp = 12  # Precision


def test_value():
    valueCall = model.value(forward, strike, time_to_expiry, df,
                            call_optionType)
    valuePut = model.value(forward, strike, time_to_expiry, df, put_optionType)

    assert round((valueCall - valuePut), dp) == round(df*(forward - strike), dp), \
        "The method called 'value()' doesn't comply with Call-Put parity"

    assert round(valueCall * 1000, 4) == 0.4599
    assert round(valuePut * 10, 4) == 0.1646
    swaps.append(swap3)

    libor_curve = IborSingleCurve(valuation_date, depos, fras, swaps)

    return libor_curve


valuation_date = Date(1, 1, 2011)

exercise_date = Date(1, 1, 2012)
swapMaturityDate = Date(1, 1, 2017)

swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
swapFixedDayCountType = DayCountTypes.ACT_365F

model1 = Black(0.00001)
model2 = BlackShifted(0.00001, 0.0)
model3 = SABR(0.013, 0.5, 0.5, 0.5)
model4 = SABRShifted(0.013, 0.5, 0.5, 0.5, -0.008)
model5 = HWTree(0.00001, 0.00001)
model6 = BKTree(0.01, 0.01)

settlement_date = valuation_date.add_weekdays(2)

libor_curve = build_curve(valuation_date)


def test_pay():
    libor_curve = build_curve(valuation_date)
    swaptionType = SwapTypes.PAY