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