예제 #1
0
    def test_bucket_analysis_option(self):

        settings = Settings()

        calendar = TARGET()

        todays_date = Date(15, May, 1998)
        settlement_date = Date(17, May, 1998)

        settings.evaluation_date = todays_date

        option_type = Put
        underlying = 40
        strike = 40
        dividend_yield = 0.00
        risk_free_rate = 0.001
        volatility = 0.20
        maturity = Date(17, May, 1999)
        daycounter = Actual365Fixed()

        underlyingH = SimpleQuote(underlying)

        payoff = PlainVanillaPayoff(option_type, strike)

        flat_term_structure = FlatForward(reference_date=settlement_date,
                                          forward=risk_free_rate,
                                          daycounter=daycounter)
        flat_dividend_ts = FlatForward(reference_date=settlement_date,
                                       forward=dividend_yield,
                                       daycounter=daycounter)

        flat_vol_ts = BlackConstantVol(settlement_date, calendar, volatility,
                                       daycounter)

        black_scholes_merton_process = BlackScholesMertonProcess(
            underlyingH, flat_dividend_ts, flat_term_structure, flat_vol_ts)

        european_exercise = EuropeanExercise(maturity)
        european_option = VanillaOption(payoff, european_exercise)
        analytic_european_engine = AnalyticEuropeanEngine(
            black_scholes_merton_process)

        european_option.set_pricing_engine(analytic_european_engine)

        ba_eo = bucket_analysis([[underlyingH]], [european_option], [1], 0.50,
                                1)

        self.assertTrue(2, ba_eo)
        self.assertTrue(type(tuple), ba_eo)
        self.assertEqual(1, len(ba_eo[0][0]))
        self.assertAlmostEqual(-0.4582666150152517, ba_eo[0][0][0])
    def test_bucket_analysis_option(self):

        settings = Settings()

        calendar = TARGET()

        todays_date = Date(15, May, 1998)
        settlement_date = Date(17, May, 1998)

        settings.evaluation_date = todays_date

        option_type = Put
        underlying = 40
        strike = 40
        dividend_yield = 0.00
        risk_free_rate = 0.001
        volatility = SimpleQuote(0.20)
        maturity = Date(17, May, 1999)
        daycounter = Actual365Fixed()

        underlyingH = SimpleQuote(underlying)

        payoff = PlainVanillaPayoff(option_type, strike)

        flat_term_structure = FlatForward(reference_date=settlement_date,
                                          forward=risk_free_rate,
                                          daycounter=daycounter)
        flat_dividend_ts = FlatForward(reference_date=settlement_date,
                                       forward=dividend_yield,
                                       daycounter=daycounter)

        flat_vol_ts = BlackConstantVol(settlement_date, calendar, volatility,
                                       daycounter)

        black_scholes_merton_process = BlackScholesMertonProcess(
            underlyingH, flat_dividend_ts, flat_term_structure, flat_vol_ts)

        european_exercise = EuropeanExercise(maturity)
        european_option = VanillaOption(payoff, european_exercise)
        analytic_european_engine = AnalyticEuropeanEngine(
            black_scholes_merton_process)

        european_option.set_pricing_engine(analytic_european_engine)

        delta, gamma = bucket_analysis([underlyingH, volatility],
                                       [european_option],
                                       shift=1e-4,
                                       type=Centered)
        self.assertAlmostEqual(delta[0], european_option.delta)
        self.assertAlmostEqual(delta[1], european_option.vega)
        self.assertAlmostEqual(gamma[0], european_option.gamma, 5)
예제 #3
0
    def setUp(self):

        self.settings = Settings()

        self.calendar = TARGET()

        self.todays_date = Date(15, May, 1998)
        self.settlement_date = Date(17, May, 1998)

        self.settings.evaluation_date = self.todays_date

        # options parameters
        self.option_type = Put
        self.underlying = 36
        self.strike = 40
        self.dividend_yield = 0.00
        self.risk_free_rate = 0.06
        self.volatility = 0.20
        self.maturity = Date(17, May, 1999)
        self.daycounter = Actual365Fixed()

        self.underlyingH = SimpleQuote(self.underlying)

        # bootstrap the yield/dividend/vol curves
        self.flat_term_structure = FlatForward(
            reference_date = self.settlement_date,
            forward        = self.risk_free_rate,
            daycounter     = self.daycounter
        )
        self.flat_dividend_ts = FlatForward(
            reference_date = self.settlement_date,
            forward        = self.dividend_yield,
            daycounter     = self.daycounter
        )

        self.flat_vol_ts = BlackConstantVol(
            self.settlement_date,
            self.calendar,
            self.volatility,
            self.daycounter
        )

        self.black_scholes_merton_process = BlackScholesMertonProcess(
            self.underlyingH,
            self.flat_dividend_ts,
            self.flat_term_structure,
            self.flat_vol_ts
        )

        self.payoff = PlainVanillaPayoff(self.option_type, self.strike)
    def _get_option_npv(self):
        """ Suboptimal getter for the npv.

        FIXME: We currently have to recreate most of the objects because we do not
        expose enough of the QuantLib api.

        """

        # convert datetime object to QlDate
        maturity = QlDate.from_datetime(self.maturity)

        underlyingH = SimpleQuote(self.underlying)

        # bootstrap the yield/dividend/vol curves
        flat_term_structure = FlatForward(
            reference_date = settlement_date,
            forward = self.risk_free_rate,
            daycounter = self.daycounter
        )

        flat_dividend_ts = FlatForward(
            reference_date = settlement_date,
            forward = self.dividend_yield,
            daycounter = self.daycounter
        )

        flat_vol_ts = BlackConstantVol(
            settlement_date, calendar, self.volatility, self.daycounter
        )

        black_scholes_merton_process = BlackScholesMertonProcess(
            underlyingH, flat_dividend_ts, flat_term_structure,flat_vol_ts
        )

        payoff = PlainVanillaPayoff(self.option_type, self.strike)

        european_exercise = EuropeanExercise(maturity)

        european_option = VanillaOption(payoff, european_exercise)

        analytic_european_engine = AnalyticEuropeanEngine(black_scholes_merton_process)

        european_option.set_pricing_engine(analytic_european_engine)

        return european_option.net_present_value
예제 #5
0
    def test_analytic_cont_geo_av_price_greeks(self):
        
        tolerance = {}
        tolerance["delta"]  = 1.0e-5
        tolerance["gamma"]  = 1.0e-5
        # tolerance["theta"]  = 1.0e-5
        tolerance["rho"]    = 1.0e-5
        tolerance["divRho"] = 1.0e-5
        tolerance["vega"]   = 1.0e-5

        opt_types = [Call, Put]
        underlyings = [100.0]
        strikes = [90.0, 100.0, 110.0]
        q_rates = [0.04, 0.05, 0.06]
        r_rates = [0.01, 0.05, 0.15]
        lengths = [1, 2]
        vols = [0.11, 0.50, 1.20]
       
        spot = SimpleQuote(0.0)
        q_rate = SimpleQuote(0.0)
        r_rate = SimpleQuote(0.0)
        vol = SimpleQuote(0.0)

        q_ts = flat_rate(q_rate, self.daycounter)
        r_ts =  flat_rate(r_rate, self.daycounter)
        vol_ts = BlackConstantVol(self.today, self.calendar, vol, self.daycounter)

        process = BlackScholesMertonProcess(spot, q_ts, r_ts, vol_ts)

        calculated = {}
        expected = {}
        for opt_type, strike, length in product(opt_types, strikes, lengths):
            
            maturity = EuropeanExercise(self.today + length*Years)

            payoff = PlainVanillaPayoff(opt_type, strike)

            engine = AnalyticContinuousGeometricAveragePriceAsianEngine(process)

            option = ContinuousAveragingAsianOption(Geometric, payoff, maturity)
                
            option.set_pricing_engine(engine)

            for u, m, n, v in product(underlyings, q_rates, r_rates, vols):

                q = m 
                r = n
                spot.value = u
                q_rate.value = q
                r_rate.value = r
                vol.value = v

                value = option.npv
                calculated["delta"] = option.delta
                calculated["gamma"] = option.gamma
                # calculated["theta"] = option.theta
                calculated["rho"] = option.rho
                calculated["divRho"] = option.dividend_rho
                calculated["vega"] = option.vega

                if (value > spot.value*1.0e-5):
                    # perturb spot and get delta and gamma
                    du = u*1.0e-4
                    spot.value = u + du
                    value_p = option.npv
                    delta_p = option.delta
                    spot.value = u - du
                    value_m = option.npv
                    delta_m = option.delta
                    spot.value = u
                    expected["delta"] = (value_p - value_m)/(2*du)
                    expected["gamma"] = (delta_p - delta_m)/(2*du)

                    # perturb rates and get rho and dividend rho
                    dr = r*1.0e-4
                    r_rate.value = r + dr
                    value_p = option.npv
                    r_rate.value = r - dr
                    value_m = option.npv
                    r_rate.value = r
                    expected["rho"] = (value_p - value_m)/(2*dr)

                    dq = q*1.0e-4
                    q_rate.value = q + dq
                    value_p = option.npv
                    q_rate.value = q - dq
                    value_m = option.npv
                    q_rate.value = q
                    expected["divRho"] = (value_p - value_m)/(2*dq)

                    # perturb volatility and get vega
                    dv = v*1.0e-4
                    vol.value = v + dv
                    value_p = option.npv
                    vol.value = v - dv
                    value_m = option.npv
                    vol.value = v
                    expected["vega"] = (value_p - value_m)/(2*dv)

                    # perturb date and get theta
                    dt = self.daycounter.year_fraction(self.today - 1, self.today + 1)
                    self.settings.evaluation_date = self.today - 1
                    value_m = option.npv
                    self.settings.evaluation_date = self.today + 1
                    value_p = option.npv
                    self.settings.evaluation_date = self.today
                    expected["theta"] = (value_p - value_m)/dt

                    # compare
                    for greek, calcl in calculated.items():
                        expct = expected[greek]
                        tol = tolerance[greek]
                        error = relative_error(expct, calcl, u)
                        self.assertTrue(error < tol)
def main():
    # global data
    todays_date = Date(15, May, 1998)
    Settings.instance().evaluation_date = todays_date
    settlement_date = Date(17, May, 1998)

    risk_free_rate = FlatForward(reference_date=settlement_date,
                                 forward=0.06,
                                 daycounter=Actual365Fixed())

    # option parameters
    exercise = AmericanExercise(earliest_exercise_date=settlement_date,
                                latest_exercise_date=Date(17, May, 1999))
    payoff = PlainVanillaPayoff(Put, 40.0)

    # market data
    underlying = SimpleQuote(36.0)
    volatility = BlackConstantVol(todays_date, TARGET(), 0.20,
                                  Actual365Fixed())
    dividend_yield = FlatForward(reference_date=settlement_date,
                                 forward=0.00,
                                 daycounter=Actual365Fixed())

    # report
    header = '%19s' % 'method' + ' |' + \
        ' |'.join(['%17s' % tag for tag in ['value',
                                            'estimated error',
                                            'actual error']])
    print()
    print(header)
    print('-' * len(header))

    refValue = None

    def report(method, x, dx=None):
        e = '%.4f' % abs(x - refValue)
        x = '%.5f' % x
        if dx:
            dx = '%.4f' % dx
        else:
            dx = 'n/a'
        print('%19s' % method + ' |' +
              ' |'.join(['%17s' % y for y in [x, dx, e]]))

    # good to go

    process = BlackScholesMertonProcess(underlying, dividend_yield,
                                        risk_free_rate, volatility)

    option = VanillaOption(payoff, exercise)

    refValue = 4.48667344
    report('reference value', refValue)

    # method: analytic

    option.set_pricing_engine(BaroneAdesiWhaleyApproximationEngine(process))
    report('Barone-Adesi-Whaley', option.net_present_value)

    # method: finite differences
    time_steps = 801
    grid_points = 800

    option.set_pricing_engine(
        FDAmericanEngine('CrankNicolson', process, time_steps, grid_points))
    report('finite differences', option.net_present_value)

    print('This is work in progress.')
    print('Some pricing engines are not yet interfaced.')

    return

    option.set_pricing_engine(BjerksundStenslandEngine(process))
    report('Bjerksund-Stensland', option.NPV())

    # method: binomial
    timeSteps = 801

    option.setPricingEngine(BinomialVanillaEngine(process, 'jr', timeSteps))
    report('binomial (JR)', option.NPV())

    option.setPricingEngine(BinomialVanillaEngine(process, 'crr', timeSteps))
    report('binomial (CRR)', option.NPV())

    option.setPricingEngine(BinomialVanillaEngine(process, 'eqp', timeSteps))
    report('binomial (EQP)', option.NPV())

    option.setPricingEngine(
        BinomialVanillaEngine(process, 'trigeorgis', timeSteps))
    report('bin. (Trigeorgis)', option.NPV())

    option.setPricingEngine(BinomialVanillaEngine(process, 'tian', timeSteps))
    report('binomial (Tian)', option.NPV())

    option.setPricingEngine(BinomialVanillaEngine(process, 'lr', timeSteps))
    report('binomial (LR)', option.NPV())
예제 #7
0
underlyingH = SimpleQuote(underlying)

# bootstrap the yield/dividend/vol curves
flat_term_structure = FlatForward(reference_date=settlement_date,
                                  forward=risk_free_rate,
                                  daycounter=daycounter)

flat_dividend_ts = FlatForward(reference_date=settlement_date,
                               forward=dividend_yield,
                               daycounter=daycounter)

flat_vol_ts = BlackConstantVol(settlement_date, calendar, volatility,
                               daycounter)

black_scholes_merton_process = BlackScholesMertonProcess(
    underlyingH, flat_dividend_ts, flat_term_structure, flat_vol_ts)

payoff = PlainVanillaPayoff(option_type, strike)

european_exercise = EuropeanExercise(maturity)

european_option = VanillaOption(payoff, european_exercise)

method = 'Black-Scholes'
analytic_european_engine = AnalyticEuropeanEngine(black_scholes_merton_process)

european_option.set_pricing_engine(analytic_european_engine)

print('today: %s settlement: %s maturity: %s' %
      (todays_date, settlement_date, maturity))
print('NPV: %f\n' % european_option.net_present_value)
예제 #8
0
    def setUp(self):

        self.settings = Settings()

        self.calendar = TARGET()

        self.todays_date = Date(15, May, 1998)
        self.settlement_date = Date(17, May, 1998)

        self.settings.evaluation_date = self.todays_date

        # options parameters
        self.option_type = Put
        self.underlying = 36
        self.strike = 40
        self.dividend_yield = 0.00
        self.risk_free_rate = 0.06
        self.volatility = 0.20
        self.maturity = Date(17, May, 1999)
        self.daycounter = Actual365Fixed()

        self.underlyingH = SimpleQuote(self.underlying)

        # bootstrap the yield/dividend/vol curves
        self.flat_term_structure = FlatForward(
            reference_date=self.settlement_date,
            forward=self.risk_free_rate,
            daycounter=self.daycounter
        )
        self.flat_dividend_ts = FlatForward(
            reference_date=self.settlement_date,
            forward=self.dividend_yield,
            daycounter=self.daycounter
        )

        self.flat_vol_ts = BlackConstantVol(
            self.settlement_date,
            self.calendar,
            self.volatility,
            self.daycounter
        )

        self.black_scholes_merton_process = BlackScholesMertonProcess(
            self.underlyingH,
            self.flat_dividend_ts,
            self.flat_term_structure,
            self.flat_vol_ts
        )

        self.payoff = PlainVanillaPayoff(self.option_type, self.strike)

        #Additional parameters for testing DividendVanillaOption
        self.dividend_dates = []
        self.dividends = []
        self.american_time_steps = 600
        self.american_grid_points = 600

        #Parameters for implied volatility:
        self.accuracy = 0.001
        self.max_evaluations = 1000
        self.min_vol = 0.001
        self.max_vol = 4
        self.target_price = 4.485992