Ejemplo n.º 1
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
Ejemplo n.º 2
0
 def bondOptionDetails(self):
     # calculate expiryTime, (coupon) startTims, payTimes, cashFlows, strike and
     # c/p flag as inputs to Hull White analytic formula
     details = {}
     details['callOrPut'] = 1.0 if self.underlyingSwap.payerOrReceiver==ql.VanillaSwap.Receiver else -1.0
     details['strike']    = 0.0
     refDate  = self.underlyingSwap.discHandle.referenceDate()
     details['expiryTime'] = ql.Actual365Fixed().yearFraction(refDate,self.exercise.dates()[0])
     fixedLeg = [ [ ql.Actual365Fixed().yearFraction(refDate,cf.date()), cf.amount() ]
                  for cf in self.underlyingSwap.swap.fixedLeg() ]
     details['fixedLeg'] = np.array(fixedLeg)
     floatLeg = [ [ ql.Actual365Fixed().yearFraction(refDate,ql.as_coupon(cf).accrualStartDate()),
                    ((1 + ql.as_coupon(cf).accrualPeriod()*ql.as_coupon(cf).rate()) *
                     self.underlyingSwap.discHandle.discount(ql.as_coupon(cf).accrualEndDate()) /
                     self.underlyingSwap.discHandle.discount(ql.as_coupon(cf).accrualStartDate()) - 1.0) *
                    ql.as_coupon(cf).nominal() 
                    ] 
                  for cf in self.underlyingSwap.swap.floatingLeg() ]
     details['floatLeg'] = np.array(floatLeg)    
     payTimes = [ floatLeg[0][0]  ]          +       \
                [ cf[0] for cf in floatLeg ] +       \
                [ cf[0] for cf in fixedLeg ] +       \
                [ ql.Actual365Fixed().yearFraction(refDate,ql.as_coupon(
                  self.underlyingSwap.swap.floatingLeg()[-1]).accrualEndDate()) ]
     caschflows = [ -ql.as_coupon(self.underlyingSwap.swap.floatingLeg()[0]).nominal() ] +  \
                  [ -cf[1] for cf in floatLeg ] +    \
                  [  cf[1] for cf in fixedLeg ] +    \
                  [ ql.as_coupon(self.underlyingSwap.swap.floatingLeg()[0]).nominal() ]
     details['payTimes'  ] = np.array(payTimes)
     details['cashFlows'] = np.array(caschflows)
     return details
Ejemplo n.º 3
0
 def makeSwaption(self,
                  vol,
                  volType=ql.ShiftedLognormal,
                  delivery=ql.Settlement.Physical,
                  settlementMethod=ql.Settlement.PhysicalOTC,
                  shift=0.02,
                  swapRebuild=True):
     if swapRebuild:
         self.makeSwap(self.optionTenor, self.swapTenor, self.fairRate)
     self.volHandle = ql.QuoteHandle(ql.SimpleQuote(vol))
     self.payerSwaption = ql.Swaption(
         self.payerSwap, ql.EuropeanExercise(self.exerciseDate), delivery,
         settlementMethod)
     self.receiverSwaption = ql.Swaption(
         self.receiverSwap, ql.EuropeanExercise(self.exerciseDate),
         delivery, settlementMethod)
     if volType == ql.ShiftedLognormal:
         swaptionEngine = ql.BlackSwaptionEngine(
             self.discountTermStructure,
             ql.QuoteHandle(ql.SimpleQuote(vol)), ql.Actual365Fixed(),
             shift)
     elif volType == ql.Normal:
         swaptionEngine = ql.BachelierSwaptionEngine(
             self.discountTermStructure,
             ql.QuoteHandle(ql.SimpleQuote(vol)), ql.Actual365Fixed())
     self.payerSwaption.setPricingEngine(swaptionEngine)
     self.receiverSwaption.setPricingEngine(swaptionEngine)
Ejemplo n.º 4
0
def ql_irr(cash_flow, first_amount, first_date):
    """ Calculate the IRR from a given cash flow

    :param cash_flow: list
        List of QuantLib.SimpleCashFlow (s)
    :param first_amount: Int
        The Amount of the first cash flow
    :param first_date: Date-Like
        The date of the first cash flow
    :return: float
    """

    ql.Settings.instance().evaluationDate = to_ql_date(first_date)
    try:
        fixed_rate = ql.CashFlows.yieldRate(cash_flow, float(first_amount),
                                            ql.Actual365Fixed(), ql.Compounded,
                                            ql.Annual, False, ql.Date(),
                                            ql.Date(), 1.0e-6, 1000, 0.05)
    except RuntimeError:
        try:
            fixed_rate = ql.CashFlows.yieldRate(cash_flow, float(first_amount),
                                                ql.Actual365Fixed(),
                                                ql.Compounded,
                                                ql.Annual, False, ql.Date(),
                                                ql.Date(), 1.0e-6, 1000, -0.1)
        except RuntimeError:
            fixed_rate = ql.CashFlows.yieldRate(cash_flow, float(first_amount),
                                                ql.Actual365Fixed(),
                                                ql.Compounded,
                                                ql.Annual, False, ql.Date(),
                                                ql.Date(), 1.0e-6, 1000, -0.5)
    return fixed_rate
Ejemplo n.º 5
0
    def setUp(self):
        self.calendar = ql.TARGET()
        self.today = self.calendar.adjust(ql.Date.todaysDate())
        ql.Settings.instance().evaluationDate = self.today

        projection_curve_handle = ql.RelinkableYieldTermStructureHandle()
        self.projection_rate = 0.01
        self.projection_quote_handle = ql.RelinkableQuoteHandle()
        projection_curve = ql.FlatForward(
            self.today, self.projection_quote_handle, ql.Actual365Fixed())
        projection_curve_handle.linkTo(projection_curve)

        self.discount_handle = ql.YieldTermStructureHandle(ql.FlatForward(
            self.today, ql.QuoteHandle(ql.SimpleQuote(0.0085)), ql.Actual365Fixed()))
        self.swap_engine = ql.DiscountingSwapEngine(self.discount_handle)

        self.idx = ql.Euribor6M(projection_curve_handle)

        self.exercises = [ql.Period(1, ql.Years), ql.Period(2, ql.Years),
                          ql.Period(3, ql.Years), ql.Period(5, ql.Years),
                          ql.Period(7, ql.Years), ql.Period(10, ql.Years)]
        self.lengths = [ql.Period(1, ql.Years), ql.Period(2, ql.Years),
                        ql.Period(3, ql.Years), ql.Period(5, ql.Years),
                        ql.Period(7, ql.Years), ql.Period(10, ql.Years),
                        ql.Period(15, ql.Years), ql.Period(20, ql.Years)]
        self.swap_type = [ql.VanillaSwap.Receiver, ql.VanillaSwap.Payer]
Ejemplo n.º 6
0
 def setUp(self):
     # we set up a QuantLib VanillaSwap as basic test object
     today     = ql.Date(5,ql.October,2020)
     ql.Settings.instance().evaluationDate = today
     # we need curves for the float leg
     discYtsH = ql.YieldTermStructureHandle(
         ql.FlatForward(today,0.01,ql.Actual365Fixed()))
     projYtsH = ql.YieldTermStructureHandle(
         ql.FlatForward(today,0.02,ql.Actual365Fixed()))
     index = ql.Euribor6M(projYtsH)
     # we set start in the future to avoid the need of index fixings
     startDate  = ql.Date(12,ql.October,2020)
     endDate    = ql.Date(12,ql.October,2030)
     calendar   = ql.TARGET()
     fixedTenor = ql.Period('1y')
     floatTenor = ql.Period('6m')
     fixedSchedule = ql.MakeSchedule(startDate,endDate,tenor=fixedTenor,calendar=calendar)
     floatSchedule = ql.MakeSchedule(startDate,endDate,tenor=floatTenor,calendar=calendar)
     swapType = ql.VanillaSwap.Payer
     vanillaSwap = ql.VanillaSwap(ql.VanillaSwap.Receiver,1.0,fixedSchedule,0.025,ql.Thirty360(),floatSchedule,index,0.0050,ql.Actual360())
     # we have all the incredients to price the swap - but not really needed for payoffs
     engine = ql.DiscountingSwapEngine(discYtsH)
     vanillaSwap.setPricingEngine(engine)
     # It is easier to work with legs instead of Swap intruments
     self.legs = [vanillaSwap.fixedLeg(), vanillaSwap.floatingLeg()]
     self.pors = [1.0, -1.0] if swapType==ql.VanillaSwap.Receiver else [-1.0, 1.0]
     self.discYtsH = discYtsH
Ejemplo n.º 7
0
 def swaptionDetails(self):
     # calculate times and cash flows as input to (cash-settled) swaption valuation
     details = {}
     details[
         'callOrPut'] = 1.0 if self.underlyingSwap.payerOrReceiver == ql.VanillaSwap.Receiver else -1.0
     details['strikeRate'] = self.underlyingSwap.fixedRate
     details['notional'] = self.underlyingSwap.notional
     refDate = self.underlyingSwap.discHandle.referenceDate()
     details['expiryTime'] = ql.Actual365Fixed().yearFraction(
         refDate,
         self.exercise.dates()[0])
     annuityLeg = [[
         ql.Actual365Fixed().yearFraction(refDate, cf.date()),
         ql.as_coupon(cf).accrualPeriod()
     ] for cf in self.underlyingSwap.swap.fixedLeg()]
     details['annuityLeg'] = np.array(annuityLeg)
     floatLeg = [[
         ql.Actual365Fixed().yearFraction(
             refDate,
             ql.as_coupon(cf).accrualStartDate()),
         ((1 + ql.as_coupon(cf).accrualPeriod() * ql.as_coupon(cf).rate()) *
          self.underlyingSwap.discHandle.discount(
              ql.as_coupon(cf).accrualEndDate()) /
          self.underlyingSwap.discHandle.discount(
              ql.as_coupon(cf).accrualStartDate()) - 1.0)
     ] for cf in self.underlyingSwap.swap.floatingLeg()]
     floatLeg = floatLeg + [[ floatLeg[0][0], 1.0 ]] + \
                [[ ql.Actual365Fixed().yearFraction(refDate,ql.as_coupon(
                  self.underlyingSwap.swap.floatingLeg()[-1]).accrualEndDate()), -1.0 ]]
     details['floatLeg'] = np.array(floatLeg)
     return details
Ejemplo n.º 8
0
 def setUp(self):
     self.todaysDate = ql.Date(5, ql.September, 2017)
     ql.Settings.instance().evaluationDate = self.todaysDate
     self.spotDate = ql.Date(7, ql.September, 2017)
     self.domestic_rate = ql.FlatForward(self.spotDate, 0.017,
                                         ql.Actual365Fixed())
     self.foreign_rate = ql.FlatForward(self.spotDate, 0.013,
                                        ql.Actual365Fixed())
Ejemplo n.º 9
0
 def npvRaw(self):
     # calculate npv manually using Bachelier formula
     # use this to cross-check npv calculation via QuantLib engine
     refDate  = self.underlyingSwap.discHandle.referenceDate()
     T = ql.Actual365Fixed().yearFraction(refDate,self.exercise.dates()[0])
     CallOrPutOnS = 1.0 if self.underlyingSwap.payerOrReceiver==ql.VanillaSwap.Payer else -1.0
     return self.annuity() * Bachelier(self.underlyingSwap.fixedRate,self.fairRate(),self.normalVolatility,T,CallOrPutOnS)
Ejemplo n.º 10
0
    def testOrnsteinUhlenbeckVsBachelier(self):
        """Testing Fdm Ornstein-Uhlenbeck pricing"""

        todaysDate = ql.Date(15, ql.January, 2020)
        ql.Settings.instance().evaluationDate = todaysDate

        dc = ql.Actual365Fixed()

        rTS = ql.FlatForward(todaysDate, 0.06, dc)

        strike = 110.0
        payoff = ql.PlainVanillaPayoff(ql.Option.Put, strike)

        maturityDate = todaysDate + ql.Period(2, ql.Years)

        exercise = ql.EuropeanExercise(maturityDate)

        option = ql.VanillaOption(payoff, exercise)

        x0 = 100
        sigma = 20.0
        speed = 5

        pdeEngine = ql.FdOrnsteinUhlenbeckVanillaEngine(
            ql.OrnsteinUhlenbeckProcess(speed, sigma, x0, x0), rTS, 50)

        option.setPricingEngine(pdeEngine)
        calculated = option.NPV()

        stdev = math.sqrt(sigma * sigma / (2 * speed))

        expected = ql.bachelierBlackFormula(ql.Option.Put, strike, x0, stdev,
                                            rTS.discount(maturityDate))

        self.assertAlmostEqual(calculated, expected, 2)
Ejemplo n.º 11
0
def jpy_3m_example():
    calendar = objects.get('JAPAN')
    start = ql.Date(15, 3, 2020)
    maturity = ql.Date(15, 6, 2020)

    fixedSchedule = ql.MakeSchedule(start,
                                    maturity,
                                    ql.Period('3M'),
                                    calendar=calendar)
    floatSchedule = ql.MakeSchedule(start,
                                    maturity,
                                    ql.Period('3M'),
                                    calendar=calendar)

    jpy_3m_crv = curves.get('JPY.3M')
    jpy_3m_yts = ql.YieldTermStructureHandle(jpy_3m_crv)

    jpy_libor_3m = objects.get('JPY.3M').clone(jpy_3m_yts)

    jpy_yts = ql.YieldTermStructureHandle(curves.get('JPY.OIS'))
    engine = ql.DiscountingSwapEngine(jpy_yts)

    swap = ql.VanillaSwap(ql.VanillaSwap.Receiver, 1e9, fixedSchedule,
                          -0.15 / 100, ql.Actual365Fixed(), floatSchedule,
                          jpy_libor_3m, 0, ql.Actual360())
    swap.setPricingEngine(engine)

    print(f"Swap NPV  : {swap.NPV():,.2f}")
    print(f"Swap Rate  : {swap.fairRate() * 100:,.6f}")
Ejemplo n.º 12
0
 def vega(self):
     refDate = self.underlyingSwap.discHandle.referenceDate()
     T = ql.Actual365Fixed().yearFraction(refDate, self.exercise.dates()[0])
     return (self.annuity() *
             BachelierVega(self.underlyingSwap.fixedRate, self.fairRate(),
                           self.normalVolatility, T) * 1.0e-4
             )  # 1bp scaling
Ejemplo n.º 13
0
    def testBSMRNDCalculator(self):
        """Testing Black-Scholes risk neutral density calculator"""

        dc = ql.Actual365Fixed()
        todaysDate = ql.Date(15, ql.January, 2020)

        r = 0.0
        q = 0.0
        vol = 0.2
        s0 = 100

        process = ql.BlackScholesMertonProcess(
            ql.QuoteHandle(ql.SimpleQuote(s0)),
            ql.YieldTermStructureHandle(ql.FlatForward(todaysDate, q, dc)),
            ql.YieldTermStructureHandle(ql.FlatForward(todaysDate, r, dc)),
            ql.BlackVolTermStructureHandle(
                ql.BlackConstantVol(todaysDate, ql.TARGET(), vol, dc)))

        rnd = ql.BSMRNDCalculator(process)

        t = 1.2
        x = math.log(80.0)

        mu = math.log(s0) + (r - q - 0.5 * vol * vol) * t

        calculated = rnd.pdf(x, t)

        stdev = vol * math.sqrt(t)

        expected = (1.0 / (math.sqrt(2 * math.pi) * stdev) *
                    math.exp(-0.5 * math.pow((x - mu) / stdev, 2.0)))

        self.assertAlmostEqual(calculated, expected, 8)
Ejemplo n.º 14
0
 def __init__(
     self,
     forward_rate: float,
     atm_forward_volatility: float,
     beta: float,
     nu: float,
     rho: float,
     reference_date: ql.Date,
     maturity_date: ql.Date,
     shift: float = 0.0,
     day_counter: ql.DayCounter = ql.Actual365Fixed()
 ) -> None:
     self.shift = shift
     if self.shift < 0.0:
         raise ValueError('Shift must be non-negative')
     self.shifted_forward_rate = forward_rate + self.shift
     if self.shifted_forward_rate < 0.0:
         raise ValueError('Shifted forward rate cannot be negative')
     self.atm_forward_volatility = atm_forward_volatility
     self.reference_date = reference_date
     self.maturity_date = maturity_date
     self.day_counter = day_counter
     self.time_to_maturity = self.compute_time_to_maturity()
     self.beta = beta
     self.nu = nu
     self.rho = rho
     self.alpha = self.update_alpha()
    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())
Ejemplo n.º 16
0
    def setUp(self):
        ql.Settings.instance().evaluationDate = ql.Date(26, 5, 2021)

        self.basis_point = 1.0e-4
        self.settlement_days = 2
        self.business_day_convention = ql.Following
        self.calendar = ql.TARGET()
        self.day_count = ql.Actual365Fixed()
        self.end_of_month = False
        base_ccy_idx_handle = ql.YieldTermStructureHandle(flat_rate(0.007))
        quoted_ccy_idx_handle = ql.YieldTermStructureHandle(flat_rate(0.015))
        self.base_ccy_idx = ql.Euribor3M(base_ccy_idx_handle)
        self.quote_ccy_idx = ql.USDLibor(
            ql.Period(3, ql.Months), quoted_ccy_idx_handle)
        self.collateral_ccy_handle = ql.YieldTermStructureHandle(
            flat_rate(0.009))
        # Cross currency basis swaps data source:
        #   N. Moreni, A. Pallavicini (2015)
        #   FX Modelling in Collateralized Markets: foreign measures, basis curves
        #   and pricing formulae.
        #   section 4.2.1, Table 2.
        self.cross_currency_basis_quotes = ((ql.Period(1, ql.Years), -14.5),
                                            (ql.Period(18, ql.Months), -18.5),
                                            (ql.Period(2, ql.Years), -20.5),
                                            (ql.Period(3, ql.Years), -23.75),
                                            (ql.Period(4, ql.Years), -25.5),
                                            (ql.Period(5, ql.Years), -26.5),
                                            (ql.Period(7, ql.Years), -26.75),
                                            (ql.Period(10, ql.Years), -26.25),
                                            (ql.Period(15, ql.Years), -24.75),
                                            (ql.Period(20, ql.Years), -23.25),
                                            (ql.Period(30, ql.Years), -20.50))
Ejemplo n.º 17
0
def build_nominal_term_structure(
        reference_date,
        nominal_data):
    nominal_dc = ql.Actual365Fixed()
    dates = [CAL.advance(reference_date, x[0]) for x in nominal_data]
    rates = [x[1] for x in nominal_data]
    return ql.ZeroCurve(dates, rates, nominal_dc)
Ejemplo n.º 18
0
 def getQLZeroCurve(self):
     #dates1=[ql.Date(i.serialNumber()) for i in dates]
     #zeros1=deepcopy(zeros)
     x1 = [i.serialNumber() for i in self.tenordates]
     y1 = self.zerorates
     x2 = [i.serialNumber() for i in self.basecurve.tenordates]
     y2 = self.basecurve.zerorates
     datesS = x1 + list(set(x2) - set(x1))  # get all unique dates
     datesS.sort()
     dates1 = []
     for i in range(0, len(datesS)):
         dates1.append(ql.Date(datesS[i]))
     if self.nullbeforefirstpillar:
         zeros1 = np.interp(datesS, x1, y1, left=0.0, right=y1[-1]) \
             + np.interp(datesS, x2, y2, left=y2[0], right=y2[-1])
     else:
         zeros1 = np.interp(datesS, x1, y1, left=y1[0], right=y1[-1]) \
              + np.interp(datesS, x2, y2, left=y2[0], right=y2[-1])
     dates1.insert(0, self.valuationdate)
     zeros1 = zeros1.tolist()
     zeros1.insert(0, zeros1[0])
     calendar = ql.WeekendsOnly()
     dates1.append(calendar.advance(dates1[-1], 1, ql.Years))
     zeros1.append(zeros1[-1])
     #  to do change us holiday?
     return ql.ZeroCurve(dates1, zeros1, ql.Actual365Fixed(),
                         ql.UnitedStates(), ql.Linear(), ql.Continuous)
Ejemplo n.º 19
0
def binomialmodels(stockprice, strikeprice, volatility, intrate, calcdate,
                   expdate, divrate, opttype, modelname, steps):
    day_count = ql.Actual365Fixed()
    calendar = ql.UnitedStates()

    calculation_date = ql.Date(calcdate.day, calcdate.month, calcdate.year)
    if opttype == "p":
        option_type = ql.Option.Put
    else:
        option_type = ql.Option.Call
    exp_date = ql.Date(expdate.day, expdate.month, expdate.year)
    ql.Settings.instance().evaluationDate = calculation_date
    payoff = ql.PlainVanillaPayoff(option_type, strikeprice)
    exercise = ql.AmericanExercise(calculation_date, exp_date)
    american_option = ql.VanillaOption(payoff, exercise)
    spot_handle = ql.QuoteHandle(ql.SimpleQuote(stockprice))

    flat_ts = ql.YieldTermStructureHandle(
        ql.FlatForward(calculation_date, intrate, day_count))
    dividend_yield = ql.YieldTermStructureHandle(
        ql.FlatForward(calculation_date, divrate, 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)

    binomial_engine = ql.BinomialVanillaEngine(bsm_process, modelname, steps)
    american_option.setPricingEngine(binomial_engine)

    return american_option.NPV()
Ejemplo n.º 20
0
    def __call__(self, date, csv_path, yts_handle_ois):
        yts_handle = ql.RelinkableYieldTermStructureHandle()
        cv_df = pd.read_csv(csv_path, index_col='Term')
        cv = cv_df.drop(
            columns=['Shift', 'Shifted Rate', 'Zero Rate', 'Discount'])
        cv['Market Rate'] = cv_df['Market Rate'] * 0.01
        helpers = ql.RateHelperVector()
        index_libor = ql.USDLibor(ql.Period('3m'), yts_handle)
        simple_quote = []

        for term, data in cv.iterrows():
            term = term.replace(' ', '')
            if term == '3MO':
                simple_quote.append(ql.SimpleQuote(float(data['Market Rate'])))
                helpers.append(
                    ql.DepositRateHelper(ql.QuoteHandle(simple_quote[-1]),
                                         index_libor))
            elif term[:2] == 'ED':
                simple_quote.append(
                    ql.SimpleQuote((1.0 - float(data['Market Rate'])) * 100))
                helpers.append(
                    ql.FuturesRateHelper(ql.QuoteHandle(simple_quote[-1]),
                                         ql.IMM.date(term[-2:]), index_libor))
            elif term[-2:] == 'YR':
                simple_quote.append(ql.SimpleQuote(float(data['Market Rate'])))
                swapIndex = ql.UsdLiborSwapIsdaFixAm(
                    ql.Period(term.replace('YR', 'y')))
                helpers.append(
                    ql.SwapRateHelper(ql.QuoteHandle(simple_quote[-1]),
                                      swapIndex, ql.QuoteHandle(), ql.Period(),
                                      yts_handle_ois))
        return ql.PiecewiseLogLinearDiscount(date, helpers,
                                             ql.Actual365Fixed())
    def setUp(self):
        self.today = ql.Date(21, ql.April, 2019)
        self.dc = ql.Actual365Fixed()
        ql.Settings.instance().evaluationDate = self.today

        self.domesticTS = ql.FlatForward(self.today, 0.025, self.dc)
        self.foreignTS = ql.FlatForward(self.today, 0.075, self.dc)
        self.fxVolTS = ql.BlackConstantVol(self.today, ql.TARGET(), 0.15, self.dc)

        self.quantoHelper = ql.FdmQuantoHelper(
            self.domesticTS, self.foreignTS, self.fxVolTS, -0.75, 1.0)

        self.divYieldTS = ql.FlatForward(self.today, 0.03, self.dc)

        divDate = ql.DateVector()
        divDate.push_back(self.today + ql.Period(6, ql.Months))

        divAmount = ql.DoubleVector()
        divAmount.push_back(8.0)

        maturityDate = self.today + ql.Period(9, ql.Months)

        self.option = ql.DividendVanillaOption(
            ql.PlainVanillaPayoff(ql.Option.Call, 105),
            ql.AmericanExercise(self.today, maturityDate),
            divDate,
            divAmount)
Ejemplo n.º 22
0
    def day_count_fraction(self, dcf):
        """
        day_count_fraction takes a string that is used in the
        conventions DataFrame, and returns the QuantLib-equivalent
        day-count object. This function takes all day-counters that are
        currently allowed in QuantLib.

        Currently, the function takes the following strings:
        Act360, Act365Fixed, ActAct, Bus252, 30360

        Args:
            dcf (str): day count fraction string

        Returns:
            object: QuantLib day-count-fraction object
        """
        if dcf == 'Act360':
            return qlib.Actual360()
        elif dcf == 'Act365Fixed':
            return qlib.Actual365Fixed()
        elif dcf == 'ActAct':
            return qlib.ActualActual()
        elif dcf == 'Bus252':
            return qlib.Business252()
        elif dcf == '30360':
            return qlib.Thirty360()
    def testPdeSolver(self):
        """ Testing BENCHOP-SLV SABR example value """

        today = ql.Date(8, 1, 2019)
        dc = ql.Actual365Fixed()
        maturityDate = today + ql.Period(10 * 365, ql.Days)
        maturityTime = dc.yearFraction(today, maturityDate)

        f0 = 0.07
        alpha = 0.4
        nu = 0.8
        beta = 0.5
        rho = -0.6
        strike = f0 * math.exp(-0.1 * math.sqrt(maturityTime))

        rTS = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.0, dc))

        # see https://ir.cwi.nl/pub/28249
        expected = 0.052450313614407

        option = ql.VanillaOption(
            ql.PlainVanillaPayoff(ql.Option.Call, strike),
            ql.EuropeanExercise(maturityDate))

        option.setPricingEngine(
            ql.FdSabrVanillaEngine(f0, alpha, beta, nu, rho, rTS, 30, 800, 30,
                                   1, 0.8))

        calculated = option.NPV()

        self.assertAlmostEqual(
            calculated,
            expected,
            4,
            msg="Unable to reproduce Le Floc'h-Kennedy SABR volalatility")
    def testHagenFormula(self):
        """ Testing Hagen et al. formula """

        today = ql.Date(9, 1, 2019)
        dc = ql.Actual365Fixed()
        maturityDate = today + ql.Period(6, ql.Months)
        maturityTime = dc.yearFraction(today, maturityDate)

        alpha = 0.35
        beta = 0.85
        nu = 0.75
        rho = 0.85
        f0 = 100.0
        strike = 110.0

        sabrVol = ql.sabrVolatility(strike, f0, maturityTime, alpha, beta, nu,
                                    rho)

        self.assertAlmostEqual(
            sabrVol,
            0.205953,
            6,
            msg="Unable to reproduce Hagen et al. SABR volalatility")

        flochKennedyVol = ql.sabrFlochKennedyVolatility(
            strike, f0, maturityTime, alpha, beta, nu, rho)

        self.assertAlmostEqual(
            flochKennedyVol,
            0.205447,
            6,
            msg="Unable to reproduce Le Floc'h-Kennedy SABR volalatility")
Ejemplo n.º 25
0
def call_price_exact(kappa, theta, beta, rho, v0, r, T, s0, K):
    strike_price = 110.0
    payoff = ql.PlainVanillaPayoff(ql.Option.Call, strike_price)
    # option data
    calculation_date = ql.Date(15, 1, 2011)
    maturity_date = ql.Date(15, 1, 2011 + T)
    spot_price = s0
    strike_price = K
    dividend_rate = 0.00
    option_type = ql.Option.Call
    risk_free_rate = r
    day_count = ql.Actual365Fixed()
    ql.Settings.instance().evaluationDate = calculation_date
    # construct the Heston process
    payoff = ql.PlainVanillaPayoff(option_type, strike_price)
    exercise = ql.EuropeanExercise(maturity_date)
    european_option = ql.VanillaOption(payoff, exercise)
    sigma = beta
    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))
    heston_process = ql.HestonProcess(flat_ts, dividend_yield, spot_handle, v0,
                                      kappa, theta, sigma, rho)
    engine = ql.AnalyticHestonEngine(ql.HestonModel(heston_process), 0.0000001,
                                     100000)
    european_option.setPricingEngine(engine)
    h_price = european_option.NPV()
    return h_price
Ejemplo n.º 26
0
def set_up_option(maturity_date, spot_price, strike_price, volatility,
                  risk_free_rate, calculation_date):
    # assume no dividend
    dividend_rate = 0.0
    option_type = ql.Option.Call
    day_count = ql.Actual365Fixed()
    calendar = ql.UnitedStates()

    ql.Settings.instance().evaluationDate = calculation_date
    # construct the European Option
    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)
    bsm_process.option = european_option

    return bsm_process
Ejemplo n.º 27
0
def to_ql_day_counter(arg):
    """Converts a string with day_counter name to the corresponding QuantLib object.

    Parameters
    ----------
    arg: str

    Returns
    -------
    QuantLib.DayCounter

    """
    if arg.upper() == "THIRTY360E":
        return ql.Thirty360(ql.Thirty360.European)
    elif arg.upper() == "THIRTY360":
        return ql.Thirty360()
    elif arg.upper() == "ACTUAL360":
        return ql.Actual360()
    elif arg.upper() == "ACTUAL365":
        return ql.Actual365Fixed()
    elif arg.upper() == "ACTUALACTUAL":
        return ql.ActualActual(ql.ActualActual.ISMA)
    elif arg.upper() == "ACTUALACTUALISMA":
        return ql.ActualActual(ql.ActualActual.ISMA)
    elif arg.upper() == "ACTUALACTUALISDA":
        return ql.ActualActual(ql.ActualActual.ISDA)
    elif arg.upper() == "BUSINESS252":
        return ql.Business252()
    else:
        raise ValueError(
            "Unable to convert {} to a QuantLib day counter".format(arg))
Ejemplo n.º 28
0
    def get_vanilla_option_price_sabr(self,
                                      strike,
                                      maturity_period,
                                      use_noarbsabr=False,
                                      option_type=ql.Option.Call):
        self.option = self.vanilla_option_helper(strike, maturity_period,
                                                 option_type)
        maturity = ql.Actual365Fixed().yearFraction(
            self.base_date,
            self.calendar.advance(self.base_date, maturity_period))

        if use_noarbsabr:
            sabr_vol = ql.sabrFlochKennedyVolatility(
                strike, self.handles['initS'].value(), maturity,
                self.handles['alpha'].value(), self.handles['beta'].value(),
                self.handles['nu'].value(), self.handles['rho'].value())
        else:
            sabr_vol = ql.sabrVolatility(strike, self.handles['initS'].value(),
                                         maturity,
                                         self.handles['alpha'].value(),
                                         self.handles['beta'].value(),
                                         self.handles['nu'].value(),
                                         self.handles['rho'].value())

        npv = ql.blackFormula(
            option_type, strike, self.handles['initS'].value(),
            sabr_vol * sqrt(maturity),
            exp(-self.handles['risk_free_rate'].value() * maturity))
        return npv
Ejemplo n.º 29
0
    def __init__(self,
                 tradeDate=FLAGS.TODAY,
                 maturity_date=FLAGS.MATURITY,
                 spot_price=FLAGS.SPOT,
                 process_parameters={
                     'drift': FLAGS.BS_DRIFT,
                     'sigma': FLAGS.BS_SIGMA
                 },
                 n_paths=FLAGS.SMALL_SAMPLE):
        """__init__.

        :param tradeDate:
        :param maturity_date:
        :param spot_price:
        :param process_parameters:
        :param n_paths:
        """

        self.tradeDate = tradeDate
        self.maturity_date = maturity_date
        self.spot_price = spot_price
        self.process_parameters = process_parameters
        self.n_paths = n_paths
        self.dates = scheduler(self.tradeDate, self.maturity_date)
        self._check()
        day_count = ql.Actual365Fixed()
        self.maturity = day_count.yearFraction(self.tradeDate,
                                               self.maturity_date)
def get_shanghai_repo_1m(date):
    calc_date = str_date_2_ql_date(date)
    ql.Settings.instance().evaluationDate = calc_date
    calendar = ql.China()
    bussiness_convention = ql.Following
    dayCount = ql.Actual365Fixed()
    end_of_month = False
    # 设置回购的基本信息
    w.start()
    # 获取上交所1d,2d,7d,14d,28d回购的数据,只取一个月期限内流动性好的品种
    repo_maturities = [
        ql.Period(1, ql.Days),
        ql.Period(2, ql.Days),
        ql.Period(7, ql.Days),
        ql.Period(14, ql.Days),
        ql.Period(28, ql.Days)
    ]
    repo_rates = w.wss(
        "204001.SH,204002.SH,204003.SH,204004.SH,204007.SH,204014.SH,204028.SH,204091.SH",
        "close", "tradeDate=20190121;priceAdj=U;cycle=D").Data[0]
    repo_rate_helpers = []
    for i, repo_maturity in enumerate(repo_maturities):
        repo_rate_helpers.append(
            ql.DepositRateHelper(
                ql.QuoteHandle(ql.SimpleQuote(repo_rates[i] / 100.0)),
                repo_maturity, 0, calendar, bussiness_convention, end_of_month,
                dayCount))
    return repo_rate_helpers