def test_FinFXMktVolSurface5(verboseCalibration): ########################################################################### # Here I remove the 10D Vols ########################################################################### if 1 == 1: # Example from Book extract by Iain Clark using Tables 3.3 and 3.4 # print("EURUSD EXAMPLE CLARK") valuation_date = Date(10, 4, 2020) forName = "EUR" domName = "USD" forCCRate = 0.03460 # EUR domCCRate = 0.02940 # USD domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate) forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate) currencyPair = forName + domName spotFXRate = 1.3465 tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y'] atmVols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677] marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85] riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562] marketStrangle10DeltaVols = [2.433, 2.83, 3.228, 3.485, 3.806, 3.208] riskReversal10DeltaVols = [-1.258, -1.297, -1.332, -1.408, -1.359, -1.208] marketStrangle10DeltaVols = None riskReversal10DeltaVols = None notionalCurrency = forName atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL deltaMethod = FinFXDeltaMethod.SPOT_DELTA volFunctionType = FinVolFunctionTypes.CLARK alpha = 0.50 # FIT WINGS AT 10D if ALPHA = 1.0 fxMarketPlus = FinFXVolSurfacePlus(valuation_date, spotFXRate, currencyPair, notionalCurrency, domDiscountCurve, forDiscountCurve, tenors, atmVols, marketStrangle25DeltaVols, riskReversal25DeltaVols, marketStrangle10DeltaVols, riskReversal10DeltaVols, alpha, atmMethod, deltaMethod, volFunctionType) fxMarketPlus.checkCalibration(False)
def test_FinFXVanillaOptionWystupExample1(): # Example from Book extract by Uwe Wystup with results in Table 1.2 # https://mathfinance.com/wp-content/uploads/2017/06/FXOptionsStructuredProducts2e-Extract.pdf # Not exactly T=1.0 but close so don't exact exact agreement # (in fact I do not get exact agreement even if I do set T=1.0) valuation_date = Date(13, 2, 2018) expiry_date = Date(13, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR ccy1 = "EUR" ccy2 = "USD" ccy1CCRate = 0.030 # EUR ccy2CCRate = 0.025 # USD currencyPair = ccy1 + ccy2 # Always ccy1ccy2 spotFXRate = 1.20 strikeFXRate = 1.250 volatility = 0.10 notional = 1000000.0 domDiscountCurve = DiscountCurveFlat(valuation_date, ccy2CCRate) forDiscountCurve = DiscountCurveFlat(valuation_date, ccy1CCRate) model = FinModelBlackScholes(volatility) # Two examples to show that changing the notional currency and notional # keeps the value unchanged notional = 1000000.0 callOption = FinFXVanillaOption(expiry_date, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_CALL, notional, "EUR", 2) value = callOption.value(1.0, spotFXRate, domDiscountCurve, forDiscountCurve, model) notional = 1250000.0 callOption = FinFXVanillaOption(expiry_date, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_CALL, notional, "USD", 2) value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) testCases.header("value", "delta") testCases.print(value, delta)
def test_BondOptionAmericanConvergenceONE(): # Build discount curve settlement_date = Date(1, 12, 2019) discount_curve = DiscountCurveFlat(settlement_date, 0.05) # Bond details maturity_date = Date(1, 9, 2025) issue_date = Date(1, 9, 2016) 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) # Option Details expiry_date = Date(1, 12, 2020) strikePrice = 100.0 face = 100.0 testCases.header("TIME", "N", "PUT_AMER", "PUT_EUR", "CALL_AME", "CALL_EUR") timeSteps = range(30, 100, 10) for numTimeSteps in timeSteps: sigma = 0.20 a = 0.1 start = time.time() optionType = FinOptionTypes.AMERICAN_PUT bondOption1 = BondOption(bond, expiry_date, strikePrice, face, optionType) model1 = FinModelRatesBK(sigma, a, numTimeSteps) v1put = bondOption1.value(settlement_date, discount_curve, model1) optionType = FinOptionTypes.EUROPEAN_PUT bondOption2 = BondOption(bond, expiry_date, strikePrice, face, optionType) model2 = FinModelRatesBK(sigma, a, numTimeSteps) v2put = bondOption2.value(settlement_date, discount_curve, model2) optionType = FinOptionTypes.AMERICAN_CALL bondOption1 = BondOption(bond, expiry_date, strikePrice, face, optionType) model1 = FinModelRatesBK(sigma, a, numTimeSteps) v1call = bondOption1.value(settlement_date, discount_curve, model1) optionType = FinOptionTypes.EUROPEAN_CALL bondOption2 = BondOption(bond, expiry_date, strikePrice, face, optionType) model2 = FinModelRatesBK(sigma, a, numTimeSteps) v2call = bondOption2.value(settlement_date, discount_curve, model2) end = time.time() period = end - start testCases.print(period, numTimeSteps, v1put, v2put, v1call, v2call)
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) exerciseDate = Date(1, 1, 2021) maturity_date = Date(1, 1, 2024) fixedCoupon = 0.06 fixedFrequencyType = FrequencyTypes.SEMI_ANNUAL fixedDayCountType = DayCountTypes.THIRTY_E_360_ISDA notional = 100.0 # Pricing a PAY swaptionType = FinSwapTypes.PAY swaption = FinIborSwaption(settlement_date, exerciseDate, maturity_date, swaptionType, fixedCoupon, fixedFrequencyType, fixedDayCountType, notional) model = FinModelBlack(0.20) v = swaption.value(valuation_date, libor_curve, model) testCases.header("LABEL", "VALUE") testCases.print("BLACK'S MODEL PRICE:", v * 100)
def test_FinFloatIborLeg(): effective_date = Date(28, 10, 2020) maturity_date = Date(28, 10, 2025) spread = 0.0 freq_type = FrequencyTypes.ANNUAL day_count_type = DayCountTypes.THIRTY_360_BOND notional = 10.0 * ONE_MILLION legPayRecType = FinSwapTypes.PAY calendar_type = CalendarTypes.TARGET bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD payment_lag = 0 principal = 0.0 swapFloatLeg = FinFloatLeg(effective_date, maturity_date, legPayRecType, spread, freq_type, day_count_type, notional, principal, payment_lag, calendar_type, bus_day_adjust_type, date_gen_rule_type) libor_curve = DiscountCurveFlat(effective_date, 0.05) firstFixing = 0.03 v = swapFloatLeg.value(effective_date, libor_curve, libor_curve, firstFixing)
def test_FinFXMktVolSurface2(verboseCalibration): #print("==============================================================") # Example from Book extract by Iain Clark using Tables 3.3 and 3.4 # print("EURJPY EXAMPLE CLARK") valuation_date = Date(10, 4, 2020) forName = "EUR" domName = "JPY" forCCRate = 0.0294 # EUR domCCRate = 0.0171 # USD domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate) forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate) currencyPair = forName + domName spotFXRate = 90.72 tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y'] atmVols = [21.50, 20.50, 19.85, 18.00, 15.95, 14.009] marketStrangle25DeltaVols = [0.35, 0.325, 0.300, 0.225, 0.175, 0.100] riskReversal25DeltaVols = [-8.350, -8.650, -8.950, -9.250, -9.550, -9.500] notionalCurrency = forName atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ fxMarket = FinFXVolSurface(valuation_date, spotFXRate, currencyPair, notionalCurrency, domDiscountCurve, forDiscountCurve, tenors, atmVols, marketStrangle25DeltaVols, riskReversal25DeltaVols, atmMethod, deltaMethod) fxMarket.checkCalibration(verboseCalibration) if PLOT_GRAPHS: fxMarket.plotVolCurves()
def test_FinFXMktVolSurface4(verboseCalibration): # USDJPY Example from Paper by Uwe Wystup using Tables 4 # print("USDJPY EXAMPLE WYSTUP") valuation_date = Date(20, 1, 2009) forName = "USD" domName = "JPY" forCCRate = 0.003525 # USD domCCRate = 0.0042875 # JPY domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate) forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate) currencyPair = forName + domName spotFXRate = 90.68 tenors = ['1M'] atmVols = [21.00] marketStrangle25DeltaVols = [0.184] riskReversal25DeltaVols = [-5.30] notionalCurrency = forName atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ fxMarket = FinFXVolSurface(valuation_date, spotFXRate, currencyPair, notionalCurrency, domDiscountCurve, forDiscountCurve, tenors, atmVols, marketStrangle25DeltaVols, riskReversal25DeltaVols, atmMethod, deltaMethod) fxMarket.checkCalibration(verboseCalibration) if PLOT_GRAPHS: fxMarket.plotVolCurves()
def test_FinFXMktVolSurface3(verboseCalibration): # EURUSD Example from Paper by Uwe Wystup using Tables 4 # print("EURUSD EXAMPLE WYSTUP") valuation_date = Date(20, 1, 2009) forName = "EUR" domName = "USD" forCCRate = 0.020113 # EUR domCCRate = 0.003525 # USD domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate) forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate) currencyPair = forName + domName spotFXRate = 1.3088 tenors = ['1M'] atmVols = [21.6215] marketStrangle25DeltaVols = [0.7375] riskReversal25DeltaVols = [-0.50] notionalCurrency = forName atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL deltaMethod = FinFXDeltaMethod.SPOT_DELTA fxMarket = FinFXVolSurface(valuation_date, spotFXRate, currencyPair, notionalCurrency, domDiscountCurve, forDiscountCurve, tenors, atmVols, marketStrangle25DeltaVols, riskReversal25DeltaVols, atmMethod, deltaMethod) fxMarket.checkCalibration(verboseCalibration) if PLOT_GRAPHS: fxMarket.plotVolCurves()
def test_FinFXVanillaOptionWystupExample2(): # Example Bloomberg Pricing at # https://stackoverflow.com/questions/48778712/fx-vanilla-call-price-in-quantlib-doesnt-match-bloomberg valuation_date = Date(13, 2, 2018) expiry_date = Date(13, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR ccy1 = "EUR" ccy2 = "USD" ccy1CCRate = 0.0396 # EUR ccy2CCRate = 0.0357 # USD currencyPair = ccy1 + ccy2 # Always ccy1ccy2 spotFXRate = 0.9090 strikeFXRate = 0.9090 volatility = 0.12 notional = 1000000.0 domDiscountCurve = DiscountCurveFlat(valuation_date, ccy2CCRate) forDiscountCurve = DiscountCurveFlat(valuation_date, ccy1CCRate) model = FinModelBlackScholes(volatility) # Two examples to show that changing the notional currency and notional # keeps the value unchanged notional = 1000000.0 callOption = FinFXVanillaOption(expiry_date, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_PUT, notional, "EUR", 2) value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) testCases.header("value", "delta") testCases.print(value, delta)
def test_FinEquityVarianceSwap(): start_date = Date(20, 3, 2018) tenor = "3M" strike = 0.3 * 0.3 volSwap = FinEquityVarianceSwap(start_date, tenor, strike) valuation_date = Date(20, 3, 2018) stock_price = 100.0 dividendYield = 0.0 dividendCurve = DiscountCurveFlat(valuation_date, dividendYield) maturity_date = start_date.addMonths(3) atmVol = 0.20 atmK = 100.0 skew = -0.02 / 5.0 # defined as dsigma/dK strikes = np.linspace(50.0, 135.0, 18) vols = volSkew(strikes, atmVol, atmK, skew) volCurve = FinEquityVolCurve(valuation_date, maturity_date, strikes, vols) strikeSpacing = 5.0 numCallOptions = 10 numPutOptions = 10 r = 0.05 discount_curve = DiscountCurveFlat(valuation_date, r) useForward = False testCases.header("LABEL", "VALUE") k1 = volSwap.fairStrike(valuation_date, stock_price, dividendCurve, volCurve, numCallOptions, numPutOptions, strikeSpacing, discount_curve, useForward) testCases.print("REPLICATION VARIANCE:", k1) k2 = volSwap.fairStrikeApprox(valuation_date, stock_price, strikes, vols) testCases.print("DERMAN SKEW APPROX for K:", k2)
def test_FinEquityChooserOptionMatlab(): """https://fr.mathworks.com/help/fininst/chooserbybls.html """ valuation_date = Date(1, 6, 2007) chooseDate = Date(31, 8, 2007) callExpiryDate = Date(2, 12, 2007) putExpiryDate = Date(2, 12, 2007) callStrike = 60.0 putStrike = 60.0 stock_price = 50.0 volatility = 0.20 interestRate = 0.10 dividendYield = 0.05 model = FinModelBlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, interestRate) dividendCurve = DiscountCurveFlat(valuation_date, dividendYield) chooserOption = FinEquityChooserOption(chooseDate, callExpiryDate, putExpiryDate, callStrike, putStrike) v = chooserOption.value(valuation_date, stock_price, discount_curve, dividendCurve, model) v_mc = chooserOption.valueMC(valuation_date, stock_price, discount_curve, dividendCurve, model, 20000) v_matlab = 8.9308 testCases.header("", "", "", "", "", "") testCases.print("FINANCEPY", v, "MATLAB", v_matlab, "MC", v_mc)
def test_FinEquityChooserOptionHaug(): """ Following example in Haug Page 130 """ valuation_date = Date(1, 1, 2015) chooseDate = Date(2, 4, 2015) callExpiryDate = Date(1, 7, 2015) putExpiryDate = Date(2, 8, 2015) callStrike = 55.0 putStrike = 48.0 stock_price = 50.0 volatility = 0.35 interestRate = 0.10 dividendYield = 0.05 model = FinModelBlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, interestRate) dividendCurve = DiscountCurveFlat(valuation_date, dividendYield) chooserOption = FinEquityChooserOption(chooseDate, callExpiryDate, putExpiryDate, callStrike, putStrike) v = chooserOption.value(valuation_date, stock_price, discount_curve, dividendCurve, model) v_mc = chooserOption.valueMC(valuation_date, stock_price, discount_curve, dividendCurve, model, 20000) v_haug = 6.0508 testCases.header("", "", "", "", "", "") testCases.print("FINANCEPY", v, "HAUG", v_haug, "MC", v_mc)
def test_FinEquityChooserOptionDerivicom(): """http://derivicom.com/support/finoptionsxl/index.html?complex_chooser.htm """ valuation_date = Date(1, 1, 2007) chooseDate = Date(1, 2, 2007) callExpiryDate = Date(1, 4, 2007) putExpiryDate = Date(1, 5, 2007) callStrike = 40.0 putStrike = 35.0 stock_price = 38.0 volatility = 0.20 interestRate = 0.08 dividendYield = 0.0625 model = FinModelBlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, interestRate) dividendCurve = DiscountCurveFlat(valuation_date, dividendYield) chooserOption = FinEquityChooserOption(chooseDate, callExpiryDate, putExpiryDate, callStrike, putStrike) v = chooserOption.value(valuation_date, stock_price, discount_curve, dividendCurve, model) v_mc = chooserOption.valueMC(valuation_date, stock_price, discount_curve, dividendCurve, model, 20000) v_derivicom = 1.0989 testCases.header("", "", "", "", "", "") testCases.print("FINANCEPY", v, "DERIVICOM", v_derivicom, "MC", v_mc)
def test_FinEquityForward(): valuation_date = Date(13, 2, 2018) expiry_date = valuation_date.addMonths(12) stock_price = 130.0 forwardPrice = 125.0 # Locked discountRate = 0.05 dividendRate = 0.02 ########################################################################### expiry_date = valuation_date.addMonths(12) notional = 100.0 discount_curve = DiscountCurveFlat(valuation_date, discountRate) dividendCurve = DiscountCurveFlat(valuation_date, dividendRate) equityForward = FinEquityForward(expiry_date, forwardPrice, notional, FinLongShort.LONG) testCases.header("SPOT FX", "FX FWD", "VALUE_BS") fwdPrice = equityForward.forward(valuation_date, stock_price, discount_curve, dividendCurve) fwdValue = equityForward.value(valuation_date, stock_price, discount_curve, dividendCurve) # print(stock_price, fwdPrice, fwdValue) testCases.print(stock_price, fwdPrice, fwdValue)
def test_example(): expiry_date = Date(1, 1, 2021) strikePrice = 105.0 optionTypeCall = FinOptionTypes.EUROPEAN_CALL optionTypePut = FinOptionTypes.EUROPEAN_PUT lookbackCall = FinEquityFixedLookbackOption(expiry_date, optionTypeCall, strikePrice) lookbackPut = FinEquityFixedLookbackOption(expiry_date, optionTypePut, strikePrice) valuation_date = Date(1, 1, 2020) interestRate = 0.10 stock_price = 100.0 dividendYield = 0.0 stockMinMax = 100.0 discount_curve = DiscountCurveFlat(valuation_date, interestRate) dividendCurve = DiscountCurveFlat(valuation_date, dividendYield) volatilities = [0.30] testCases.header("VALUE") for vol in volatilities: v = lookbackCall.value(valuation_date, stock_price, discount_curve, dividendCurve, vol, stockMinMax) testCases.print(v)
def test_FinFixedOIS(): # Here I follow the example in # https://blog.deriscope.com/index.php/en/excel-quantlib-overnight-index-swap effective_date = Date(30, 11, 2018) end_date = Date(30, 11, 2023) end_date = effective_date.addMonths(60) oisRate = 0.04 fixed_legType = FinSwapTypes.PAY fixedFreqType = FrequencyTypes.ANNUAL fixedDayCount = DayCountTypes.ACT_360 floatFreqType = FrequencyTypes.ANNUAL floatDayCount = DayCountTypes.ACT_360 floatSpread = 0.0 notional = ONE_MILLION payment_lag = 1 ois = FinOIS(effective_date, end_date, fixed_legType, oisRate, fixedFreqType, fixedDayCount, notional, payment_lag, floatSpread, floatFreqType, floatDayCount) # print(ois) valuation_date = effective_date marketRate = 0.05 oisCurve = DiscountCurveFlat(valuation_date, marketRate, FrequencyTypes.ANNUAL) v = ois.value(effective_date, oisCurve) # print(v) # ois._fixed_leg.printValuation() # ois._floatLeg.printValuation() testCases.header("LABEL", "VALUE") testCases.print("SWAP_VALUE", v)
def test_FinIborCapletHull(): # Hull Page 703, example 29.3 todayDate = Date(20, 6, 2019) valuation_date = todayDate maturity_date = valuation_date.addTenor("2Y") libor_curve = DiscountCurveFlat(valuation_date, 0.070, FrequencyTypes.QUARTERLY, DayCountTypes.THIRTY_E_360) k = 0.08 capFloorType = FinCapFloorTypes.CAP capFloor = FinIborCapFloor(valuation_date, maturity_date, capFloorType, k, None, FrequencyTypes.QUARTERLY, DayCountTypes.THIRTY_E_360) # Value cap using a single flat cap volatility model = FinModelBlack(0.20) capFloor.value(valuation_date, libor_curve, model) # Value cap by breaking it down into caplets using caplet vols capletStartDate = valuation_date.addTenor("1Y") capletEndDate = capletStartDate.addTenor("3M") vCaplet = capFloor.valueCapletFloorLet(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 test_FinSwaptionVolSurface1(verboseCalibration): ########################################################################### if 1 == 1: # https://fr.mathworks.com/help/fininst/pricing-a-swaption-using-the-sabr-model.html valuation_date = Date(12, 6, 2013) # These are 3M, 1Y, 2Y, 3Y, 4Y, 5Y, 7Y, 10Y exerciseDates = [Date(12, 9, 2013), Date(12, 6, 2014), Date(12, 6, 2015), Date(12, 6, 2016), Date(12, 6, 2017), Date(12, 6, 2018), Date(12, 6, 2020), Date(12, 6, 2023)] # First dimension is the strike, then the expiry date marketVolatilities = [[57.6, 53.7, 49.4, 45.6, 44.1, 41.1, 35.2, 32.0], [46.6, 46.9, 44.8, 41.6, 39.8, 37.4, 33.4, 31.0], [35.9, 39.3, 39.6, 37.9, 37.2, 34.7, 30.5, 28.9], [34.1, 36.5, 37.8, 36.6, 35.0, 31.9, 28.1, 26.6], [41.0, 41.3, 39.5, 37.8, 36.0, 32.6, 29.0, 26.0], [45.8, 43.4, 41.9, 39.2, 36.9, 33.2, 29.6, 26.3], [50.3, 46.9, 44.0, 40.0, 37.5, 33.8, 30.2, 27.3]] marketVolatilities = np.array(marketVolatilities) / 100.0 # First dimension is the strike, then the expiry date marketStrikes = [[1.00, 1.25, 1.68, 2.00, 2.26, 2.41, 2.58, 2.62], [1.50, 1.75, 2.18, 2.50, 2.76, 2.91, 3.08, 3.12], [2.00, 2.25, 2.68, 3.00, 3.26, 3.41, 3.58, 3.62], [2.50, 2.75, 3.18, 3.50, 3.76, 3.91, 4.08, 4.12], [3.00, 3.25, 3.68, 4.00, 4.26, 4.41, 4.58, 4.62], [3.50, 3.75, 4.18, 4.50, 4.76, 4.91, 5.08, 5.12], [4.00, 4.25, 4.68, 5.00, 5.26, 5.41, 5.58, 5.62]] marketStrikes = np.array(marketStrikes) / 100.0 fwdSwapRates = marketStrikes[3] atmVols = marketVolatilities[3] rfrRate = 0.020 # USD discount_curve = DiscountCurveFlat(valuation_date, rfrRate) divRate = 0.010 # USD dividendCurve = DiscountCurveFlat(valuation_date, divRate) volFunctionType = FinVolFunctionTypes.SABR_BETA_HALF swaptionSurface = FinSwaptionVolSurface(valuation_date, exerciseDates, fwdSwapRates, marketStrikes, marketVolatilities, volFunctionType) tol = 1e-4 swaptionSurface.checkCalibration(False, tol) if 1==1: # PLOT_GRAPHS: swaptionSurface.plotVolCurves()
def test_Bond(): import pandas as pd path = os.path.join(os.path.dirname(__file__), './data/giltBondPrices.txt') bondDataFrame = pd.read_csv(path, sep='\t') bondDataFrame['mid'] = 0.5 * (bondDataFrame['bid'] + bondDataFrame['ask']) freq_type = FrequencyTypes.SEMI_ANNUAL settlement_date = Date(19, 9, 2012) face = ONE_MILLION for accrual_type in DayCountTypes: testCases.header("MATURITY", "COUPON", "CLEAN_PRICE", "ACCD_DAYS", "ACCRUED", "YTM") for _, bond in bondDataFrame.iterrows(): dateString = bond['maturity'] matDatetime = dt.datetime.strptime(dateString, '%d-%b-%y') maturityDt = fromDatetime(matDatetime) issueDt = Date(maturityDt._d, maturityDt._m, 2000) coupon = bond['coupon'] / 100.0 clean_price = bond['mid'] bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type, 100) ytm = bond.yield_to_maturity(settlement_date, clean_price) accrued_interest= bond._accruedInterest accd_days = bond._accrued_days testCases.print("%18s" % maturityDt, "%8.4f" % coupon, "%10.4f" % clean_price, "%6.0f" % accd_days, "%10.4f" % accrued_interest, "%8.4f" % ytm) ########################################################################### # EXAMPLE FROM http://bondtutor.com/btchp4/topic6/topic6.htm accrualConvention = DayCountTypes.ACT_ACT_ICMA y = 0.062267 settlement_date = Date(19, 4, 1994) issue_date = Date(15, 7, 1990) maturity_date = Date(15, 7, 1997) coupon = 0.085 face = ONE_MILLION freq_type = FrequencyTypes.SEMI_ANNUAL bond = Bond(issue_date, maturity_date, coupon, freq_type, accrualConvention, face) testCases.header("FIELD", "VALUE") full_price = bond.full_price_from_ytm(settlement_date, y) testCases.print("Full Price = ", full_price) clean_price = bond.clean_price_from_ytm(settlement_date, y) testCases.print("Clean Price = ", clean_price) accrued_interest= bond._accruedInterest testCases.print("Accrued = ", accrued_interest) ytm = bond.yield_to_maturity(settlement_date, clean_price) testCases.print("Yield to Maturity = ", ytm) bump = 1e-4 priceBumpedUp = bond.full_price_from_ytm(settlement_date, y + bump) testCases.print("Price Bumped Up:", priceBumpedUp) priceBumpedDn = bond.full_price_from_ytm(settlement_date, y - bump) testCases.print("Price Bumped Dn:", priceBumpedDn) durationByBump = -(priceBumpedUp - full_price) / bump testCases.print("Duration by Bump = ", durationByBump) duration = bond.dollar_duration(settlement_date, y) testCases.print("Dollar Duration = ", duration) testCases.print("Duration Difference:", duration - durationByBump) modified_duration = bond.modified_duration(settlement_date, y) testCases.print("Modified Duration = ", modified_duration) macauley_duration = bond.macauley_duration(settlement_date, y) testCases.print("Macauley Duration = ", macauley_duration) conv = bond.convexity_from_ytm(settlement_date, y) testCases.print("Convexity = ", conv) # ASSET SWAP SPREAD # When the libor curve is the flat bond curve then the ASW is zero by # definition flatCurve = DiscountCurveFlat(settlement_date, ytm, FrequencyTypes.SEMI_ANNUAL) testCases.header("FIELD", "VALUE") clean_price = bond.clean_price_from_ytm(settlement_date, ytm) asw = bond.asset_swap_spread(settlement_date, clean_price, flatCurve) testCases.print("Discounted on Bond Curve ASW:", asw * 10000) # When the libor curve is the Libor curve then the ASW is positive libor_curve = buildIborCurve(settlement_date) asw = bond.asset_swap_spread(settlement_date, clean_price, libor_curve) oas = bond.option_adjusted_spread(settlement_date, clean_price, libor_curve) testCases.print("Discounted on LIBOR Curve ASW:", asw * 10000) testCases.print("Discounted on LIBOR Curve OAS:", oas * 10000) p = 90.0 asw = bond.asset_swap_spread(settlement_date, p, libor_curve) oas = bond.option_adjusted_spread(settlement_date, p, libor_curve) testCases.print("Deep discount bond at 90 ASW:", asw * 10000) testCases.print("Deep discount bond at 90 OAS:", oas * 10000) p = 100.0 asw = bond.asset_swap_spread(settlement_date, p, libor_curve) oas = bond.option_adjusted_spread(settlement_date, p, libor_curve) testCases.print("Par bond at 100 ASW:", asw * 10000) testCases.print("Par bond at 100 OAS:", oas * 10000) p = 120.0 asw = bond.asset_swap_spread(settlement_date, p, libor_curve) oas = bond.option_adjusted_spread(settlement_date, p, libor_curve) testCases.print("Above par bond at 120 ASW:", asw * 10000) testCases.print("Above par bond at 120 OAS:", oas * 10000) ########################################################################## # https://data.bloomberglp.com/bat/sites/3/2017/07/SF-2017_Paul-Fjeldsted.pdf # Page 10 TREASURY NOTE SCREENSHOT ########################################################################## testCases.banner("BLOOMBERG US TREASURY EXAMPLE") settlement_date = Date(21, 7, 2017) issue_date = Date(15, 5, 2010) maturity_date = Date(15, 5, 2027) coupon = 0.02375 freq_type = FrequencyTypes.SEMI_ANNUAL accrual_type = DayCountTypes.ACT_ACT_ICMA face = 100.0 bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type, face) testCases.header("FIELD", "VALUE") clean_price = 99.7808417 yld = bond.current_yield(clean_price) testCases.print("Current Yield = ", yld) ytm = bond.yield_to_maturity(settlement_date, clean_price, FinYTMCalcType.UK_DMO) testCases.print("UK DMO Yield To Maturity = ", ytm) ytm = bond.yield_to_maturity(settlement_date, clean_price, FinYTMCalcType.US_STREET) testCases.print("US STREET Yield To Maturity = ", ytm) ytm = bond.yield_to_maturity(settlement_date, clean_price, FinYTMCalcType.US_TREASURY) testCases.print("US TREASURY Yield To Maturity = ", ytm) full_price = bond.full_price_from_ytm(settlement_date, ytm) testCases.print("Full Price = ", full_price) clean_price = bond.clean_price_from_ytm(settlement_date, ytm) testCases.print("Clean Price = ", clean_price) accrued_interest= bond._accruedInterest testCases.print("Accrued = ", accrued_interest) accddays = bond._accrued_days testCases.print("Accrued Days = ", accddays) duration = bond.dollar_duration(settlement_date, ytm) testCases.print("Dollar Duration = ", duration) modified_duration = bond.modified_duration(settlement_date, ytm) testCases.print("Modified Duration = ", modified_duration) macauley_duration = bond.macauley_duration(settlement_date, ytm) testCases.print("Macauley Duration = ", macauley_duration) conv = bond.convexity_from_ytm(settlement_date, ytm) testCases.print("Convexity = ", conv) ########################################################################## # Page 11 APPLE NOTE SCREENSHOT ########################################################################## testCases.banner("BLOOMBERG APPLE CORP BOND EXAMPLE") settlement_date = Date(21, 7, 2017) issue_date = Date(13, 5, 2012) maturity_date = Date(13, 5, 2022) coupon = 0.027 freq_type = FrequencyTypes.SEMI_ANNUAL accrual_type = DayCountTypes.THIRTY_E_360_ISDA face = 100.0 bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type, face) testCases.header("FIELD", "VALUE") clean_price = 101.581564 yld = bond.current_yield(clean_price) testCases.print("Current Yield", yld) ytm = bond.yield_to_maturity(settlement_date, clean_price, FinYTMCalcType.UK_DMO) testCases.print("UK DMO Yield To Maturity", ytm) ytm = bond.yield_to_maturity(settlement_date, clean_price, FinYTMCalcType.US_STREET) testCases.print("US STREET Yield To Maturity", ytm) ytm = bond.yield_to_maturity(settlement_date, clean_price, FinYTMCalcType.US_TREASURY) testCases.print("US TREASURY Yield To Maturity", ytm) full_price = bond.full_price_from_ytm(settlement_date, ytm) testCases.print("Full Price", full_price) clean_price = bond.clean_price_from_ytm(settlement_date, ytm) testCases.print("Clean Price", clean_price) accddays = bond._accrued_days testCases.print("Accrued Days", accddays) accrued_interest= bond._accruedInterest testCases.print("Accrued", accrued_interest) duration = bond.dollar_duration(settlement_date, ytm) testCases.print("Dollar Duration", duration) modified_duration = bond.modified_duration(settlement_date, ytm) testCases.print("Modified Duration", modified_duration) macauley_duration = bond.macauley_duration(settlement_date, ytm) testCases.print("Macauley Duration", macauley_duration) conv = bond.convexity_from_ytm(settlement_date, ytm) testCases.print("Convexity", conv)
def test_FinBinomialTree(): stock_price = 50.0 riskFreeRate = 0.06 dividendYield = 0.04 volatility = 0.40 valuation_date = Date(1, 1, 2016) expiry_date = Date(1, 1, 2017) model = FinModelBlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, riskFreeRate) dividendCurve = DiscountCurveFlat(valuation_date, dividendYield) num_stepsList = [100, 500, 1000, 2000, 5000] strikePrice = 50.0 testCases.banner("================== EUROPEAN PUT =======================") putOption = FinEquityVanillaOption(expiry_date, strikePrice, FinOptionTypes.EUROPEAN_PUT) value = putOption.value(valuation_date, stock_price, discount_curve, dividendCurve, model) delta = putOption.delta(valuation_date, stock_price, discount_curve, dividendCurve, model) gamma = putOption.gamma(valuation_date, stock_price, discount_curve, dividendCurve, model) theta = putOption.theta(valuation_date, stock_price, discount_curve, dividendCurve, model) testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta") testCases.print(value, delta, gamma, theta) payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.EUROPEAN params = np.array([-1, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_stepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stock_price, discount_curve, dividendCurve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration) testCases.banner("================== AMERICAN PUT =======================") payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.AMERICAN params = np.array([-1, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_stepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stock_price, discount_curve, dividendCurve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration) testCases.banner( "================== EUROPEAN CALL =======================") callOption = FinEquityVanillaOption(expiry_date, strikePrice, FinOptionTypes.EUROPEAN_CALL) value = callOption.value(valuation_date, stock_price, discount_curve, dividendCurve, model) delta = callOption.delta(valuation_date, stock_price, discount_curve, dividendCurve, model) gamma = callOption.gamma(valuation_date, stock_price, discount_curve, dividendCurve, model) theta = callOption.theta(valuation_date, stock_price, discount_curve, dividendCurve, model) testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta") testCases.print(value, delta, gamma, theta) payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.EUROPEAN params = np.array([1.0, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_stepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stock_price, discount_curve, dividendCurve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration) testCases.banner( "================== AMERICAN CALL =======================") payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.AMERICAN params = np.array([1.0, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_stepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stock_price, discount_curve, dividendCurve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration)
def test_FinIborBermudanSwaptionBKModel(): """ 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 exerciseDate = settlement_date.addYears(1) swapMaturityDate = settlement_date.addYears(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 = FinIborSwap(exerciseDate, swapMaturityDate, FinSwapTypes.PAY, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fwdSwapValue = fwdPAYSwap.value(settlement_date, libor_curve, libor_curve) testCases.header("LABEL", "VALUE") testCases.print("FWD SWAP VALUE", fwdSwapValue) # fwdPAYSwap.printFixedLegPV() # Now we create the European swaptions fixed_legType = FinSwapTypes.PAY europeanSwaptionPay = FinIborSwaption(settlement_date, exerciseDate, swapMaturityDate, fixed_legType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fixed_legType = FinSwapTypes.RECEIVE europeanSwaptionRec = FinIborSwaption(settlement_date, exerciseDate, swapMaturityDate, fixed_legType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) ########################################################################### ########################################################################### ########################################################################### # BLACK'S MODEL ########################################################################### ########################################################################### ########################################################################### testCases.banner("======= ZERO VOLATILITY ========") model = FinModelBlack(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 = FinModelBlack(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 numTimeSteps = 100 model = FinModelRatesBK(sigma, a, numTimeSteps) 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 = FinModelRatesBK(sigma, a, numTimeSteps) 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_legType = FinSwapTypes.PAY exerciseType = FinExerciseTypes.EUROPEAN bermudanSwaptionPay = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fixed_legType = FinSwapTypes.RECEIVE exerciseType = FinExerciseTypes.EUROPEAN bermudanSwaptionRec = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, 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 = FinModelRatesBK(sigma, a, numTimeSteps) testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BK PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 = FinModelRatesBK(sigma, a, numTimeSteps) testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BK PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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_legType = FinSwapTypes.PAY exerciseType = FinExerciseTypes.BERMUDAN bermudanSwaptionPay = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fixed_legType = FinSwapTypes.RECEIVE exerciseType = FinExerciseTypes.BERMUDAN bermudanSwaptionRec = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, 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 = FinModelRatesBK(sigma, a, numTimeSteps) testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BK PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 = FinModelRatesBK(sigma, a, numTimeSteps) testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BK PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 numTimeSteps = 200 model = FinModelRatesBDT(sigma, numTimeSteps) 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 = FinModelRatesBDT(sigma, numTimeSteps) 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_legType = FinSwapTypes.PAY exerciseType = FinExerciseTypes.EUROPEAN bermudanSwaptionPay = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fixed_legType = FinSwapTypes.RECEIVE bermudanSwaptionRec = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) testCases.banner( "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BDT MODEL ========" ) # Used BK with constant short-rate volatility sigma = 0.000001 model = FinModelRatesBDT(sigma, numTimeSteps) testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BDT PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 = FinModelRatesBDT(sigma, numTimeSteps) testCases.banner("BDT MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BDT PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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_legType = FinSwapTypes.PAY exerciseType = FinExerciseTypes.BERMUDAN bermudanSwaptionPay = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fixed_legType = FinSwapTypes.RECEIVE bermudanSwaptionRec = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, 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 = FinModelRatesBDT(sigma, numTimeSteps) testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BDT PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 = FinModelRatesBDT(sigma, numTimeSteps) # print("BDT MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BDT PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 numTimeSteps = 200 model = FinModelRatesHW(sigma, a, numTimeSteps) 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 = FinModelRatesHW(sigma, a, numTimeSteps) 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_legType = FinSwapTypes.PAY exerciseType = FinExerciseTypes.EUROPEAN bermudanSwaptionPay = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fixed_legType = FinSwapTypes.RECEIVE bermudanSwaptionRec = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) testCases.banner( "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE HW MODEL ========" ) sigma = 0.000001 model = FinModelRatesHW(sigma, a, numTimeSteps) testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BDT PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 = FinModelRatesHW(sigma, a, numTimeSteps) testCases.banner("BDT MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN BDT PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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_legType = FinSwapTypes.PAY exerciseType = FinExerciseTypes.BERMUDAN bermudanSwaptionPay = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, swapFixedCoupon, swapFixedFrequencyType, swapFixedDayCountType) fixed_legType = FinSwapTypes.RECEIVE bermudanSwaptionRec = FinIborBermudanSwaption( settlement_date, exerciseDate, swapMaturityDate, fixed_legType, exerciseType, 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 = FinModelRatesHW(sigma, a, numTimeSteps) testCases.banner("HW MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN HW PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.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 = FinModelRatesHW(sigma, a, numTimeSteps) testCases.banner("HW MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE") valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN HW PAY VALUE:", valuePay) valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model) testCases.print("BERMUDAN HW REC VALUE:", valueRec) payRec = valuePay - valueRec testCases.print("PAY MINUS RECEIVER :", payRec)
def test_FinEquityRainbowOption(): # import matplotlib.pyplot as plt valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 1, 2016) interestRate = 0.05 discount_curve = DiscountCurveFlat(valuation_date, interestRate) numAssets = 2 volatilities = np.ones(numAssets) * 0.3 dividend_yields = np.ones(numAssets) * 0.01 dividendCurves = [] for q in dividend_yields: dividendCurve = DiscountCurveFlat(valuation_date, q) dividendCurves.append(dividendCurve) stock_prices = np.ones(numAssets) * 100 num_pathsList = [10000] corrList = np.linspace(0.0, 0.999999, 6) strike = 100.0 testCases.banner( "===================================================================") testCases.banner(" CALL ON MAXIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.CALL_ON_MAXIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiry_date, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) for num_paths in num_pathsList: start = time.time() v = rainbowOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) v_MC = rainbowOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MAX Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON MAX Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ########################################################################## testCases.banner( "===================================================================") testCases.banner(" CALL ON MINIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.CALL_ON_MINIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiry_date, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) for num_paths in num_pathsList: start = time.time() v = rainbowOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) v_MC = rainbowOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MIN Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON MIN Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ############################################################################### testCases.banner( "===================================================================") testCases.banner(" PUT ON MAXIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.PUT_ON_MAXIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiry_date, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) for num_paths in num_pathsList: start = time.time() v = rainbowOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) v_MC = rainbowOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "PUT ON MAX Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "PUT ON MAX Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ########################################################################## testCases.banner( "===================================================================") testCases.banner(" PUT ON MINIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.PUT_ON_MINIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiry_date, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) for num_paths in num_pathsList: start = time.time() v = rainbowOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) v_MC = rainbowOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "PUT ON MIN Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "PUT ON MIN Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ########################################################################## numAssets = 2 volatilities = np.ones(numAssets) * 0.3 dividend_yields = np.ones(numAssets) * 0.01 stock_prices = np.ones(numAssets) * 100 strike = 100.0 correlation = 0.50 testCases.banner( "===================================================================") testCases.banner(" CALL ON 1st") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) for num_paths in num_pathsList: payoffType1 = FinEquityRainbowOptionTypes.CALL_ON_MAXIMUM payoffParams1 = [strike] rainbowOption1 = FinEquityRainbowOption(expiry_date, payoffType1, payoffParams1, numAssets) payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH payoffParams2 = [1, strike] rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2, payoffParams2, numAssets) start = time.time() v = rainbowOption1.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) v_MC = rainbowOption2.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MAX Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON 1st Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') testCases.banner( "===================================================================") testCases.banner(" CALL ON 2nd") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) for num_paths in num_pathsList: payoffType1 = FinEquityRainbowOptionTypes.CALL_ON_MINIMUM payoffParams1 = [strike] rainbowOption1 = FinEquityRainbowOption(expiry_date, payoffType1, payoffParams1, numAssets) payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH payoffParams2 = [2, strike] rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2, payoffParams2, numAssets) start = time.time() v = rainbowOption1.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) v_MC = rainbowOption2.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MIN Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON 2nd Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') testCases.banner( "===================================================================") testCases.banner(" CALL ON 1-5") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] num_paths = 10000 numAssets = 5 volatilities = np.ones(numAssets) * 0.3 dividend_yields = np.ones(numAssets) * 0.01 stock_prices = np.ones(numAssets) * 100 dividendCurves = [] for q in dividend_yields: dividendCurve = DiscountCurveFlat(valuation_date, q) dividendCurves.append(dividendCurve) # plt.figure(figsize=(10,8)) testCases.header("NUMPATHS", "CORRELATION", "NTD", "VALUE", "VALUE_MC", "TIME") for n in [1, 2, 3, 4, 5]: rainboxOptionValues = [] rainbowOptionValuesMC = [] payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH payoffParams2 = [n, strike] rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2, payoffParams2, numAssets) for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) start = time.time() v_MC = rainbowOption2.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, n, v, v_MC, duration) rainbowOptionValuesMC.append(v_MC) # plt.plot(corrList, rainbowOptionValuesMC, 'o-', label = "CALL Rainbow Option MC NTH = " + str(n)) # plt.xlabel("Correlation") # plt.legend(loc='best') testCases.banner( "===================================================================") testCases.banner(" PUT ON 1-5") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] num_paths = 10000 numAssets = 5 volatilities = np.ones(numAssets) * 0.3 dividend_yields = np.ones(numAssets) * 0.01 stock_prices = np.ones(numAssets) * 100 # plt.figure(figsize=(10,8)) testCases.header("NUMPATHS", "CORRELATION", "NTD", "VALUE", "VALUE_MC", "TIME") for n in [1, 2, 3, 4, 5]: rainboxOptionValues = [] rainbowOptionValuesMC = [] payoffType2 = FinEquityRainbowOptionTypes.PUT_ON_NTH payoffParams2 = [n, strike] rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2, payoffParams2, numAssets) for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) corrMatrix = betaVectorToCorrMatrix(betas) start = time.time() v_MC = rainbowOption2.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, correlation, n, v, v_MC, duration) rainbowOptionValuesMC.append(v_MC)
def test_FinFXVanillaOptionHullExample(): # Example from Hull 4th edition page 284 valuation_date = Date(1, 1, 2015) expiry_date = valuation_date.addMonths(4) spotFXRate = 1.60 volatility = 0.1411 domInterestRate = 0.08 forInterestRate = 0.11 model = FinModelBlackScholes(volatility) domDiscountCurve = DiscountCurveFlat(valuation_date, domInterestRate) forDiscountCurve = DiscountCurveFlat(valuation_date, forInterestRate) num_pathsList = [10000, 20000, 40000, 80000, 160000, 320000] testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") strikeFXRate = 1.60 for num_paths in num_pathsList: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = callOption.valueMC(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model, num_paths) end = time.time() duration = end - start testCases.print(num_paths, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) spotFXRates = spotFXRates / 100.0 num_paths = 100000 testCases.header("NUMPATHS", "CALL_VALUE_BS", "CALL_VALUE_MC", "TIME") for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = callOption.valueMC(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model, num_paths) end = time.time() duration = end - start testCases.print(num_paths, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) / 100.0 num_paths = 100000 testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "PUT_VALUE_MC", "TIME") for spotFXRate in spotFXRates: putOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") value = putOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = putOption.valueMC(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model, num_paths) end = time.time() duration = end - start testCases.print(spotFXRate, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) / 100.0 testCases.header("SPOT FX RATE", "CALL_VALUE_BS", "DELTA_BS", "VEGA_BS", "THETA_BS", "RHO_BS") for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) vega = callOption.vega(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) theta = callOption.theta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) # callOption.rho(valuation_date,stock_price, interestRate, # dividendYield, modelType, modelParams) rho = 999 testCases.print(spotFXRate, value, delta, vega, theta, rho) testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "DELTA_BS", "VEGA_BS", "THETA_BS", "RHO_BS") for spotFXRate in spotFXRates: putOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") value = putOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = putOption.delta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) vega = putOption.vega(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) theta = putOption.theta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) # putOption.rho(valuation_date,stock_price, interestRate, dividendYield, # modelType, modelParams) rho = 999 testCases.print(spotFXRate, value, delta, vega, theta, rho) ########################################################################## testCases.header("SPOT FX RATE", "VALUE_BS", "VOL_IN", "IMPLD_VOL") spotFXRates = np.arange(100, 200, 10) / 100.0 for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] impliedVol = callOption.impliedVolatility(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, value) testCases.print(spotFXRate, value, volatility, impliedVol)
def test_FinEquityVolSurface(verboseCalibration): valuation_date = Date(11, 1, 2021) stock_price = 3800.0 # Check expiry_dates = [ Date(11, 2, 2021), Date(11, 3, 2021), Date(11, 4, 2021), Date(11, 7, 2021), Date(11, 10, 2021), Date(11, 1, 2022), Date(11, 1, 2023) ] strikes = np.array([3037, 3418, 3608, 3703, 3798, 3893, 3988, 4178, 4557]) volSurface = [ [42.94, 31.30, 25.88, 22.94, 19.72, 16.90, 15.31, 17.54, 25.67], [37.01, 28.25, 24.19, 21.93, 19.57, 17.45, 15.89, 15.34, 21.15], [34.68, 27.38, 23.82, 21.85, 19.83, 17.98, 16.52, 15.31, 18.94], [31.41, 26.25, 23.51, 22.05, 20.61, 19.25, 18.03, 16.01, 15.90], [29.91, 25.58, 23.21, 22.01, 20.83, 19.70, 18.62, 16.63, 14.94], [29.26, 25.24, 23.03, 21.91, 20.81, 19.73, 18.69, 16.76, 14.63], [27.59, 24.33, 22.72, 21.93, 21.17, 20.43, 19.71, 18.36, 16.26] ] volSurface = np.array(volSurface) volSurface = volSurface / 100.0 r = 0.020 # USD discount_curve = DiscountCurveFlat(valuation_date, r) q = 0.010 # USD dividendCurve = DiscountCurveFlat(valuation_date, q) volFunctionType = FinVolFunctionTypes.SVI equitySurface = FinEquityVolSurface(valuation_date, stock_price, discount_curve, dividendCurve, expiry_dates, strikes, volSurface, volFunctionType) # tol = 1e-4 # equitySurface.checkCalibration(False, tol) if 1 == 0: # PLOT_GRAPHS: equitySurface.plotVolCurves() plt.figure() mins = strikes[0] * 0.5 maxs = strikes[-1] * 1.5 dbns = equitySurface.impliedDbns(mins, maxs, 1000) for i in range(0, len(dbns)): expiry_dateStr = str(equitySurface._expiry_dates[i]) plt.plot(dbns[i]._x, dbns[i]._densitydx, label=expiry_dateStr) plt.title(volFunctionType) plt.legend() print("SUM:", dbns[i].sum()) deltas = np.linspace(0.10, 0.90, 9) testCases.header("EXPIRY", "DELTA", "VOL", "STRIKE") for expiry_date in expiry_dates: for delta in deltas: vol = equitySurface.volatilityFromDeltaDate(delta, expiry_date) testCases.print(expiry_date, delta, vol[0], vol[1])
def test_FinEquityBasketOption(): import time valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 1, 2016) volatility = 0.30 interestRate = 0.05 discount_curve = DiscountCurveFlat(valuation_date, interestRate) ########################################################################## # Homogeneous Basket ########################################################################## numAssets = 5 volatilities = np.ones(numAssets) * volatility dividend_yields = np.ones(numAssets) * 0.01 stock_prices = np.ones(numAssets) * 100 dividendCurves = [] for q in dividend_yields: dividendCurve = DiscountCurveFlat(valuation_date, q) dividendCurves.append(dividendCurve) betaList = np.linspace(0.0, 0.999999, 11) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for num_paths in [10000]: callOption = FinEquityBasketOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_CALL, numAssets) betas = np.ones(numAssets) * beta corrMatrix = betaVectorToCorrMatrix(betas) start = time.time() v = callOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) vMC = callOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, beta, v, vMC, duration) ########################################################################## # INHomogeneous Basket ########################################################################## numAssets = 5 volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4]) dividend_yields = np.array([0.01, 0.02, 0.04, 0.01, 0.02]) stock_prices = np.array([100, 105, 120, 100, 90]) dividendCurves = [] for q in dividend_yields: dividendCurve = DiscountCurveFlat(valuation_date, q) dividendCurves.append(dividendCurve) betaList = np.linspace(0.0, 0.999999, 11) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for num_paths in [10000]: callOption = FinEquityBasketOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_CALL, numAssets) betas = np.ones(numAssets) * beta corrMatrix = betaVectorToCorrMatrix(betas) start = time.time() v = callOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) vMC = callOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, beta, v, vMC, duration) ########################################################################## # Homogeneous Basket ########################################################################## numAssets = 5 volatilities = np.ones(numAssets) * volatility dividend_yields = np.ones(numAssets) * 0.01 stock_prices = np.ones(numAssets) * 100 betaList = np.linspace(0.0, 0.999999, 11) dividendCurves = [] for q in dividend_yields: dividendCurve = DiscountCurveFlat(valuation_date, q) dividendCurves.append(dividendCurve) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for num_paths in [10000]: callOption = FinEquityBasketOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_PUT, numAssets) betas = np.ones(numAssets) * beta corrMatrix = betaVectorToCorrMatrix(betas) start = time.time() v = callOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) vMC = callOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, beta, v, vMC, duration) ########################################################################## # INHomogeneous Basket ########################################################################## numAssets = 5 volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4]) dividend_yields = np.array([0.01, 0.02, 0.04, 0.01, 0.02]) stock_prices = np.array([100, 105, 120, 100, 90]) betaList = np.linspace(0.0, 0.999999, 11) dividendCurves = [] for q in dividend_yields: dividendCurve = DiscountCurveFlat(valuation_date, q) dividendCurves.append(dividendCurve) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for num_paths in [10000]: callOption = FinEquityBasketOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_PUT, numAssets) betas = np.ones(numAssets) * beta corrMatrix = betaVectorToCorrMatrix(betas) start = time.time() v = callOption.value(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix) vMC = callOption.valueMC(valuation_date, stock_prices, discount_curve, dividendCurves, volatilities, corrMatrix, num_paths) end = time.time() duration = end - start testCases.print(num_paths, beta, v, vMC, duration)
def testFinModelBlackScholes(): valuation_date = Date(8, 5, 2015) expiry_date = Date(15, 1, 2016) strikePrice = 130.0 stock_price = 127.62 volatility = 0.20 interestRate = 0.001 dividendYield = 0.0163 optionType = FinOptionTypes.AMERICAN_CALL euOptionType = FinOptionTypes.EUROPEAN_CALL amOption = FinEquityAmericanOption(expiry_date, strikePrice, optionType) ameuOption = FinEquityAmericanOption(expiry_date, strikePrice, euOptionType) euOption = FinEquityVanillaOption(expiry_date, strikePrice, euOptionType) discount_curve = DiscountCurveFlat(valuation_date, interestRate, FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F) dividendCurve = DiscountCurveFlat(valuation_date, dividendYield, FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F) num_steps_per_year = 400 modelTree = FinModelBlackScholes(volatility, FinModelBlackScholesTypes.CRR_TREE, num_steps_per_year) v = amOption.value(valuation_date, stock_price, discount_curve, dividendCurve, modelTree) # print(v) modelApprox = FinModelBlackScholes(volatility, FinModelBlackScholesTypes.BARONE_ADESI) v = amOption.value(valuation_date, stock_price, discount_curve, dividendCurve, modelApprox) # print(v) v = ameuOption.value(valuation_date, stock_price, discount_curve, dividendCurve, modelTree) # print(v) v = euOption.value(valuation_date, stock_price, discount_curve, dividendCurve, modelTree) # print(v) amTreeValue = [] amBAWValue = [] euTreeValue = [] euAnalValue = [] volatility = 0.20
def test_BondOptionZEROVOLConvergence(): # Build discount curve settlement_date = Date(1, 9, 2019) rate = 0.05 discount_curve = DiscountCurveFlat(settlement_date, rate, FrequencyTypes.ANNUAL) # Bond details issue_date = Date(1, 9, 2014) 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 = Date(1, 12, 2021) face = 100.0 dfExpiry = discount_curve.df(expiry_date) fwdCleanValue = bond.clean_price_from_discount_curve( expiry_date, discount_curve) # fwdFullValue = bond.full_price_from_discount_curve(expiry_date, discount_curve) # print("BOND FwdCleanBondPx", fwdCleanValue) # print("BOND FwdFullBondPx", fwdFullValue) # 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, 100) 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 a = 0.1 model = FinModelRatesHW(sigma, a, 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)
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_BondOptionEuropeanConvergence(): # CONVERGENCE TESTS # COMPARE AMERICAN TREE VERSUS JAMSHIDIAN IN EUROPEAN LIMIT TO CHECK THAT # TREE HAS BEEN CORRECTLY CONSTRUCTED. FIND VERY GOOD AGREEMENT. # Build discount curve settlement_date = Date(1, 12, 2019) discount_curve = DiscountCurveFlat(settlement_date, 0.05, FrequencyTypes.CONTINUOUS) # Bond details issue_date = Date(1, 12, 2015) maturity_date = Date(1, 12, 2020) coupon = 0.05 freq_type = FrequencyTypes.ANNUAL accrual_type = DayCountTypes.ACT_ACT_ICMA bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type) # Option Details - put expiry in the middle of a coupon period expiry_date = Date(1, 3, 2020) strikePrice = 100.0 face = 100.0 timeSteps = range(100, 400, 100) strikePrice = 100.0 testCases.header("TIME", "N", "PUT_JAM", "PUT_TREE", "CALL_JAM", "CALL_TREE") for numTimeSteps in timeSteps: sigma = 0.05 a = 0.1 start = time.time() optionType = FinOptionTypes.EUROPEAN_PUT bondOption1 = BondOption(bond, expiry_date, strikePrice, face, optionType) model1 = FinModelRatesHW(sigma, a, numTimeSteps) v1put = bondOption1.value(settlement_date, discount_curve, model1) bondOption2 = BondOption(bond, expiry_date, strikePrice, face, optionType) model2 = FinModelRatesHW(sigma, a, numTimeSteps, FinHWEuropeanCalcType.EXPIRY_ONLY) v2put = bondOption2.value(settlement_date, discount_curve, model2) optionType = FinOptionTypes.EUROPEAN_CALL bondOption1 = BondOption(bond, expiry_date, strikePrice, face, optionType) model1 = FinModelRatesHW(sigma, a, numTimeSteps) v1call = bondOption1.value(settlement_date, discount_curve, model1) bondOption2 = BondOption(bond, expiry_date, strikePrice, face, optionType) model2 = FinModelRatesHW(sigma, a, numTimeSteps, FinHWEuropeanCalcType.EXPIRY_TREE) v2call = bondOption2.value(settlement_date, discount_curve, model2) end = time.time() period = end - start testCases.print(period, numTimeSteps, v1put, v2put, v1call, v2call)
def test_FinEquityLookBackOption(): valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 1, 2016) stock_price = 100.0 volatility = 0.3 interestRate = 0.05 dividendYield = 0.01 num_pathsRange = [10000] stock_priceRange = range(90, 110, 10) num_steps_per_year = 252 discount_curve = DiscountCurveFlat(valuation_date, interestRate) dividendCurve = DiscountCurveFlat(valuation_date, dividendYield) ############################################################################### testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_CALL for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFloatLookbackOption(expiry_date, optionType) stockMin = stock_price value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_CALL for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFloatLookbackOption(expiry_date, optionType) stockMin = stock_price - 10 value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_PUT for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFloatLookbackOption(expiry_date, optionType) stockMax = stock_price value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_PUT for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFloatLookbackOption(expiry_date, optionType) stockMax = stock_price + 10 value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, stockMax, value, valueMC, diff, timeElapsed) ############################################################################### ############################################################################### stock_priceRange = range(90, 110, 10) num_steps_per_year = 252 testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_CALL k = 95.0 for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFixedLookbackOption(expiry_date, optionType, k) stockMax = stock_price value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, k, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_CALL k = 100.0 for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFixedLookbackOption(expiry_date, optionType, k) stockMax = stock_price value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, k, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_CALL k = 105.0 for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFixedLookbackOption(expiry_date, optionType, k) stockMax = stock_price + 10.0 value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMax, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, k, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_PUT k = 95.0 for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFixedLookbackOption(expiry_date, optionType, k) stockMin = stock_price value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, k, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_PUT k = 100.0 for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFixedLookbackOption(expiry_date, optionType, k) stockMin = stock_price value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, k, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinOptionTypes.EUROPEAN_PUT k = 105.0 for stock_price in stock_priceRange: for num_paths in num_pathsRange: option = FinEquityFixedLookbackOption(expiry_date, optionType, k) stockMin = stock_price - 10.0 value = option.value( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin) start = time.time() valueMC = option.valueMC( valuation_date, stock_price, discount_curve, dividendCurve, volatility, stockMin, num_paths, num_steps_per_year) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( num_paths, optionType, stock_price, k, stockMin, value, valueMC, diff, timeElapsed)