def evaluate_american_option(input_dict): tparams = input_dict["tradeParameters"] # Option Construction todaysDate = construct_date(tparams["evaluationDate"]) ql.Settings.instance().evaluationDate = todaysDate exercise = ql.AmericanExercise(todaysDate, construct_date(tparams["exerciseDate"])) payoff = ql.PlainVanillaPayoff(ql.Option.Put, tparams["payoff"]) option = ql.VanillaOption(payoff, exercise) # Market Data underlying = ql.SimpleQuote(tparams["underlying"]) dividendYield = ql.FlatForward(todaysDate, tparams["dividendYield"], ql.Actual365Fixed()) volatility = ql.BlackConstantVol(todaysDate, ql.TARGET(), tparams["volatility"], ql.Actual365Fixed()) riskFreeRate = ql.FlatForward(todaysDate, tparams["riskFreeRate"], ql.Actual365Fixed()) process = ql.BlackScholesMertonProcess( ql.QuoteHandle(underlying), ql.YieldTermStructureHandle(dividendYield), ql.YieldTermStructureHandle(riskFreeRate), ql.BlackVolTermStructureHandle(volatility), ) if input_dict["engineName"] == "BaroneAdesiWhaleyApproximationEngine": option.setPricingEngine(ql.BaroneAdesiWhaleyApproximationEngine(process)) elif input_dict["engineName"] == "BjerksundStenslandApproximationEngine": option.setPricingEngine(ql.BjerksundStenslandApproximationEngine(process)) elif input_dict["engineName"] == "FdBlackScholesVanillaEngine": timeSteps = input_dict["engineParameters"]["timeSteps"] gridPoints = input_dict["engineParameters"]["gridPoints"] option.setPricingEngine(ql.FdBlackScholesVanillaEngine(process, timeSteps, gridPoints)) elif input_dict["engineName"] == "BinomialVanillaEngine": timeSteps = input_dict["engineParameters"]["timeSteps"] # possible tree settings: ["JR", "CRR", "EQP", "Trigeorgis", "Tian", "LR", "Joshi4"] tree = input_dict["engineParameters"]["tree"] option.setPricingEngine(ql.BinomialVanillaEngine(process, tree, timeSteps)) else: raise Exception("Unimplemented engineName [{}]".format(input_dict["engineName"])) value = option.NPV() return value
# semi-analytic Bates for European method = 'Bates semi-analytic' batesProcess = ql.BatesProcess( flatTermStructure, flatDividendTS, underlyingH, volatility * volatility, 1.0, volatility * volatility, 0.001, 0.0, 1e-14, 1e-14, 1e-14) batesModel = ql.BatesModel(batesProcess) europeanOption.setPricingEngine( ql.BatesEngine(batesModel)) tab.add_row([method, europeanOption.NPV(), 'N/A', 'N/A']) # Barone-Adesi and Whaley approximation for American method = 'Barone-Adesi/Whaley' americanOption.setPricingEngine( ql.BaroneAdesiWhaleyApproximationEngine(bsmProcess)) tab.add_row([method, 'N/A', 'N/A', americanOption.NPV()]) # Bjerksund and Stensland approximation for American method = 'Bjerksund/Stensland' americanOption.setPricingEngine( ql.BjerksundStenslandApproximationEngine(bsmProcess)) tab.add_row([method, 'N/A', 'N/A', americanOption.NPV()]) # Integral method = 'Integral' europeanOption.setPricingEngine( ql.IntegralEngine(bsmProcess)) tab.add_row([method, europeanOption.NPV(), 'N/A', 'N/A']) # Finite differences
ql.BlackVolTermStructureHandle(volatility), ) # %% [markdown] # ### Pricing # # We'll collect tuples of method name, option value, and estimated error from the analytic formula. # %% results = [] # %% [markdown] # #### Analytic approximations # %% option.setPricingEngine(ql.BaroneAdesiWhaleyApproximationEngine(process)) results.append(("Barone-Adesi-Whaley", option.NPV())) # %% option.setPricingEngine(ql.BjerksundStenslandApproximationEngine(process)) results.append(("Bjerksund-Stensland", option.NPV())) # %% [markdown] # #### Finite-difference method # %% timeSteps = 801 gridPoints = 800 # %% option.setPricingEngine(