Exemplo n.º 1
0
def set_values(values):
    try:
        settlement_date = values["startDate"]
        days = ql.Actual365Fixed()
        calendar = ql.Japan()
        frequency = ql.Annual
        ql.Settings.instance().evaluationDate = values["startDate"]

        compounding = ql.Compounded

        payoff = ql.PlainVanillaPayoff(values["callput"],
                                       values["strikeprice"])

        eu_exercise = ql.EuropeanExercise(values["expirationdate"])
        european_option = ql.VanillaOption(payoff, eu_exercise)

        spot_handle = ql.QuoteHandle(ql.SimpleQuote(values["spotprice"]))
        rTS = ql.YieldTermStructureHandle(
            ql.FlatForward(settlement_date, values["domesticInterestrate"],
                           days, compounding, frequency))
        fTS = ql.YieldTermStructureHandle(
            ql.FlatForward(settlement_date, values["foreignInterestrate"],
                           days, compounding, frequency))
        flat_vol_ts = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(settlement_date, calendar,
                                values["volatility"], days))
        garman_kohlagen_process = ql.GarmanKohlagenProcess(
            spot_handle, fTS, rTS, flat_vol_ts)

        engine = ql.AnalyticEuropeanEngine(garman_kohlagen_process)

        european_option.setPricingEngine(engine)
        vol = float(
            european_option.impliedVolatility(values["premium"],
                                              garman_kohlagen_process,
                                              0.000000001,
                                              minVol=0.00001,
                                              maxVol=5.0) * 100)
        flat_vol_ts = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(settlement_date, calendar, vol / 100, days))
        garman_kohlagen_process = ql.GarmanKohlagenProcess(
            spot_handle, fTS, rTS, flat_vol_ts)
        engine = ql.AnalyticEuropeanEngine(garman_kohlagen_process)
        european_option.setPricingEngine(engine)
        return round(float(values["premium"]), 3), floatrounding(
            float(european_option.delta())), floatrounding(vol), None
    except Exception as e:
        message = 'Unkown Error Occured'

        if 'root not bracketed' in repr(e):
            message = server_responses.root_not_bracketed_error
        elif 'ValueError' in repr(e):
            message = server_responses.value_error
        if 'KeyError' in repr(e):
            message = server_responses.missing_key_error

        return None, None, None, message
Exemplo n.º 2
0
    def calculateImpliedVolatility(self, option_price, spot_price,
                                   strike_price, calculation_date,
                                   maturity_date, option_type):
        volatility = 0
        calendar = ql.China()
        payoff = ql.PlainVanillaPayoff(option_type, strike_price)
        exercise = ql.EuropeanExercise(maturity_date)
        european_option = ql.VanillaOption(payoff, exercise)
        spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_price))
        flat_ts = ql.YieldTermStructureHandle(
            ql.FlatForward(calculation_date, risk_free_rate, day_count))
        dividend_yield = ql.YieldTermStructureHandle(
            ql.FlatForward(calculation_date, dividend_rate, day_count))
        flat_vol_ts = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(calculation_date, calendar, volatility,
                                day_count))
        bsm_process = ql.BlackScholesMertonProcess(spot_handle, dividend_yield,
                                                   flat_ts, flat_vol_ts)
        vol = european_option.impliedVolatility(option_price, bsm_process)

        flat_vol_ts2 = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(calculation_date, calendar, vol, day_count))
        bsm_process2 = ql.BlackScholesMertonProcess(spot_handle,
                                                    dividend_yield, flat_ts,
                                                    flat_vol_ts2)
        european_option2 = ql.VanillaOption(payoff, exercise)
        european_option2.setPricingEngine(
            ql.AnalyticEuropeanEngine(bsm_process2))
        #     print european_option2.NPV() - option_price
        return vol, european_option2.delta()
 def __call__(self, vol):
     flat_vol_ts = ql.BlackVolTermStructureHandle(
         ql.BlackConstantVol(self._valuation_date, self._calendar, vol, self._day_count))
     bsm_process = ql.BlackScholesMertonProcess(self._forward_handle, self._dividend_handle, self._yc_handle,
                                                flat_vol_ts)
     self._european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))
     return self._european_option.NPV()
    def set_values(self,request_form):
        spot_rate = float(request_form['spotprice'])
        strike_rate = float(request_form['strikeprice'])
        domestic_interest_rate = float(request_form['domesticInterestrate'])
        foreign_interest_rate = float(request_form['foreignInterestrate'])
        volatility = float(request_form['volatility'])
        expiration_date = ql.Date(int(request_form['expirationdate'][8:10]),int(request_form['expirationdate'][5:7]),int(request_form['expirationdate'][0:4]))
        start_date = ql.Date(int(request_form['startdate'][8:10]),int(request_form['startdate'][5:7]),int(request_form['startdate'][0:4]))
        settlement_date = start_date
        days = ql.Actual365Fixed()
        calendar = ql.Japan()
        frequency = ql.Annual
        ql.Settings.instance().evaluationDate = start_date
        if(request_form['callput'] == 'call'):
            option_type = ql.Option.Call
        else:
            option_type = ql.Option.Put
        compounding = ql.Compounded

        payoff = ql.PlainVanillaPayoff(option_type, strike_rate)

        eu_exercise = ql.EuropeanExercise(expiration_date)
        european_option = ql.VanillaOption(payoff, eu_exercise)

        spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_rate))
        rTS = ql.YieldTermStructureHandle(ql.FlatForward(settlement_date,domestic_interest_rate, days,compounding, frequency))
        fTS = ql.YieldTermStructureHandle(ql.FlatForward(settlement_date,foreign_interest_rate, days,compounding, frequency))
        flat_vol_ts = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(settlement_date, calendar, volatility, days))
        garman_kohlagen_process = ql.GarmanKohlagenProcess(spot_handle, fTS, rTS, flat_vol_ts)

        engine = ql.AnalyticEuropeanEngine(garman_kohlagen_process)

        european_option.setPricingEngine(engine);
        return float(european_option.NPV()),float(european_option.delta())
Exemplo n.º 5
0
    def GreeksFunc(self, option, process):

        try:
            if self.product.exercise_type == 'E':
                engine = ql.AnalyticEuropeanEngine(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)

# =============================================================================
#         #无论亚美还是亚欧都一样
#         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)  #进入离散法计算Greeks
# =============================================================================

        return Greeks
Exemplo n.º 6
0
def plainvanilla(today, s, k, r, q, matDate, vol, flag):
    ql.Settings.instance().evaluationDate = ql.Date(today.day, today.month,
                                                    today.year)
    riskFreeRate = ql.FlatForward(today, r, ql.Actual365Fixed())
    # option parameters
    exercise = ql.EuropeanExercise(matDate)
    if (flag.lower() == "c" or flag.lower() == "call"):
        optionType = ql.Option.Call
    else:
        optionType = ql.Option.Put
    payoff = ql.PlainVanillaPayoff(optionType, k)

    underlying = ql.SimpleQuote(s)
    volatility = ql.BlackConstantVol(today, ql.SouthKorea(), vol,
                                     ql.Actual365Fixed())
    dividendYield = ql.FlatForward(today, q, ql.Actual365Fixed())
    process = ql.BlackScholesMertonProcess(
        ql.QuoteHandle(underlying), ql.YieldTermStructureHandle(dividendYield),
        ql.YieldTermStructureHandle(riskFreeRate),
        ql.BlackVolTermStructureHandle(volatility))
    option = ql.VanillaOption(payoff, exercise)

    # method: analytic
    option.setPricingEngine(ql.AnalyticEuropeanEngine(process))
    res = {
        "npv": option.NPV(),
        "delta": option.delta() * 0.01 * s,
        "gamma": option.gamma() * ((0.01 * s)**2),
        "theta": option.theta()
    }
    return res
Exemplo n.º 7
0
    def testQuantoTermStructure(self):
        """Testing quanto term structure"""
        today = ql.Date.todaysDate()

        dividend_ts = ql.YieldTermStructureHandle(
            ql.FlatForward(today, ql.QuoteHandle(ql.SimpleQuote(0.055)),
                           self.dayCounter))
        r_domestic_ts = ql.YieldTermStructureHandle(
            ql.FlatForward(today, ql.QuoteHandle(ql.SimpleQuote(-0.01)),
                           self.dayCounter))
        r_foreign_ts = ql.YieldTermStructureHandle(
            ql.FlatForward(today, ql.QuoteHandle(ql.SimpleQuote(0.02)),
                           self.dayCounter))
        sigma_s = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(today, self.calendar,
                                ql.QuoteHandle(ql.SimpleQuote(0.25)),
                                self.dayCounter))
        sigma_fx = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(today, self.calendar,
                                ql.QuoteHandle(ql.SimpleQuote(0.05)),
                                self.dayCounter))
        rho = ql.QuoteHandle(ql.SimpleQuote(0.3))
        s_0 = ql.QuoteHandle(ql.SimpleQuote(100.0))

        exercise = ql.EuropeanExercise(
            self.calendar.advance(today, 6, ql.Months))
        payoff = ql.PlainVanillaPayoff(ql.Option.Call, 95.0)

        vanilla_option = ql.VanillaOption(payoff, exercise)
        quanto_ts = ql.YieldTermStructureHandle(
            ql.QuantoTermStructure(dividend_ts, r_domestic_ts, r_foreign_ts,
                                   sigma_s, ql.nullDouble(), sigma_fx,
                                   ql.nullDouble(), rho.value()))
        gbm_quanto = ql.BlackScholesMertonProcess(s_0, quanto_ts,
                                                  r_domestic_ts, sigma_s)
        vanilla_engine = ql.AnalyticEuropeanEngine(gbm_quanto)
        vanilla_option.setPricingEngine(vanilla_engine)

        quanto_option = ql.QuantoVanillaOption(payoff, exercise)
        gbm_vanilla = ql.BlackScholesMertonProcess(s_0, dividend_ts,
                                                   r_domestic_ts, sigma_s)
        quanto_engine = ql.QuantoEuropeanEngine(gbm_vanilla, r_foreign_ts,
                                                sigma_fx, rho)
        quanto_option.setPricingEngine(quanto_engine)

        quanto_option_pv = quanto_option.NPV()
        vanilla_option_pv = vanilla_option.NPV()

        message = """Failed to reproduce QuantoOption / EuropeanQuantoEngine NPV:
                      {quanto_pv}
                      by using the QuantoTermStructure as the dividend together with
                      VanillaOption / AnalyticEuropeanEngine:
                      {vanilla_pv}
                  """.format(quanto_pv=quanto_option_pv,
                             vanilla_pv=vanilla_option_pv)

        self.assertAlmostEquals(quanto_option_pv,
                                vanilla_option_pv,
                                delta=1e-12,
                                msg=message)
Exemplo n.º 8
0
    def GreeksFunc(self, option, process):
        if self.exercise_type == 'E':
            engine = ql.AnalyticEuropeanEngine(process)
            option.setPricingEngine(engine)
            Greeks = pd.DataFrame([option.delta(),option.gamma(),option.vega()/100,option.theta()/365,option.rho()/100],\
                                   index=['Delta','Gamma','Vega(%)','ThetaPerDay','Rho(%)'])
        elif self.exercise_type == 'A':
            #用离散法计算Greeks
            engine = ql.BaroneAdesiWhaleyEngine(process)
            #engine = ql.BinomialVanillaEngine(process, "crr", 100)  #BTM
            option.setPricingEngine(engine)

            #Delta Gamma
            u0 = self.underlying_price.value()
            p0 = option.NPV()
            h = 0.01  #dS
            self.underlying_price.setValue(u0 + h)
            p_plus = option.NPV()
            #print(p_plus)
            self.underlying_price.setValue(u0 - h)
            p_minus = option.NPV()
            self.underlying_price.setValue(u0)
            delta = (p_plus - p_minus) / (2 * h)
            gamma = (p_plus - 2 * p0 + p_minus) / (h * h)

            #Vega
            v0 = self.volatility.value()
            h = 0.1
            self.volatility.setValue(v0 + h)
            print(self.volatility.value())
            p_plus = option.NPV()
            print(p_plus)
            self.volatility.setValue(v0)
            vega = (p_plus - p0) / h

            #Theta
            ql.Settings.instance().evaluationDate = self.vDate + 1
            p1 = option.NPV()
            h = 1 / 365.0
            theta = (p1 - p0) / h
            ql.Settings.instance().evaluationDate = self.vDate

            #Rho
            r0 = self.interest_rate.value()
            h = 0.0001
            self.interest_rate.setValue(r0 + h)
            p_plus = option.NPV()
            self.interest_rate.setValue(r0)
            rho = (p_plus - p0) / h

            Greeks = pd.DataFrame([delta,gamma,vega/100,theta/365,rho/100],\
                                   index=['Delta','Gamma','Vega(%)','ThetaPerDay','Rho(%)'])

        else:
            pass

        return Greeks
Exemplo n.º 9
0
 def get_vanilla_option_price_analytic(self,
                                       strike,
                                       maturity_period,
                                       option_type=ql.Option.Call):
     self.option = self.vanilla_option_helper(strike, maturity_period,
                                              option_type)
     self.engine = ql.AnalyticEuropeanEngine(self.process)
     self.option.setPricingEngine(self.engine)
     return self.option.NPV()
Exemplo n.º 10
0
 def reset_vol(self, vol):
     self.flat_vol_ts = ql.BlackVolTermStructureHandle(
         ql.BlackConstantVol(self.settlement, self.calendar, vol,
                             self.day_count))
     self.bsm_process = ql.BlackScholesMertonProcess(
         self.spot_handle, self.dividend_yield, self.flat_ts,
         self.flat_vol_ts)
     engine = ql.AnalyticEuropeanEngine(self.bsm_process)
     self.ql_option.setPricingEngine(engine)
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
Exemplo n.º 12
0
def bsm_quantlib():
    # 1.设置期权的五要素以及分红率和期权类型
    # 1.1五要素
    maturity_date = ql.Date(31, 7, 2020)
    spot_price = 9.37
    strike_price = 10.00
    volatility = 0.20  # the historical vols for a year
    risk_free_rate = 0.001
    # 1.2分红率
    dividend_rate = 0.01
    # 1.3期权类型
    option_type = ql.Option.Call

    # 1.4设置日期计算方式与使用地区
    day_count = ql.Actual365Fixed()
    calendar = ql.UnitedStates()
    # 1.5计算期权价格的日期,也就是估值日,我们设为今天
    calculation_date = ql.Date(31, 7, 2019)
    ql.Settings.instance().evaluationDate = calculation_date
    # 2.利用上的设置配置一个欧式期权
    payoff = ql.PlainVanillaPayoff(option_type, strike_price)
    exercise = ql.EuropeanExercise(maturity_date)
    # 2.1根据payoff与exercise完成欧式期权的构建
    european_option = ql.VanillaOption(payoff, exercise)

    # 3.构造我们的BSM定价引擎
    # 3.1 处理股票当前价格
    spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_price))
    # 3.2 根据之前的无风险利率和日期计算方式,构建利率期限结构
    flat_ts = ql.YieldTermStructureHandle(
        ql.FlatForward(calculation_date, risk_free_rate, day_count))
    # 3.3 设置分红率期限结构
    dividend_yield = ql.YieldTermStructureHandle(
        ql.FlatForward(calculation_date, dividend_rate, day_count))
    # 3.4 设置波动率结构
    flat_vol_ts = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(calculation_date, calendar, volatility, day_count))
    # 3.5 构造BSM定价引擎
    bsm_process = ql.BlackScholesMertonProcess(spot_handle, dividend_yield,
                                               flat_ts, flat_vol_ts)

    # 4使用BSM定价引擎计算
    european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))
    #bs_price = european_option.NPV()
    #print"The theoretical price is ", bs_price

    # RESULTS
    print("Option value =", european_option.NPV())
    print("Delta value  =", european_option.delta())
    print("Theta value  =", european_option.theta())
    print("Theta perday =", european_option.thetaPerDay())
    print("Gamma value  =", european_option.gamma())
    print("Vega value   =", european_option.vega())
    print("Rho value    =", european_option.rho())
Exemplo n.º 13
0
 def PricingFunc(self, option, process):
     '''------------- Set pricing engine, return both option and process -------------'''
     if self.exercise_type == 'E':
         engine = ql.AnalyticEuropeanEngine(process)
     elif self.exercise_type == 'A':
         engine = ql.BaroneAdesiWhaleyEngine(process)
         #engine = ql.BinomialVanillaEngine(process, "crr", 100)
     else:
         pass
     option.setPricingEngine(engine)
     return option.NPV()
Exemplo n.º 14
0
 def PricingFunc(self, option, process):
     '''设置定价引擎,返回 option, process'''
     if self.product.exercise_type == 'E':
         engine = ql.AnalyticEuropeanEngine(process)
     elif self.product.exercise_type == 'A':
         engine = ql.BaroneAdesiWhaleyEngine(process)
         #engine = ql.BinomialVanillaEngine(process, "crr", 100)
     else:
         pass
     option.setPricingEngine(engine)
     return option.NPV()
Exemplo n.º 15
0
    def get_BS_price(self,S=None, sigma = None,risk_free = None, \
               dividend = None, K = None, exercise_date = None, calculation_date = None, \
               day_count = None, dt = None, evaluation_method = "Numpy"):

        if evaluation_method is "QuantLib":
            # For our purpose, assume all inputs are scalar.
            stochastic_process = BlackScholesProcess(s0 = S, sigma = sigma, \
                     risk_free = risk_free, dividend = dividend, day_count=day_count)

            engine = ql.AnalyticEuropeanEngine(
                stochastic_process.get_process(calculation_date))

            ql_payoff = ql.PlainVanillaPayoff(ql.Option.Call, K)
            exercise_date = ql.EuropeanExercise(exercise_date)
            instrument = ql.VanillaOption(ql_payoff, exercise_date)

            if type(self.process).__name__ is "BlackScholesProcess":
                engine = ql.AnalyticEuropeanEngine(
                    self.process.get_process(calculation_date))

            instrument.setPricingEngine(engine)

            return instrument.NPV()
        elif evaluation_method is "Numpy":
            # For our purpose, assume s0 is a NumPy array, other inputs are scalar.
            T = np.arange(0, (exercise_date - calculation_date + 1)) * dt
            T = np.repeat(np.flip(T[None, :]), S.shape[0], 0)

            # Ignore division by 0 warning (expected behaviors as the limits of CDF is defined).
            with np.errstate(divide='ignore'):
                d1 = np.divide(
                    np.log(S / K) +
                    (risk_free - dividend + 0.5 * sigma**2) * T,
                    sigma * np.sqrt(T))
                d2 = np.divide(
                    np.log(S / K) +
                    (risk_free - dividend - 0.5 * sigma**2) * T,
                    sigma * np.sqrt(T))

            return (S * stats.norm.cdf(d1, 0.0, 1.0) -
                    K * np.exp(-risk_free * T) * stats.norm.cdf(d2, 0.0, 1.0))
Exemplo n.º 16
0
def euromodel(price, underline, expire, strike, spot_vol, t):
    exercise = ql.EuropeanExercise(ql.Settings.instance().evaluationDate +
                                   expire)
    payoff = ql.PlainVanillaPayoff(t, strike)
    option = ql.EuropeanOption(payoff, exercise)

    underline = ql.QuoteHandle(ql.SimpleQuote(underline))
    dividend = ql.YieldTermStructureHandle(
        ql.FlatForward(0, ql.TARGET(), 0, ql.Actual365Fixed()))
    risk_free_rate = ql.YieldTermStructureHandle(
        ql.FlatForward(0, ql.TARGET(), 0.00, ql.Actual365Fixed()))
    spot_vol = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(0, ql.TARGET(), spot_vol, ql.Actual365Fixed()))

    process = ql.BlackScholesMertonProcess(underline, dividend, risk_free_rate,
                                           spot_vol)
    option.setPricingEngine(ql.AnalyticEuropeanEngine(process))

    try:
        iv = option.impliedVolatility(price, process)
    except Exception as e:
        iv = 0

    fiv = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(0, ql.TARGET(), iv, ql.Actual365Fixed()))
    process = ql.BlackScholesMertonProcess(underline, dividend, risk_free_rate,
                                           fiv)
    option.setPricingEngine(ql.AnalyticEuropeanEngine(process))

    delta = option.delta()
    vega = option.vega()
    gamma = option.gamma()
    theta = option.theta()

    return {
        "iv": iv,
        "delta": delta,
        "vega": vega,
        "gamma": gamma,
        "theta": theta
    }
Exemplo n.º 17
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
Exemplo n.º 18
0
def calculate_effective_delta_svi2(hedge_date, daycounter, calendar, params_Mi,
                                   spot, rf_h_d, strike, maturitydt,
                                   optiontype):
    ql.Settings.instance().evaluationDate = hedge_date
    step = 0.005
    rf = rf_h_d
    yield_ts = ql.YieldTermStructureHandle(
        ql.FlatForward(hedge_date, rf, daycounter))
    dividend_ts = ql.YieldTermStructureHandle(
        ql.FlatForward(hedge_date, 0.0, daycounter))
    exercise = ql.EuropeanExercise(maturitydt)
    payoff = ql.PlainVanillaPayoff(optiontype, strike)
    option = ql.EuropeanOption(payoff, exercise)
    ttm = daycounter.yearFraction(hedge_date, maturitydt)

    s_plus = spot + step
    s_minus = spot - step
    Ft_plus = s_plus * math.exp(rf * ttm)
    x_plus = math.log(strike / Ft_plus, math.e)
    Ft_minus = s_minus * math.exp(rf * ttm)
    x_minus = math.log(strike / Ft_minus, math.e)
    iv_plus = implied_vol_function(params_Mi, x_plus)
    iv_minus = implied_vol_function(params_Mi, x_minus)
    flat_vol_plus = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(hedge_date, calendar, iv_plus, daycounter))
    flat_vol_minus = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(hedge_date, calendar, iv_minus, daycounter))

    process_plus = ql.BlackScholesMertonProcess(
        ql.QuoteHandle(ql.SimpleQuote(s_plus)), dividend_ts, yield_ts,
        flat_vol_plus)
    process_minus = ql.BlackScholesMertonProcess(
        ql.QuoteHandle(ql.SimpleQuote(s_minus)), dividend_ts, yield_ts,
        flat_vol_minus)
    option.setPricingEngine(ql.AnalyticEuropeanEngine(process_plus))
    npv_plus = option.NPV()
    option.setPricingEngine(ql.AnalyticEuropeanEngine(process_minus))
    npv_minus = option.NPV()
    delta = (npv_plus - npv_minus) / (s_plus - s_minus)
    return delta
Exemplo n.º 19
0
def calculate_graphLines(values):
    try:
        settlement_date = values["startDate"]
        days = ql.Actual365Fixed()
        calendar = ql.Japan()
        frequency = ql.Annual
        ql.Settings.instance().evaluationDate = values["startDate"]

        compounding = ql.Compounded

        payoff = ql.PlainVanillaPayoff(values["callput"],
                                       values["strikeprice"])

        eu_exercise = ql.EuropeanExercise(values["expirationdate"])
        european_option = ql.VanillaOption(payoff, eu_exercise)

        spot_handle = ql.QuoteHandle(ql.SimpleQuote(values["spotprice"]))
        rTS = ql.YieldTermStructureHandle(
            ql.FlatForward(settlement_date, values["domesticInterestrate"],
                           days, compounding, frequency))
        fTS = ql.YieldTermStructureHandle(
            ql.FlatForward(settlement_date, values["foreignInterestrate"],
                           days, compounding, frequency))
        flat_vol_ts = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(settlement_date, calendar,
                                values["volatility"], days))
        garman_kohlagen_process = ql.GarmanKohlagenProcess(
            spot_handle, fTS, rTS, flat_vol_ts)

        engine = ql.AnalyticEuropeanEngine(garman_kohlagen_process)

        european_option.setPricingEngine(engine)

        premium = float(european_option.NPV())

        x_axis_values, premium_values, intrinsic_values = [], [], []
        max_value, min_value = create_range(values)
        x_axis_values = create_x_axis_values(max_value, min_value, values)
        premium_values = create_premium_values(x_axis_values, premium, values)
        intrinsic_values = get_intrinsic_values(x_axis_values, premium, values)

        return x_axis_values, premium_values, intrinsic_values, None
    except Exception as e:
        message = 'Unkown Error Occured'
        if 'KeyError' in repr(e):
            message = server_responses.missing_key_error
        elif 'strike (inf)' in repr(e):
            message = server_responses.strike_outside_of_domain_curve_error
        elif 'ValueError' in repr(e):
            message = server_responses.value_error

        return None, None, None, message
def calculate_plain_price_vol(evaluation, daycounter, calendar, option,
                              hist_spots, spot, vol, engineType):
    underlying = ql.SimpleQuote(spot)
    option_ql = option.option_ql
    process = evaluation.get_bsmprocess_cnstvol(daycounter, calendar,
                                                underlying, vol)

    if engineType == 'BinomialEngine':
        engine = ql.BinomialVanillaEngine(process, 'crr', 400)
    else:
        engine = ql.AnalyticEuropeanEngine(process)
    option_ql.setPricingEngine(engine)
    option_price = option_ql.NPV()
    option_delta = option_ql.delta()
    return option_price, option_delta
Exemplo n.º 21
0
    def create_engine(self):
        if self.exercise_type == 'european':
            self.exercise = ql.EuropeanExercise(self.date_expiration)
            self.engine = ql.AnalyticEuropeanEngine(self.process)
        elif self.exercise_type == 'american':
            self.exercise = ql.AmericanExercise(self.date_evaluation,
                                                self.date_expiration)
            self.engine = ql.BinomialVanillaEngine(self.process, 'crr',
                                                   self.n_steps)
        else:
            raise Exception("Received unexpected exercise type "
                            f"'{self.exercise_type}'.")

        self.option = ql.VanillaOption(self.payoff, self.exercise)
        self.option.setPricingEngine(self.engine)
Exemplo n.º 22
0
 def GreeksFunc(self, option, process):
     if self.product.exercise_type == 'E':
         engine = ql.AnalyticEuropeanEngine(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':
         #用离散法计算Greeks
         engine = ql.BaroneAdesiWhaleyEngine(process)
         #engine = ql.BinomialVanillaEngine(process, "crr", 100)  #BTM
         option.setPricingEngine(engine)
         Greeks = self.Numerical_Greeks(option)  #进入离散法计算Greeks
     else:
         pass
     return Greeks
Exemplo n.º 23
0
def _gbm_option(val_date=FLAGS.TODAY,
                maturity_date=FLAGS.MATURITY,
                spot_price=FLAGS.SPOT,
                risk_free_rate=FLAGS.RF_RATE,
                sigma=FLAGS.BS_SIGMA,
                strike_price=FLAGS.STRIKE):
    """_gbm_option. Helper to create the option object in QuantLib

    :param val_date: valuation date
    :param maturity_date: maturity of the call option
    :param spot_price:
    :param risk_free_rate: risk free rate for the BS model
    :param sigma: volatility of the BS model
    :param strike_price: strike price of the call option
    """

    option_type = ql.Option.Call
    day_count = ql.Actual365Fixed()
    calendar = ql.UnitedStates()
    payoff = ql.PlainVanillaPayoff(option_type, strike_price)
    eu_exercise = ql.EuropeanExercise(maturity_date)
    european_option = ql.VanillaOption(payoff, eu_exercise)

    spot_handle = ql.QuoteHandle(
        ql.SimpleQuote(spot_price)
    )

    flat_ts = ql.YieldTermStructureHandle(
        ql.FlatForward(val_date, risk_free_rate, day_count)
    )

    dividend_rate = 0
    dividend_yield = ql.YieldTermStructureHandle(
        ql.FlatForward(val_date, dividend_rate, day_count)
    )

    flat_vol_ts = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(val_date, calendar, sigma, day_count)
    )

    bsm_process = ql.BlackScholesMertonProcess(spot_handle,
                                               dividend_yield,
                                               flat_ts,
                                               flat_vol_ts)

    european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))

    return european_option
Exemplo n.º 24
0
    def pricing(self, option_type, strike_price, expiry_date, valuation_date,
                underlying_price, dividend_rate, interest_rate, volatility):
        #         ------------- Option setup -------------
        if option_type.lower() in ['c', 'call']:
            put_or_call = ql.Option.Call
        elif option_type.lower() in ['p', 'put']:
            put_or_call = ql.Option.Put
        else:
            print('unknown option type:', option_type)
            return (-1)
        payoff = ql.PlainVanillaPayoff(put_or_call, strike_price)

        #         shift expiry date forward by 1 day, so that calculation can be done on the expiry day
        expiry_date_1 = expiry_date + dt.timedelta(days=1)
        eDate = ql.Date(expiry_date_1.day, expiry_date_1.month,
                        expiry_date_1.year)
        exercise = ql.EuropeanExercise(eDate)
        option = ql.VanillaOption(payoff, exercise)

        #         ------------- Process setup -------------
        valuation_date = min(expiry_date, valuation_date)
        vDate = ql.Date(valuation_date.day, valuation_date.month,
                        valuation_date.year)

        #         Set the valuation date, by default it will use today's date
        ql.Settings.instance().evaluationDate = vDate

        #         Calendar
        calendar = ql.China()
        day_counter = ql.ActualActual()

        #         Curve setup
        dividend_curve = ql.FlatForward(vDate, dividend_rate, day_counter)
        interest_curve = ql.FlatForward(vDate, interest_rate, day_counter)
        volatility_curve = ql.BlackConstantVol(vDate, calendar, volatility,
                                               day_counter)

        #         Setup Black Scholes Merton Process
        u = ql.QuoteHandle(ql.SimpleQuote(underlying_price))
        d = ql.YieldTermStructureHandle(dividend_curve)
        r = ql.YieldTermStructureHandle(interest_curve)
        v = ql.BlackVolTermStructureHandle(volatility_curve)
        process = ql.BlackScholesMertonProcess(u, d, r, v)

        #         ------------- Set pricing engine, return both option and process -------------
        engine = ql.AnalyticEuropeanEngine(process)
        option.setPricingEngine(engine)
        return (pd.Series({'option': option, 'process': process}))
Exemplo n.º 25
0
def getTheoOptionsPrice(calc_date, spot_price, strike_price, contract_type,
                        days_to_expire, vix):
    # option data
    #spot_price = 2970.27
    #strike_price = 2900
    volatility = vix  # the historical vols for a year
    dividend_rate = 0.0
    if contract_type == 'c':
        option_type = ql.Option.Call
    else:
        option_type = ql.Option.Put

    risk_free_rate = 0.000
    day_count = ql.Actual365Fixed()
    calendar = ql.UnitedStates()

    calculation_date = ql.Date(calc_date.day, calc_date.month, calc_date.year)
    (d, m, y) = getMaturityDate(calc_date, days_to_expire)
    maturity_date = ql.Date(d, m, y)
    ql.Settings.instance().evaluationDate = calculation_date
    settlement = calculation_date
    # construct the European Option
    payoff = ql.PlainVanillaPayoff(option_type, strike_price)
    exercise = ql.EuropeanExercise(maturity_date)
    european_option = ql.VanillaOption(payoff, exercise)

    am_exercise = ql.AmericanExercise(settlement, maturity_date)
    american_option = ql.VanillaOption(payoff, am_exercise)

    spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_price))
    flat_ts = ql.YieldTermStructureHandle(
        ql.FlatForward(calculation_date, risk_free_rate, day_count))
    dividend_yield = ql.YieldTermStructureHandle(
        ql.FlatForward(calculation_date, dividend_rate, day_count))
    flat_vol_ts = ql.BlackVolTermStructureHandle(
        ql.BlackConstantVol(calculation_date, calendar, volatility, day_count))
    bsm_process = ql.BlackScholesMertonProcess(spot_handle, dividend_yield,
                                               flat_ts, flat_vol_ts)

    european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))
    bs_price = european_option.NPV()
    print("The theoretical price is ", bs_price)
    steps = 200
    binomial_engine = ql.BinomialVanillaEngine(bsm_process, "crr", steps)
    american_option.setPricingEngine(binomial_engine)
    print(american_option.NPV())

    return bs_price
Exemplo n.º 26
0
def bs_opt(maturity_date,spot_price,strike_price,volatility,dividend_rate,option_type,risk_free_rate,day_count
          ,calendar,calculation_date):
    #payoff
    payoff = ql.PlainVanillaPayoff(option_type, strike_price)
    exercise = ql.EuropeanExercise(maturity_date)
    european_option = ql.VanillaOption(payoff, exercise)
    #process
    spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_price))
    flat_ts = ql.YieldTermStructureHandle(ql.FlatForward(calculation_date, risk_free_rate, day_count))
    dividend_yield = ql.YieldTermStructureHandle(ql.FlatForward(calculation_date, dividend_rate, day_count))
    flat_vol_ts = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(calculation_date, calendar, volatility, day_count))
    #price
    bsm_process = ql.BlackScholesMertonProcess(spot_handle, dividend_yield, flat_ts, flat_vol_ts)
    european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))
    bs_price = european_option.NPV()
    return bs_price
Exemplo n.º 27
0
 def __init__(self,
              dt_eval: datetime.date,
              dt_maturity: datetime.date,
              option_type: constant.OptionType,
              spot: float,
              strike: float,
              vol: float = 0.0,
              rf: float = 0.03,
              dividend_rate: float = 0.0):
     super().__init__()
     self.dt_eval = dt_eval
     self.dt_maturity = dt_maturity
     self.option_type = option_type
     self.values: typing.List[typing.List[float]] = []
     self.asset_values: typing.List[typing.List[float]] = []
     self.exercise_values: typing.List[typing.List[float]] = []
     self.strike = strike
     self.spot = spot
     self.vol = vol
     self.rf = rf
     self.dividend_rate = dividend_rate
     self.maturity_date = constant.QuantlibUtil.to_ql_date(dt_maturity)
     self.settlement = constant.QuantlibUtil.to_ql_date(dt_eval)
     ql.Settings.instance().evaluationDate = self.settlement
     if option_type == constant.OptionType.PUT:
         self.ql_option_type = ql.Option.Put
     else:
         self.ql_option_type = ql.Option.Call
     payoff = ql.PlainVanillaPayoff(self.ql_option_type, strike)
     self.exercise = ql.EuropeanExercise(self.maturity_date)
     self.ql_option = ql.VanillaOption(payoff, self.exercise)
     self.day_count = ql.ActualActual()
     self.calendar = ql.China()
     self.spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot))
     self.flat_ts = ql.YieldTermStructureHandle(
         ql.FlatForward(self.settlement, rf, self.day_count))
     self.dividend_yield = ql.YieldTermStructureHandle(
         ql.FlatForward(self.settlement, self.dividend_rate,
                        self.day_count))
     self.flat_vol_ts = ql.BlackVolTermStructureHandle(
         ql.BlackConstantVol(self.settlement, self.calendar, self.vol,
                             self.day_count))
     self.bsm_process = ql.BlackScholesMertonProcess(
         self.spot_handle, self.dividend_yield, self.flat_ts,
         self.flat_vol_ts)
     engine = ql.AnalyticEuropeanEngine(self.bsm_process)
     self.ql_option.setPricingEngine(engine)
Exemplo n.º 28
0
def to_ql_option_engine(engine_name=None, process=None, model=None):
    """ Returns a QuantLib.PricingEngine for Options

    :param engine_name: str
        The engine name
    :param process: QuantLib.StochasticProcess
        The QuantLib object with the option Stochastic Process.
    :param model: QuantLib.CalibratedModel
    :return: QuantLib.PricingEngine
    """
    if engine_name.upper() == 'BINOMIAL_VANILLA':
        return ql.BinomialVanillaEngine(process, 'LR', 801)
    elif engine_name.upper() == 'ANALYTIC_HESTON':
        if model is None:
            model = ql.HestonModel(process)
        elif model is not None and process is not None:
            model = model(process)
        return ql.AnalyticHestonEngine(model)
    elif engine_name.upper() == 'ANALYTIC_EUROPEAN':
        return ql.AnalyticEuropeanEngine(process)
    elif engine_name.upper() == 'ANALYTIC_EUROPEAN_DIVIDEND':
        return ql.AnalyticDividendEuropeanEngine(process)
    elif engine_name.upper() == "FINITE_DIFFERENCES":
        return ql.FdBlackScholesVanillaEngine(process)
    elif engine_name.upper() == 'HESTON_FINITE_DIFFERENCES':
        if model is None:
            model = ql.HestonModel(process)
        elif model is not None and process is not None:
            model = model(process)
        return ql.FdHestonVanillaEngine(model)
    elif engine_name.upper() == "BARONE_ADESI_WHALEY":
        return ql.BaroneAdesiWhaleyEngine(process)
    elif engine_name.upper() == "BJERKSUND_STENSLAND":
        return ql.BjerksundStenslandEngine(process)
    elif engine_name.upper() == "ANALYTIC_GJR_GARCH":
        if model is None:
            model = ql.GJRGARCHModel(process)
        elif model is not None and process is not None:
            model = model(process)
        return ql.AnalyticGJRGARCHEngine(model)
    elif engine_name.upper() == 'MC_GJR_GARCH':
        return ql.MCEuropeanGJRGARCHEngine(process=process,
                                           traits='pseudorandom',
                                           timeStepsPerYear=20,
                                           requiredTolerance=0.02)
    else:
        return None
Exemplo n.º 29
0
    def __init__(self,
                 maturity: ql.Period() = ql.Period(1, ql.Years),
                 tradeType: TradeType = TradeType.CALL,
                 tradeDirection: TradeDirection = TradeDirection.LONG,
                 underlying: Stock = Stock.ADS,
                 notional: float = 1,
                 strike: float = None):
        """
        Equity Option

        :param notional: Count of underlying shares
        :param maturity: Time to maturity of the option (in days). Will be used for both, M and T of paragraph 155 after being divided by 360
        :param tradeType: Can be TradeType.CALL or TradeType.PUT
        :param tradeDirection: Can be TradeDirection.LONG or TradeDirection.SHORT
        :param strike: Strike of option is no strike is given it default to an at the money option
        """
        self.underlying = underlying
        self.K = strike if strike != None else EquitySpotQuote[
            self.underlying.name].value.value(
            )  # no K is given it is the current Spot
        self.currency = underlying.value['Currency']
        self.ql_maturity = maturity
        super(EquityOption,
              self).__init__(assetClass=AssetClass.EQ,
                             tradeType=tradeType,
                             tradeDirection=tradeDirection,
                             m=convert_period_to_days(maturity) / 360,
                             t=convert_period_to_days(maturity) / 360,
                             notional=notional)
        vol_handle = EquityVolatility[self.underlying.name].value
        spot_handle = EquitySpot[self.underlying.name].value
        self.S = spot_handle.value()
        discounting_curve = DiscountCurve[self.currency.name].value
        black_scholes_process = ql.BlackScholesProcess(spot_handle,
                                                       discounting_curve.value,
                                                       vol_handle)
        engine = ql.AnalyticEuropeanEngine(black_scholes_process)
        if tradeType.name == TradeType.CALL.name:
            option_type = ql.Option.Call
        else:
            option_type = ql.Option.Put
        payoff = ql.PlainVanillaPayoff(option_type, self.K)
        maturity_date = today + maturity
        exercise = ql.EuropeanExercise(maturity_date)
        self.ql_option = ql.VanillaOption(payoff, exercise)
        self.ql_option.setPricingEngine(engine)
Exemplo n.º 30
0
def create_premium_values(x_axis_values, premium, values):
    values_array = []

    for item in x_axis_values:
        spot_rate = item
        settlement_date = values["startDate"]
        days = ql.Actual365Fixed()
        calendar = ql.Japan()
        frequency = ql.Annual
        ql.Settings.instance().evaluationDate = values["startDate"]

        compounding = ql.Compounded

        payoff = ql.PlainVanillaPayoff(values["callput"],
                                       values["strikeprice"])

        eu_exercise = ql.EuropeanExercise(values["expirationdate"])
        european_option = ql.VanillaOption(payoff, eu_exercise)

        spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_rate))
        rTS = ql.YieldTermStructureHandle(
            ql.FlatForward(settlement_date, values["domesticInterestrate"],
                           days, compounding, frequency))
        fTS = ql.YieldTermStructureHandle(
            ql.FlatForward(settlement_date, values["foreignInterestrate"],
                           days, compounding, frequency))
        flat_vol_ts = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(settlement_date, calendar,
                                values["volatility"], days))
        garman_kohlagen_process = ql.GarmanKohlagenProcess(
            spot_handle, fTS, rTS, flat_vol_ts)

        engine = ql.AnalyticEuropeanEngine(garman_kohlagen_process)

        european_option.setPricingEngine(engine)

        values_array.append(float(european_option.NPV()))

    if values["callput"] == ql.Option.Call:
        for i in range(0, len(values_array)):
            values_array[i] = values_array[i] - premium
    else:
        for i in range(0, len(values_array)):
            values_array[i] = values_array[i] - premium
    premium_values = values_array
    return premium_values