def test_FinBondEmbeddedOptionQUANTLIB(): # Based on example at the nice blog on Quantlib at # http://gouthamanbalaraman.com/blog/callable-bond-quantlib-python.html # I get a price of 68.97 for 1000 time steps which is higher than the # 68.38 found in blog article. But this is for 40 grid points. # Note also that a basis point vol of 0.120 is 12% which is VERY HIGH! valuationDate = FinDate(16, 8, 2016) settlementDate = valuationDate.addWeekDays(3) ########################################################################### discountCurve = FinDiscountCurveFlat(valuationDate, 0.035, FinFrequencyTypes.SEMI_ANNUAL) ########################################################################### issueDate = FinDate(15, 9, 2010) maturityDate = FinDate(15, 9, 2022) coupon = 0.025 freqType = FinFrequencyTypes.QUARTERLY accrualType = FinDayCountTypes.ACT_ACT_ICMA bond = FinBond(issueDate, maturityDate, coupon, freqType, accrualType) ########################################################################### # Set up the call and put times and prices ########################################################################### nextCallDate = FinDate(15, 9, 2016) callDates = [nextCallDate] callPrices = [100.0] for _ in range(1, 24): nextCallDate = nextCallDate.addMonths(3) callDates.append(nextCallDate) callPrices.append(100.0) putDates = [] putPrices = [] # the value used in blog of 12% bp vol is unrealistic sigma = 0.12 / 0.035 # basis point volatility a = 0.03 puttableBond = FinBondEmbeddedOption(issueDate, maturityDate, coupon, freqType, accrualType, callDates, callPrices, putDates, putPrices) testCases.header("BOND PRICE", "PRICE") v = bond.cleanPriceFromDiscountCurve(settlementDate, discountCurve) testCases.print("Bond Pure Price:", v) testCases.header("TIME", "NumTimeSteps", "BondWithOption", "BondPure") timeSteps = range(100, 200, 20) # 1000, 10) values = [] for numTimeSteps in timeSteps: model = FinModelRatesBK(sigma, a, numTimeSteps) start = time.time() v = puttableBond.value(settlementDate, discountCurve, model) end = time.time() period = end - start testCases.print(period, numTimeSteps, v['bondwithoption'], v['bondpure']) values.append(v['bondwithoption']) if plotGraphs: plt.figure() plt.title("Puttable Bond Price Convergence") plt.plot(timeSteps, values)
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.addWeekDays(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)