예제 #1
0
    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
예제 #3
0
 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()
예제 #4
0
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
예제 #6
0
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()
예제 #9
0
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