def GreeksFunc(self, option, process): engine = ql.AnalyticBarrierEngine(process) option.setPricingEngine(engine) try: if self.product.exercise_type == 'E': engine = ql.AnalyticBarrierEngine(process) option.setPricingEngine(engine) Greeks = pd.DataFrame([option.delta(),option.gamma(),option.vega()/100,option.theta()/365,option.rho()/100], columns = [''], \ index=['Delta','Gamma','Vega(%)','ThetaPerDay','Rho(%)']) elif self.product.exercise_type == 'A': #用BaroneAdesiWhaley离散法计算Greeks engine = ql.BaroneAdesiWhaleyEngine(process) #engine = ql.BinomialVanillaEngine(process, "crr", 100) #BTM option.setPricingEngine(engine) Greeks = self.Numerical_Greeks(option) else: raise ValueError #传入的参数self.product.exercise_type 无效 #缺少解析解时用离散法蒙特卡洛模拟,计算Greeks except: engine = ql.MCDiscreteArithmeticAPEngine( process, self.product.mc_str, self.product.is_bb, self.product.is_av, self.product.is_cv, self.product.n_require, self.product.tolerance, self.product.n_max, self.product.seed) option.setPricingEngine(engine) Greeks = self.Numerical_Greeks(option) return Greeks
def calculate_barrier_price(evaluation, barrier_option, hist_spots, process, engineType): barrier = barrier_option.barrier barrierType = barrier_option.barrierType barrier_ql = barrier_option.option_ql exercise = barrier_option.exercise payoff = barrier_option.payoff # barrier_engine = ql.BinomialBarrierEngine(process, 'crr', 400) # european_engine = ql.BinomialVanillaEngine(process, 'crr', 400) european_engine = ql.AnalyticEuropeanEngine(process) barrier_engine = ql.AnalyticBarrierEngine(process) barrier_ql.setPricingEngine(barrier_engine) option_ql = ql.EuropeanOption(payoff, exercise) option_ql.setPricingEngine(european_engine) # check if hist_spots hit the barrier if len(hist_spots) == 0: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() else: if barrierType == ql.Barrier.DownOut: if min(hist_spots) <= barrier: barrier_engine = None european_engine = None return 0.0, 0.0 else: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() elif barrierType == ql.Barrier.UpOut: if max(hist_spots) >= barrier: barrier_engine = None european_engine = None return 0.0, 0.0 else: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() elif barrierType == ql.Barrier.DownIn: if min(hist_spots) > barrier: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() else: option_price = option_ql.NPV() # option_delta = option_ql.delta() else: if max(hist_spots) < barrier: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() else: option_price = option_ql.NPV() # option_delta = option_ql.delta() barrier_engine = None european_engine = None barrier_ql = None option_ql = None if math.isnan(option_price): return 0.0 else: return option_price
def PricingFunc(self, option, process): '''设置定价引擎''' # 欧式、美式均为QuantLib.AnalyticBarrierEngine if self.product.exercise_type == 'E': engine = ql.AnalyticBarrierEngine(process) elif self.product.exercise_type == 'A': engine = ql.BaroneAdesiWhaleyEngine(process) else: pass option.setPricingEngine(engine) return option.NPV()
def get_engine(bsmprocess, engineType): if engineType == 'AnalyticEuropeanEngine': engine = ql.AnalyticEuropeanEngine(bsmprocess) elif engineType == 'BinomialVanillaEngine': engine = ql.BinomialVanillaEngine(bsmprocess, 'crr', 801) elif engineType == 'AnalyticBarrierEngine': engine = ql.AnalyticBarrierEngine(bsmprocess) elif engineType == 'BinomialBarrierEngine': engine = ql.BinomialBarrierEngine(bsmprocess, 'crr', 801) else: engine = None return engine
def calculate_effective_delta(evaluation, daycounter, calendar, barrier_option, spot, vol, dS=0.001): barrier_ql = barrier_option.option_ql process1 = evaluation.get_bsmprocess_cnstvol(daycounter, calendar, ql.SimpleQuote(spot + dS), vol) process2 = evaluation.get_bsmprocess_cnstvol(daycounter, calendar, ql.SimpleQuote(spot - dS), vol) barrier_engine1 = ql.AnalyticBarrierEngine(process1) barrier_engine2 = ql.AnalyticBarrierEngine(process2) barrier_ql.setPricingEngine(barrier_engine1) option_price1 = barrier_ql.NPV() barrier_ql.setPricingEngine(barrier_engine2) option_price2 = barrier_ql.NPV() delta_eff = (option_price1 - option_price2) / (2 * dS) return delta_eff
def BarrierOptionCalc(options): print(options) spot = ql.SimpleQuote(options["spot"]) strike = options["strike"] barrier = options["barrier"] barrierType = options["barrierType"] volatility = ql.SimpleQuote(options["volatility"]) maturity = options["maturity"] rf = ql.SimpleQuote(options["rf"]) optionType = options["optionType"] pricingEngine = options["pricingEngine"] optionExercise = options["optionExercise"] if not hasattr(ql.Barrier, barrierType): raise Exception("barrier type not understood") barrierType = getattr(ql.Barrier, barrierType) if not hasattr(ql.Option, optionType): raise Exception("option type not understood") optionType = getattr(ql.Option, optionType) today = ql.Settings.instance().evaluationDate maturity_date = today + int(maturity) divYield = 0. rebate = 0. # process = ql.BlackScholesMertonProcess( # ql.QuoteHandle(spot), # ql.YieldTermStructureHandle(ql.FlatForward(today, divYield, day_count)), # ql.YieldTermStructureHandle(ql.FlatForward(today, ql.QuoteHandle(rf), day_count)), # ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today, calendar, ql.QuoteHandle(volatility), day_count))) process = ql.BlackScholesProcess( ql.QuoteHandle(spot), ql.YieldTermStructureHandle( ql.FlatForward(today, ql.QuoteHandle(rf), day_count)), ql.BlackVolTermStructureHandle( ql.BlackConstantVol(today, calendar, ql.QuoteHandle(volatility), day_count))) if (optionExercise == "European"): optionExercise = ql.EuropeanExercise(maturity_date) elif (optionExercise == "American"): optionExercise = ql.AmericanExercise(today + 1, maturity_date) else: raise Exception("optionExercise not understood") timeSteps = 1000 gridPoints = 1000 if (pricingEngine == "Analytical"): pricingEngine = ql.AnalyticBarrierEngine(process) elif (pricingEngine == "AnalyticalBinary"): pricingEngine = ql.AnalyticBinaryBarrierEngine(process) elif (pricingEngine == "FD"): pricingEngine = ql.FdBlackScholesBarrierEngine(process, timeSteps, gridPoints) elif (pricingEngine == "MC"): pricingEngine = ql.MCBarrierEngine(process, 'pseudorandom', timeSteps=1, requiredTolerance=0.02, seed=42) elif (pricingEngine == "Binomial"): pricingEngine = ql.BinomialBarrierEngine(process, 'jr', timeSteps) else: raise Exception("pricingEngine not understood") option = ql.BarrierOption(barrierType, barrier, rebate, ql.PlainVanillaPayoff(optionType, strike), optionExercise) option.setPricingEngine(pricingEngine) results = {} for t in ["NPV", "delta", "vega", "theta", "rho", "gamma"]: try: results[t] = getattr(option, t)() except RuntimeError as e: print(t, e) results[t] = float('nan') if math.isnan(results["NPV"]): return results computegreeks(results, option, spot, volatility, rf, today) return results
def calculate_barrier_price_vol(evaluation, daycounter, calendar, barrier_option, hist_spots, spot, vol, engineType): evalDate = evaluation.evalDate ql.Settings.instance().evaluationDate = evalDate maturitydt = barrier_option.maturitydt optiontype = barrier_option.optionType strike = barrier_option.strike underlying = ql.SimpleQuote(spot) barrier = barrier_option.barrier barrierType = barrier_option.barrierType barrier_ql = barrier_option.option_ql exercise = barrier_option.exercise payoff = barrier_option.payoff process = evaluation.get_bsmprocess_cnstvol(daycounter, calendar, underlying, vol) # barrier_engine = ql.BinomialBarrierEngine(process, 'crr', 400) # european_engine = ql.BinomialVanillaEngine(process, 'crr', 400) european_engine = ql.AnalyticEuropeanEngine(process) barrier_engine = ql.AnalyticBarrierEngine(process) barrier_ql.setPricingEngine(barrier_engine) option_ql = ql.EuropeanOption(payoff, exercise) option_ql.setPricingEngine(european_engine) # check if hist_spots hit the barrier if len(hist_spots) == 0: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() option_delta = calculate_effective_delta(evaluation, daycounter, calendar, barrier_option, spot, vol) else: if barrierType == ql.Barrier.DownOut: if min(hist_spots) <= barrier or spot <= barrier: barrier_engine = None european_engine = None return 0.0, 0.0 else: if evalDate < maturitydt: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() option_delta = calculate_effective_delta( evaluation, daycounter, calendar, barrier_option, spot, vol) else: if optiontype == ql.Option.Call: option_price = max(0.0, spot - strike) else: option_price = max(0.0, strike - spot) option_delta = 0.0 elif barrierType == ql.Barrier.UpOut: if max(hist_spots) >= barrier or spot >= barrier: barrier_engine = None european_engine = None return 0.0, 0.0 else: if evalDate < maturitydt: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() option_delta = calculate_effective_delta( evaluation, daycounter, calendar, barrier_option, spot, vol) else: if optiontype == ql.Option.Call: option_price = max(0.0, spot - strike) else: option_price = max(0.0, strike - spot) option_delta = 0.0 elif barrierType == ql.Barrier.DownIn: if min(hist_spots) <= barrier or spot <= barrier: # print('touched barrier') if evalDate < maturitydt: option_delta = option_ql.delta() option_price = option_ql.NPV() else: if optiontype == ql.Option.Call: option_price = max(0.0, spot - strike) else: option_price = max(0.0, strike - spot) option_delta = 0.0 else: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() option_delta = calculate_effective_delta( evaluation, daycounter, calendar, barrier_option, spot, vol) # if min(hist_spots) > barrier and spot > barrier: # option_price = barrier_ql.NPV() # # option_delta = barrier_ql.delta() # option_delta = calculate_effective_delta( # evaluation, daycounter, calendar, barrier_option, spot, vol) # else: # option_price = option_ql.NPV() # option_delta = option_ql.delta() else: if max(hist_spots) >= barrier or spot >= barrier: if evalDate < maturitydt: option_delta = option_ql.delta() option_price = option_ql.NPV() else: if optiontype == ql.Option.Call: option_price = max(0.0, spot - strike) else: option_price = max(0.0, strike - spot) option_delta = 0.0 else: option_price = barrier_ql.NPV() # option_delta = barrier_ql.delta() option_delta = calculate_effective_delta( evaluation, daycounter, calendar, barrier_option, spot, vol) # if max(hist_spots) < barrier and spot < barrier: # option_price = barrier_ql.NPV() # # option_delta = barrier_ql.delta() # option_delta = calculate_effective_delta( # evaluation, daycounter, calendar, barrier_option, spot, vol) # else: # option_price = option_ql.NPV() # option_delta = option_ql.delta() barrier_engine = None european_engine = None barrier_ql = None option_ql = None if math.isnan(option_price): return 0.0, 0.0 else: return option_price, option_delta
# bootstrap the yield/vol curves dayCounter = ql.Actual365Fixed() h1 = ql.QuoteHandle(riskFreeRate) h2 = ql.QuoteHandle(volatility) flatRate = ql.YieldTermStructureHandle( ql.FlatForward(0, ql.NullCalendar(), h1, dayCounter)) flatVol = ql.BlackVolTermStructureHandle( ql.BlackConstantVol(0, ql.NullCalendar(), h2, dayCounter)) # instantiate the option exercise = ql.EuropeanExercise(maturity) payoff = ql.PlainVanillaPayoff(type, strike) bsProcess = ql.BlackScholesProcess(ql.QuoteHandle(underlying), flatRate, flatVol) barrierEngine = ql.AnalyticBarrierEngine(bsProcess) europeanEngine = ql.AnalyticEuropeanEngine(bsProcess) referenceOption = ql.BarrierOption(barrierType, barrier, rebate, payoff, exercise) referenceOption.setPricingEngine(barrierEngine) referenceValue = referenceOption.NPV() tab1.add_row(["Original barrier option", referenceValue, 'N/A']) # Replicating portfolios portfolio1 = ql.CompositeInstrument() portfolio2 = ql.CompositeInstrument() portfolio3 = ql.CompositeInstrument()
maturity = 0.25 divYield = 0.0 V=[] delta=[] for s in S: underlying=s # Grids = (5 , 10 , 25 , 50 , 100 , 1000 , 5000) # maxG = Grids [ -1] # today = ql.Settings.instance().evaluationDate maturity_date = today + int ( maturity * 12) process = ql.BlackScholesMertonProcess(ql.QuoteHandle(ql.SimpleQuote(underlying)) , ql.YieldTermStructureHandle(ql.FlatForward(today , divYield , ql.Thirty360())) , ql.YieldTermStructureHandle(ql.FlatForward(today , rf , ql.Thirty360())) , ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today,ql.NullCalendar() , sigma , ql.Thirty360 ()))) option = ql.BarrierOption( barrierType , barrier , rebate , ql.PlainVanillaPayoff( optionType , strike), ql.EuropeanExercise(maturity_date)) option.setPricingEngine(ql.AnalyticBarrierEngine(process)) trueValue = option.NPV() #trueDelta=option.delta()w V.append(trueValue) #delta.append(trueDelta) plt.plot(V) #plt.plot(delta)
barrierType) # staticHedge = StaticHedgePortfolio(barrier_option) # staticHedge.set_static_portfolio(evaluation,spot,black_var_surface) strike_barrier = ((barrier)**2) / strike strike_barrierforward = ((barrier * np.exp(rf * ttm))**2) / strike strike_strikeforward = ((daily_close)**2) / strike print(maturitydt) print('init spot', daily_close) print('underlying : ', daily_close) print('barrier : ', barrier) print('strike : ', strike) # print('barrier forward : ', barrier * np.exp(rf * ttm)) european_engine = ql.AnalyticEuropeanEngine(process) barrier_engine = ql.AnalyticBarrierEngine(process) barrieroption.setPricingEngine(barrier_engine) barrier_price = barrieroption.NPV() init_barrier = barrier_price * facevalue # Construct Replicaiton Portfolio portfolio = ql.CompositeInstrument() # Long a call struck at strike call = ql.EuropeanOption(payoff, exercise) call.setPricingEngine(european_engine) call_value = call.NPV() print('call value : ', call_value) portfolio.add(call) # short put_ratio shares of puts struck at k_put k_put = strike_barrierforward