def test_FinSABR():

    strikes = np.linspace(0.01, 0.06, 100)

    alpha = 0.060277
    beta = 0.5
    rho = 0.2097
    nu = 0.75091
    model1 = FinModelSABR(alpha, beta, rho, nu)

    alpha = 0.058484
    beta = 0.5
    rho = 0.20568
    nu = 0.79647
    model2 = FinModelSABR(alpha, beta, rho, nu)

    f = 0.0350
    T = 1.0

    vols1 = model1.blackVol(f, strikes, T)
    vols2 = model2.blackVol(f, strikes, T)

    if PLOT_GRAPHS:
        plt.figure()
        plt.plot(strikes, vols1)
        plt.plot(strikes, vols2)
        plt.title("SABR")
def test_FinIborCapFloor():

    todayDate = FinDate(20, 6, 2019)
    valuationDate = todayDate
    startDate = todayDate.addWeekDays(2)
    maturityDate = startDate.addTenor("1Y")
    liborCurve = test_FinIborDepositsAndSwaps(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 = FinModelBlack(0.20)
    model2 = FinModelBlackShifted(0.25, 0.0)
    model3 = FinModelSABR(0.013, 0.5, 0.5, 0.5)
    model4 = FinModelSABRShifted(0.013, 0.5, 0.5, 0.5, -0.008)
    model5 = FinModelRatesHW(0.30, 0.01)
    model6 = FinModelBachelier(0.01)

    for k in strikes:
        capFloorType = FinCapFloorTypes.CAP
        capfloor = FinIborCapFloor(startDate, maturityDate, capFloorType, k)
        cvalue1 = capfloor.value(valuationDate, liborCurve, model1)
        cvalue2 = capfloor.value(valuationDate, liborCurve, model2)
        cvalue3 = capfloor.value(valuationDate, liborCurve, model3)
        cvalue4 = capfloor.value(valuationDate, liborCurve, model4)
        cvalue5 = capfloor.value(valuationDate, liborCurve, model5)
        cvalue6 = capfloor.value(valuationDate, liborCurve, 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 = FinIborCapFloor(startDate, maturityDate, capFloorType, k)
        fvalue1 = capfloor.value(valuationDate, liborCurve, model1)
        fvalue2 = capfloor.value(valuationDate, liborCurve, model2)
        fvalue3 = capfloor.value(valuationDate, liborCurve, model3)
        fvalue4 = capfloor.value(valuationDate, liborCurve, model4)
        fvalue5 = capfloor.value(valuationDate, liborCurve, model5)
        fvalue6 = capfloor.value(valuationDate, liborCurve, 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 = FinIborCapFloor(startDate, maturityDate, capFloorType, k)
        cvalue1 = capfloor.value(valuationDate, liborCurve, model1)
        cvalue2 = capfloor.value(valuationDate, liborCurve, model2)
        cvalue3 = capfloor.value(valuationDate, liborCurve, model3)
        cvalue4 = capfloor.value(valuationDate, liborCurve, model4)
        cvalue5 = capfloor.value(valuationDate, liborCurve, model5)
        cvalue6 = capfloor.value(valuationDate, liborCurve, model6)

        capFloorType = FinCapFloorTypes.FLOOR
        capfloor = FinIborCapFloor(startDate, maturityDate, capFloorType, k)
        fvalue1 = capfloor.value(valuationDate, liborCurve, model1)
        fvalue2 = capfloor.value(valuationDate, liborCurve, model2)
        fvalue3 = capfloor.value(valuationDate, liborCurve, model3)
        fvalue4 = capfloor.value(valuationDate, liborCurve, model4)
        fvalue5 = capfloor.value(valuationDate, liborCurve, model5)
        fvalue6 = capfloor.value(valuationDate, liborCurve, 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 #3
0
def test_FinLiborSwaptionQLExample():

    #   valuationDate = FinDate(28, 2, 2014)
    settlementDate = FinDate(4, 3, 2014)

    depoDCCType = FinDayCountTypes.THIRTY_E_360_ISDA
    depos = []
    depo = FinLiborDeposit(settlementDate, "1W", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinLiborDeposit(settlementDate, "1M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinLiborDeposit(settlementDate, "3M", 0.0023, depoDCCType)
    depos.append(depo)
    depo = FinLiborDeposit(settlementDate, "6M", 0.0023, depoDCCType)
    depos.append(depo)

    # No convexity correction provided so I omit interest rate futures

    swaps = []
    accType = FinDayCountTypes.ACT_365F
    fixedFreqType = FinFrequencyTypes.SEMI_ANNUAL
    swapType = FinLiborSwapTypes.PAYER

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

    liborCurve = FinLiborCurve(settlementDate, depos, [], swaps,
                               FinInterpTypes.LINEAR_ZERO_RATES)

    exerciseDate = settlementDate.addTenor("5Y")
    swapMaturityDate = exerciseDate.addTenor("5Y")
    swapFixedCoupon = 0.040852
    swapFixedFrequencyType = FinFrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = FinDayCountTypes.THIRTY_E_360_ISDA
    swapFloatFrequencyType = FinFrequencyTypes.QUARTERLY
    swapFloatDayCountType = FinDayCountTypes.ACT_360
    swapNotional = 1000000
    swaptionType = FinLiborSwapTypes.PAYER

    swaption = FinLiborSwaption(settlementDate, exerciseDate, swapMaturityDate,
                                swaptionType, swapFixedCoupon,
                                swapFixedFrequencyType, swapFixedDayCountType,
                                swapNotional, swapFloatFrequencyType,
                                swapFloatDayCountType)

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

    model = FinModelBlack(0.1533)
    v = swaption.value(settlementDate, liborCurve, model)
    testCases.print(model.__class__, v)

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

    model = FinModelSABR(0.132, 0.5, 0.5, 0.5)
    v = swaption.value(settlementDate, liborCurve, model)
    testCases.print(model.__class__, v)

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

    model = FinModelRatesHW(0.010000000, 0.00000000001)
    v = swaption.value(settlementDate, liborCurve, model)
    testCases.print(model.__class__, v)
Example #4
0
def testFinLiborSwaptionModels():

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

    valuationDate = FinDate(2011, 1, 1)
    liborCurve = test_FinLiborDepositsAndSwaps(valuationDate)

    exerciseDate = FinDate(2012, 1, 1)
    swapMaturityDate = FinDate(2017, 1, 1)

    swapFixedFrequencyType = FinFrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = FinDayCountTypes.ACT_365F

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

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

    model1 = FinModelBlack(0.00001)
    model2 = FinModelBlackShifted(0.00001, 0.0)
    model3 = FinModelSABR(0.013, 0.5, 0.5, 0.5)
    model4 = FinModelSABRShifted(0.013, 0.5, 0.5, 0.5, -0.008)
    model5 = FinModelRatesHW(0.00001, 0.00001)
    model6 = FinModelRatesBK(0.01, 0.01)

    settlementDate = valuationDate.addWorkDays(2)

    for k in strikes:
        swaptionType = FinLiborSwapTypes.PAYER
        swaption = FinLiborSwaption(settlementDate, exerciseDate,
                                    swapMaturityDate, swaptionType, k,
                                    swapFixedFrequencyType,
                                    swapFixedDayCountType)

        swap1 = swaption.value(valuationDate, liborCurve, model1)
        swap2 = swaption.value(valuationDate, liborCurve, model2)
        swap3 = swaption.value(valuationDate, liborCurve, model3)
        swap4 = swaption.value(valuationDate, liborCurve, model4)
        swap5 = swaption.value(valuationDate, liborCurve, model5)
        swap6 = swaption.value(valuationDate, liborCurve, 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 = FinLiborSwapTypes.RECEIVER
        swaption = FinLiborSwaption(settlementDate, exerciseDate,
                                    swapMaturityDate, swaptionType, k,
                                    swapFixedFrequencyType,
                                    swapFixedDayCountType)

        swap1 = swaption.value(valuationDate, liborCurve, model1)
        swap2 = swaption.value(valuationDate, liborCurve, model2)
        swap3 = swaption.value(valuationDate, liborCurve, model3)
        swap4 = swaption.value(valuationDate, liborCurve, model4)
        swap5 = swaption.value(valuationDate, liborCurve, model5)
        swap6 = swaption.value(valuationDate, liborCurve, model6)
        testCases.print("REC", k, swap1, swap2, swap3, swap4, swap5, swap6)
Example #5
0
def test_SABR_Calibration():

    beta = 0.5
    rho = -0.09
    nu = 0.1

    strikeVol = 0.1

    f = 0.043
    k = 0.050
    r = 0.03
    texp = 1.0

    callOptionType = FinOptionTypes.EUROPEAN_CALL
    putOptionType = FinOptionTypes.EUROPEAN_PUT

    df = np.exp(-r * texp)

    testCases.header("TEST", "CALIBRATION ERROR")

    # Make SABR equivalent to lognormal (Black) model
    # (i.e. alpha = 0, beta = 1, rho = 0, nu = 0, shift = 0)
    modelSABR_01 = FinModelSABR(0.0, 1.0, 0.0, 0.0)
    modelSABR_01.setAlphaFromBlackVol(strikeVol, f, k, texp)

    impliedLognormalVol = modelSABR_01.blackVol(f, k, texp)
    impliedATMLognormalVol = modelSABR_01.blackVol(k, k, texp)
    impliedLognormalSmile = impliedLognormalVol - impliedATMLognormalVol

    assert impliedLognormalSmile == 0.0, "In lognormal model, smile should be flat"
    calibrationError = round(strikeVol - impliedLognormalVol, 12)
    testCases.print("LOGNORMAL CASE", calibrationError)

    # Volatility: pure SABR dynamics
    modelSABR_02 = FinModelSABR(alpha, beta, rho, nu)
    modelSABR_02.setAlphaFromBlackVol(strikeVol, f, k, texp)

    impliedLognormalVol = modelSABR_02.blackVol(f, k, texp)
    impliedATMLognormalVol = modelSABR_02.blackVol(k, k, texp)
    impliedLognormalSmile = impliedLognormalVol - impliedATMLognormalVol
    calibrationError = round(strikeVol - impliedLognormalVol, 12)
    testCases.print("SABR CASE", calibrationError)

    # Valuation: pure SABR dynamics
    valueCall = modelSABR_02.value(f, k, texp, df, callOptionType)
    valuePut = modelSABR_02.value(f, k, texp, df, putOptionType)
    assert round(valueCall - valuePut, 12) == round(df*(f - k), 12), \
        "The method called 'value()' doesn't comply with Call-Put parity"