Ejemplo n.º 1
0
def blsprice(spot, strike, risk_free_rate, time, volatility,
             option_type='Call', dividend=0.0):
    """
    Black-Scholes option pricing model
    """
    spot = SimpleQuote(spot)

    daycounter = Actual360()
    risk_free_ts = FlatForward(today(), risk_free_rate, daycounter)
    dividend_ts = FlatForward(today(), dividend, daycounter)
    volatility_ts = BlackConstantVol(today(), NullCalendar(),
                                     volatility, daycounter)

    process = BlackScholesMertonProcess(spot, dividend_ts,
                                        risk_free_ts, volatility_ts)

    exercise_date = today() + 90
    exercise = EuropeanExercise(exercise_date)

    payoff = PlainVanillaPayoff(option_type, strike)

    option = EuropeanOption(payoff, exercise)
    engine = AnalyticEuropeanEngine(process)
    option.set_pricing_engine(engine)
    return option.npv
Ejemplo n.º 2
0
def _blsimpv(price, spot, strike, risk_free_rate, time,
             option_type='Call', dividend=0.0):

    spot = SimpleQuote(spot)
    daycounter = ActualActual()
    risk_free_ts = FlatForward(today(), risk_free_rate, daycounter)
    dividend_ts = FlatForward(today(), dividend, daycounter)
    volatility_ts = BlackConstantVol(today(), NullCalendar(),
                                     .3, daycounter)

    process = BlackScholesMertonProcess(spot, dividend_ts,
                                        risk_free_ts, volatility_ts)

    exercise_date = today() + Period(time * 365, Days)
    exercise = EuropeanExercise(exercise_date)

    payoff = PlainVanillaPayoff(option_type, strike)

    option = EuropeanOption(payoff, exercise)
    engine = AnalyticEuropeanEngine(process)
    option.set_pricing_engine(engine)

    accuracy = 0.001
    max_evaluations = 1000
    min_vol = 0.01
    max_vol = 2

    vol = option.implied_volatility(price, process,
            accuracy,
            max_evaluations,
            min_vol,
            max_vol)

    return vol
Ejemplo n.º 3
0
def _blsimpv(price, spot, strike, risk_free_rate, time, option_type, dividend):

    spot = SimpleQuote(spot)
    daycounter = ActualActual(ISMA)
    risk_free_ts = FlatForward(today(), risk_free_rate, daycounter)
    dividend_ts = FlatForward(today(), dividend, daycounter)
    volatility_ts = BlackConstantVol(today(), NullCalendar(), .3, daycounter)

    process = BlackScholesMertonProcess(spot, dividend_ts, risk_free_ts,
                                        volatility_ts)

    exercise_date = today() + Period(time * 365, Days)
    exercise = EuropeanExercise(exercise_date)

    payoff = PlainVanillaPayoff(option_type, strike)

    option = EuropeanOption(payoff, exercise)
    engine = AnalyticEuropeanEngine(process)
    option.set_pricing_engine(engine)

    accuracy = 0.001
    max_evaluations = 1000
    min_vol = 0.01
    max_vol = 2

    vol = option.implied_volatility(price, process, accuracy, max_evaluations,
                                    min_vol, max_vol)

    return vol
Ejemplo n.º 4
0
    def test_settings_instance_method(self):

        Settings.instance().evaluation_date = today()

        self.assertEqual(
                today(),
                Settings.instance().evaluation_date
        )
Ejemplo n.º 5
0
    def test_settings_instance_method(self):

        Settings.instance().evaluation_date = today()

        self.assertEqual(
                today(),
                Settings.instance().evaluation_date
        )
Ejemplo n.º 6
0
def zero_curve(ts):
    days = range(10, 365*20, 30)
    dtMat = [calendar.advance(today(), d, Days) for d in days]
    df = np.array([ts.discount(dt) for dt in dtMat])
    dtMat = [QLDateTodate(dt) for dt in dtMat]
    dtToday = QLDateTodate(today())
    dt = np.array([(d-dtToday).days/365.0 for d in dtMat])
    zc = -np.log(df) / dt
    return (dtMat, zc)
Ejemplo n.º 7
0
def zero_curve(ts):
    days = range(10, 365 * 20, 30)
    dtMat = [calendar.advance(today(), d, Days) for d in days]
    df = np.array([ts.discount(dt) for dt in dtMat])
    dtMat = [QLDateTodate(dt) for dt in dtMat]
    dtToday = QLDateTodate(today())
    dt = np.array([(d - dtToday).days / 365.0 for d in dtMat])
    zc = -np.log(df) / dt
    return (dtMat, zc)
Ejemplo n.º 8
0
def _blsprice(spot,
              strike,
              risk_free_rate,
              time,
              volatility,
              option_type='Call',
              dividend=0.0,
              calc='price'):
    """
    Black-Scholes option pricing model + greeks.
    """
    _spot = SimpleQuote(spot)

    daycounter = ActualActual(ISMA)
    risk_free_ts = FlatForward(today(), risk_free_rate, daycounter)
    dividend_ts = FlatForward(today(), dividend, daycounter)
    volatility_ts = BlackConstantVol(today(), NullCalendar(), volatility,
                                     daycounter)

    process = BlackScholesMertonProcess(_spot, dividend_ts, risk_free_ts,
                                        volatility_ts)

    exercise_date = today() + Period(time * 365, Days)
    exercise = EuropeanExercise(exercise_date)

    payoff = PlainVanillaPayoff(option_type, strike)

    option = EuropeanOption(payoff, exercise)
    engine = AnalyticEuropeanEngine(process)
    option.set_pricing_engine(engine)

    if calc == 'price':
        res = option.npv
    elif calc == 'delta':
        res = option.delta
    elif calc == 'gamma':
        res = option.gamma
    elif calc == 'theta':
        res = option.theta
    elif calc == 'rho':
        res = option.rho
    elif calc == 'vega':
        res = option.vega
    elif calc == 'lambda':
        res = option.delta * spot / option.npv
    else:
        raise ValueError('calc type %s is unknown' % calc)

    return res
Ejemplo n.º 9
0
    def setUp(self):
        settlement_date = today()

        settings = Settings()
        settings.evaluation_date = settlement_date

        daycounter = ActualActual()
        self.calendar = NullCalendar()

        i_rate = .1
        i_div = .04

        self.risk_free_ts = flat_rate(i_rate, daycounter)
        self.dividend_ts = flat_rate(i_div, daycounter)

        self.s0 = SimpleQuote(32.0)

        # Bates model

        self.v0 = 0.05
        self.kappa = 5.0
        self.theta = 0.05
        self.sigma = 1.0e-4
        self.rho = 0.0
        self.Lambda = .1
        self.nu = .01
        self.delta = .001
Ejemplo n.º 10
0
    def test_create_libor_index(self):

        settings = Settings.instance()

        # Market information
        calendar = UnitedStates(LiborImpact)

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)

        term_structure = YieldTermStructure(relinkable=True)
        term_structure.link_to(FlatForward(settlement_date, 0.05,
                                           Actual365Fixed()))

        index = Libor('USDLibor', Period(6, Months), settlement_days,
                      USDCurrency(), calendar, Actual360(),
                      term_structure)
        default_libor = USDLibor(Period(6, Months))
        for attribute in ["business_day_convention", "end_of_month",
                          "fixing_calendar", "joint_calendar", "tenor",
                          "fixing_days", "day_counter", "family_name", "name"]:
            self.assertEqual(getattr(index, attribute),
                             getattr(default_libor, attribute))
Ejemplo n.º 11
0
    def setUp(self):
        atm_option_tenors = [Period(1, Months), Period(6, Months)] + \
                            [Period(i, Years) for i in [1, 5, 10, 30]]
        atm_swap_tenors = [Period(1, Years), Period(5, Years), Period(10, Years),
                           Period(30, Years)]

        m = np.array([[.1300, .1560, .1390, .1220],
                      [.1440, .1580, .1460, .1260],
                      [.1600, .1590, .1470, .1290],
                      [.1640, .1470, .1370, .1220],
                      [.1400, .1300, .1250, .1100],
                      [.1130, .1090, .1070, .0930]])

        M = Matrix.from_ndarray(m)

        calendar = UnitedStates()
        self.atm_vol = SwaptionVolatilityMatrix(calendar,
                                                Following,
                                                atm_option_tenors,
                                                atm_swap_tenors,
                                                M,
                                                Actual365Fixed())

        reference_date = calendar.adjust(today())
        Settings().evaluation_date = reference_date
        self.term_structure = FlatForward(reference_date, 0.05, Actual365Fixed())
        self.swap_index = EuriborSwapIsdaFixA(Period(10, Years),
                                              forwarding=self.term_structure)
Ejemplo n.º 12
0
    def test_create_libor_index(self):

        settings = Settings.instance()

        # Market information
        calendar = UnitedStates(LiborImpact)

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)

        term_structure = YieldTermStructure(relinkable=True)
        term_structure.link_to(
            FlatForward(settlement_date, 0.05, Actual365Fixed()))

        index = Libor('USDLibor', Period(6, Months), settlement_days,
                      USDCurrency(), calendar, Actual360(), term_structure)
        default_libor = USDLibor(Period(6, Months))
        for attribute in [
                "business_day_convention", "end_of_month", "fixing_calendar",
                "joint_calendar", "tenor", "fixing_days", "day_counter",
                "family_name", "name"
        ]:
            self.assertEqual(getattr(index, attribute),
                             getattr(default_libor, attribute))
Ejemplo n.º 13
0
    def test_blsprice(self):

        from quantlib.settings import Settings
        from quantlib.time.api import today
        Settings.instance().evaluation_date = today()
        call_value = blsprice(100.0, 97.0, 0.1, 0.25, 0.5)
        self.assertAlmostEquals(call_value, 12.61, 2)
Ejemplo n.º 14
0
    def test_create_swap_index(self):

        settings = Settings.instance()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date


        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date);

        ibor_index = Libor('USD Libor', Period(6, Months), settlement_days,
                        USDCurrency(), calendar, Actual360())


        index = SwapIndex(
            'family name', Period(3, Months), 10, USDCurrency(), TARGET(),
            Period(12, Months), Following, Actual360(), ibor_index)

        self.assertIsNotNone(index)
Ejemplo n.º 15
0
    def test_create_libor_index(self):

        settings = Settings.instance()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)

        term_structure = YieldTermStructure(relinkable=True)
        term_structure.link_to(
            FlatForward(settlement_date, 0.05, Actual365Fixed()))

        index = Libor('USD Libor', Period(6, Months), settlement_days,
                      USDCurrency(), calendar, Actual360(), term_structure)

        t = index.tenor
        self.assertEquals(t.length, 6)
        self.assertEquals(t.units, 2)
        self.assertEquals('USD Libor6M Actual/360', index.name)
Ejemplo n.º 16
0
 def setUp(self):
     """"""
     self.today = today()
     self.settings = Settings()
     self.settings.evaluation_date = self.today
     self.dc = Actual365Fixed()
     self.spot = SimpleQuote(0.0)
     self.q_rate = SimpleQuote(0.0)
     self.q_ts = FlatForward(self.today, self.q_rate, self.dc)
     self.r_rate = SimpleQuote(0.0)
     self.r_ts = FlatForward(self.today, self.r_rate, self.dc)
     self.values = {
         'type': SwapType.Long,
         'strike': 0.04,
         'nominal': 50000,
         's': 100.0,
         'q': 0.00,
         'r': 0.05,
         't': 0.246575,
         'v': 0.20,
         'result': 0.04189,
         'tol': 1.0e-4,
     }
     self.spot.value = self.values['s']
     self.q_rate.value = self.values['q']
     self.r_rate.value = self.values['r']
     self.ex_date = self.today + int(self.values['t'] * 365 + 0.5)
Ejemplo n.º 17
0
    def test_create_swap_index(self):

        settings = Settings.instance()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)
        term_structure = YieldTermStructure(relinkable=True)
        term_structure.link_to(FlatForward(settlement_date, 0.05,
                                          Actual365Fixed()))

        ibor_index = Libor('USD Libor', Period(6, Months), settlement_days,
                        USDCurrency(), calendar, Actual360(),
                           term_structure)

        index = SwapIndex(
            'family name', Period(3, Months), 10, USDCurrency(), TARGET(),
            Period(12, Months), Following, Actual360(), ibor_index)

        self.assertIsNotNone(index)
Ejemplo n.º 18
0
    def setUp(self):
        settlement_date = today()

        settings = Settings()
        settings.evaluation_date = settlement_date

        daycounter = ActualActual()
        self.calendar = NullCalendar()

        i_rate = .1
        i_div = .04

        self.risk_free_ts = flat_rate(i_rate, daycounter)
        self.dividend_ts = flat_rate(i_div, daycounter)

        self.s0 = SimpleQuote(32.0)

        # Bates model

        self.v0 = 0.05
        self.kappa = 5.0
        self.theta = 0.05
        self.sigma = 1.0e-4
        self.rho = 0.0
        self.Lambda = .1
        self.nu = .01
        self.delta = .001
Ejemplo n.º 19
0
    def test_create_swap_index(self):

        settings = Settings.instance()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)
        term_structure = YieldTermStructure(relinkable=True)
        term_structure.link_to(
            FlatForward(settlement_date, 0.05, Actual365Fixed()))

        ibor_index = Libor('USD Libor', Period(6, Months), settlement_days,
                           USDCurrency(), calendar, Actual360(),
                           term_structure)

        index = SwapIndex('family name', Period(3, Months), 10, USDCurrency(),
                          TARGET(), Period(12, Months), Following, Actual360(),
                          ibor_index)

        self.assertIsNotNone(index)
Ejemplo n.º 20
0
    def test_create_libor_index(self):

        settings = Settings.instance()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)

        term_structure = YieldTermStructure(relinkable=True)
        term_structure.link_to(FlatForward(settlement_date, 0.05,
                                           Actual365Fixed()))

        index = Libor('USD Libor', Period(6, Months), settlement_days,
                      USDCurrency(), calendar, Actual360(),
                      term_structure)

        t = index.tenor
        self.assertEqual(t.length, 6)
        self.assertEqual(t.units, 2)
        self.assertEqual('USD Libor6M Actual/360', index.name)
Ejemplo n.º 21
0
    def test_blsprice(self):

        from quantlib.settings import Settings
        from quantlib.time.api import today
        Settings.instance().evaluation_date = today()
        call_value = blsprice(100.0, 97.0, 0.1, 0.25, 0.5)
        self.assertAlmostEquals(call_value, 12.61, 2)
Ejemplo n.º 22
0
    def test_smith(self):
        # test against result published in
        # Journal of Computational Finance Vol. 11/1 Fall 2007
        # An almost exact simulation method for the heston model

        settlement_date = today()
        self.settings.evaluation_date = settlement_date

        daycounter = ActualActual()
        timeToMaturity = 4

        exercise_date = settlement_date + timeToMaturity * 365

        c_payoff = PlainVanillaPayoff(Call, 100)

        exercise = EuropeanExercise(exercise_date)

        risk_free_ts = flat_rate(0., daycounter)
        dividend_ts = flat_rate(0., daycounter)

        s0 = SimpleQuote(100.0)

        v0 = 0.0194
        kappa = 1.0407
        theta = 0.0586
        sigma = 0.5196
        rho = -.6747

        nb_steps_a = 100
        nb_paths = 20000
        seed = 12347

        process = HestonProcess(risk_free_ts, dividend_ts, s0, v0, kappa,
                                theta, sigma, rho, QUADRATICEXPONENTIAL)

        model = HestonModel(process)

        option = VanillaOption(c_payoff, exercise)

        engine = AnalyticHestonEngine(model, 144)

        option.set_pricing_engine(engine)

        price_fft = option.net_present_value

        engine = MCEuropeanHestonEngine(process,
                                        antithetic_variate=True,
                                        steps_per_year=nb_steps_a,
                                        required_samples=nb_paths,
                                        seed=seed)

        option.set_pricing_engine(engine)
        price_mc = option.net_present_value

        expected = 15.1796
        tolerance = .05

        self.assertAlmostEqual(price_fft, expected, delta=tolerance)
        self.assertAlmostEqual(price_mc, expected, delta=tolerance)
Ejemplo n.º 23
0
    def test_creation(self):

        settings = Settings()

        # Market information
        calendar = TARGET()

        # must be a business day
        settings.evaluation_date = calendar.adjust(today())

        settlement_date = Date(18, September, 2008)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date);

        quotes = [SimpleQuote(0.0096), SimpleQuote(0.0145), SimpleQuote(0.0194)]
        tenors =  [3, 6, 12]

        rate_helpers = []

        calendar =  TARGET()
        deposit_day_counter = Actual365Fixed()
        convention = ModifiedFollowing
        end_of_month = True

        for quote, month in zip(quotes, tenors):
            tenor = Period(month, Months)
            fixing_days = 3

            helper = DepositRateHelper(
                quote, tenor, fixing_days, calendar, convention, end_of_month,
                deposit_day_counter
            )

            rate_helpers.append(helper)


        ts_day_counter = ActualActual(ISDA)

        tolerance = 1.0e-15

        ts = PiecewiseYieldCurve[BootstrapTrait.Discount, LogLinear].from_reference_date(
            settlement_date, rate_helpers,
            ts_day_counter, accuracy=tolerance
        )

        self.assertIsNotNone(ts)

        self.assertEqual( Date(18, September, 2008), ts.reference_date)

        # this is not a real test ...
        self.assertAlmostEqual(0.9975, ts.discount(Date(21, 12, 2008)), 4)
        self.assertAlmostEqual(0.9944, ts.discount(Date(21, 4, 2009)), 4)
        self.assertAlmostEqual(0.9904, ts.discount(Date(21, 9, 2009)), 4)

        dates, dfs = zip(*ts.nodes)
        self.assertAlmostEqual(list(dates), ts.dates)
        self.assertAlmostEqual(list(dfs), ts.data)
Ejemplo n.º 24
0
def _blsprice(spot, strike, risk_free_rate, time, volatility,
             option_type='Call', dividend=0.0, calc='price'):
    """
    Black-Scholes option pricing model + greeks.
    """
    _spot = SimpleQuote(spot)

    daycounter = ActualActual(ISMA)
    risk_free_ts = FlatForward(today(), risk_free_rate, daycounter)
    dividend_ts = FlatForward(today(), dividend, daycounter)
    volatility_ts = BlackConstantVol(today(), NullCalendar(),
                                     volatility, daycounter)

    process = BlackScholesMertonProcess(_spot, dividend_ts,
                                        risk_free_ts, volatility_ts)

    exercise_date = today() + Period(time * 365, Days)
    exercise = EuropeanExercise(exercise_date)

    payoff = PlainVanillaPayoff(option_type, strike)

    option = EuropeanOption(payoff, exercise)
    engine = AnalyticEuropeanEngine(process)
    option.set_pricing_engine(engine)

    if calc == 'price':
        res = option.npv
    elif calc == 'delta':
        res = option.delta
    elif calc == 'gamma':
        res = option.gamma
    elif calc == 'theta':
        res = option.theta
    elif calc == 'rho':
        res = option.rho
    elif calc == 'vega':
        res = option.vega
    elif calc == 'lambda':
        res = option.delta * spot / option.npv
    else:
        raise ValueError('calc type %s is unknown' % calc)

    return res
Ejemplo n.º 25
0
def blsprice(spot, strike, risk_free_rate, time, volatility, option_type='Call', dividend=0.0):
    """ """
    spot = SimpleQuote(spot)

    daycounter = Actual360()
    risk_free_ts = FlatForward(today(), risk_free_rate, daycounter)
    dividend_ts = FlatForward(today(), dividend, daycounter)
    volatility_ts = BlackConstantVol(today(), NullCalendar(), volatility, daycounter)

    process = BlackScholesMertonProcess(spot, dividend_ts, risk_free_ts, volatility_ts)

    exercise_date = today() + 90
    exercise = EuropeanExercise(exercise_date)

    payoff = PlainVanillaPayoff(option_type, strike)

    option = EuropeanOption(payoff, exercise)
    engine = AnalyticEuropeanEngine(process)
    option.set_pricing_engine(engine)
    return option.npv
Ejemplo n.º 26
0
    def test_analytic_versus_black(self):

        settlement_date = today()
        self.settings.evaluation_date = settlement_date

        daycounter = ActualActual()

        exercise_date = settlement_date + 6 * Months

        payoff = PlainVanillaPayoff(Put, 30)

        exercise = EuropeanExercise(exercise_date)

        risk_free_ts = flat_rate(0.1, daycounter)
        dividend_ts = flat_rate(0.04, daycounter)

        s0 = SimpleQuote(32.0)

        v0    = 0.05
        kappa = 5.0
        theta = 0.05
        sigma = 1.0e-4
        rho   = 0.0

        process = HestonProcess(
            risk_free_ts, dividend_ts, s0, v0, kappa, theta, sigma, rho
        )

        option = VanillaOption(payoff, exercise)

        engine = AnalyticHestonEngine(HestonModel(process), 144)

        option.set_pricing_engine(engine)

        calculated = option.net_present_value

        year_fraction = daycounter.year_fraction(
            settlement_date, exercise_date
        )

        forward_price = 32 * np.exp((0.1 - 0.04) * year_fraction)
        expected = blackFormula(
            payoff.type, payoff.strike, forward_price,
            np.sqrt(0.05 * year_fraction)
        ) * np.exp(-0.1 * year_fraction)

        tolerance = 2.0e-7

        self.assertAlmostEqual(
            calculated,
            expected,
            delta=tolerance
        )
Ejemplo n.º 27
0
    def test_creation(self):

        settings = Settings()

        # Market information
        calendar = TARGET()

        # must be a business day
        settings.evaluation_date = calendar.adjust(today())

        settlement_date = Date(18, September, 2008)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date);

        quotes = [0.0096, 0.0145, 0.0194]
        tenors =  [3, 6, 12]

        rate_helpers = []

        calendar =  TARGET()
        deposit_day_counter = Actual365Fixed()
        convention = ModifiedFollowing
        end_of_month = True

        for quote, month in zip(quotes, tenors):
            tenor = Period(month, Months)
            fixing_days = 3

            helper = DepositRateHelper(
                quote, tenor, fixing_days, calendar, convention, end_of_month,
                deposit_day_counter
            )

            rate_helpers.append(helper)


        ts_day_counter = ActualActual(ISDA)

        tolerance = 1.0e-15

        ts = term_structure_factory(
            'discount', 'loglinear', settlement_date, rate_helpers,
            ts_day_counter, tolerance
        )

        self.assertIsNotNone(ts)

        self.assertEquals( Date(18, September, 2008), ts.reference_date)

        # this is not a real test ...
        self.assertAlmostEquals(0.9975, ts.discount(Date(21, 12, 2008)), 4)
        self.assertAlmostEquals(0.9944, ts.discount(Date(21, 4, 2009)), 4)
        self.assertAlmostEquals(0.9904, ts.discount(Date(21, 9, 2009)), 4)
Ejemplo n.º 28
0
    def test_creation(self):

        settings = Settings()

        # Market information
        calendar = TARGET()

        # must be a business day
        settings.evaluation_date = calendar.adjust(today())

        settlement_date = Date(18, September, 2008)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date);

        quotes = [SimpleQuote(0.0096), SimpleQuote(0.0145), SimpleQuote(0.0194)]
        tenors =  [3, 6, 12]

        rate_helpers = []

        calendar =  TARGET()
        deposit_day_counter = Actual365Fixed()
        convention = ModifiedFollowing
        end_of_month = True

        for quote, month in zip(quotes, tenors):
            tenor = Period(month, Months)
            fixing_days = 3

            helper = DepositRateHelper(
                quote, tenor, fixing_days, calendar, convention, end_of_month,
                deposit_day_counter
            )

            rate_helpers.append(helper)


        ts_day_counter = ActualActual(ISDA)

        tolerance = 1.0e-15

        ts = PiecewiseYieldCurve.from_reference_date(
            BootstrapTrait.Discount, Interpolator.LogLinear, settlement_date, rate_helpers,
            ts_day_counter, tolerance
        )

        self.assertIsNotNone(ts)

        self.assertEqual( Date(18, September, 2008), ts.reference_date)

        # this is not a real test ...
        self.assertAlmostEqual(0.9975, ts.discount(Date(21, 12, 2008)), 4)
        self.assertAlmostEqual(0.9944, ts.discount(Date(21, 4, 2009)), 4)
        self.assertAlmostEqual(0.9904, ts.discount(Date(21, 9, 2009)), 4)
Ejemplo n.º 29
0
    def test_creation(self):

        settings = Settings()

        # Market information
        calendar = TARGET()

        # must be a business day
        settings.evaluation_date = calendar.adjust(today())

        settlement_date = Date(18, September, 2008)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date);

        quotes = [0.0096, 0.0145, 0.0194]
        tenors =  [3, 6, 12]

        rate_helpers = []

        calendar =  TARGET()
        deposit_day_counter = Actual365Fixed()
        convention = ModifiedFollowing
        end_of_month = True

        for quote, month in zip(quotes, tenors):
            tenor = Period(month, Months)
            fixing_days = 3

            helper = DepositRateHelper(
                quote, tenor, fixing_days, calendar, convention, end_of_month,
                deposit_day_counter
            )

            rate_helpers.append(helper)


        ts_day_counter = ActualActual(ISDA)

        tolerance = 1.0e-15

        ts = term_structure_factory(
            'discount', 'loglinear', settlement_date, rate_helpers,
            ts_day_counter, tolerance
        )

        self.assertIsNotNone(ts)

        self.assertEquals( Date(18, September, 2008), ts.reference_date)

        # this is not a real test ...
        self.assertAlmostEquals(0.9975, ts.discount(Date(21, 12, 2008)), 4)
        self.assertAlmostEquals(0.9944, ts.discount(Date(21, 4, 2009)), 4)
        self.assertAlmostEquals(0.9904, ts.discount(Date(21, 9, 2009)), 4)
Ejemplo n.º 30
0
    def test_analytic_versus_black(self):
        settlement_date = today()
        self.settings.evaluation_date = settlement_date

        daycounter = ActualActual()

        exercise_date = settlement_date + 6 * Months

        payoff = PlainVanillaPayoff(Put, 30)

        exercise = EuropeanExercise(exercise_date)

        risk_free_ts = flat_rate(0.1, daycounter)
        dividend_ts = flat_rate(0.04, daycounter)

        s0 = SimpleQuote(32.0)

        v0    = 0.05
        kappa = 5.0
        theta = 0.05
        sigma = 1.0e-4
        rho   = 0.0

        process = HestonProcess(
            risk_free_ts, dividend_ts, s0, v0, kappa, theta, sigma, rho
        )

        option = VanillaOption(payoff, exercise)

        engine = AnalyticHestonEngine(HestonModel(process), 144)

        option.set_pricing_engine(engine)

        calculated = option.net_present_value

        year_fraction = daycounter.year_fraction(
            settlement_date, exercise_date
        )

        forward_price = 32 * np.exp((0.1 - 0.04) * year_fraction)
        expected = blackFormula(
            payoff.type, payoff.strike, forward_price,
            np.sqrt(0.05 * year_fraction)
        ) * np.exp(-0.1 * year_fraction)

        tolerance = 2.0e-7

        self.assertAlmostEqual(
            calculated,
            expected,
            delta=tolerance
        )
Ejemplo n.º 31
0
    def test_using_settings(self):

        settings = Settings()

        evaluation_date = today()

        # have to set the evaluation date before the test as it is a global
        # attribute for the whole library ... meaning that previous test_cases
        # might have set this to another date
        settings.evaluation_date = evaluation_date

        self.assertEqual(settings.evaluation_date, evaluation_date)
        self.assertTrue(settings.version.startswith('1'))
Ejemplo n.º 32
0
    def test_using_settings(self):

        settings = Settings()

        evaluation_date = today()

        # have to set the evaluation date before the test as it is a global
        # attribute for the whole library ... meaning that previous test_cases
        # might have set this to another date
        settings.evaluation_date = evaluation_date

        self.assertEqual(settings.evaluation_date, evaluation_date)
        self.assertTrue(settings.version.startswith('1'))
Ejemplo n.º 33
0
    def test_bond_schedule_today(self):
        '''Test date calculations and role of settings when evaluation date
        set to current date.


        '''

        todays_date = today()

        settings = Settings()
        settings.evaluation_date = todays_date

        calendar = TARGET()
        effective_date = Date(10, Jul, 2006)
        termination_date = calendar.advance(
            effective_date, 10, Years, convention=Unadjusted)

        settlement_days = 3
        face_amount = 100.0
        coupon_rate = 0.05
        redemption = 100.0

        fixed_bond_schedule = Schedule.from_rule(
            effective_date,
            termination_date,
            Period(Annual),
            calendar,
            ModifiedFollowing,
            ModifiedFollowing,
            Rule.Backward
        )

        issue_date = effective_date

        bond = FixedRateBond(
            settlement_days,
		    face_amount,
		    fixed_bond_schedule,
		    [coupon_rate],
            ActualActual(ISMA),
		    Following,
            redemption,
            issue_date
        )

        self.assertEqual(
            calendar.advance(todays_date, 3, Days), bond.settlement_date())
Ejemplo n.º 34
0
    def test_bond_schedule_today(self):
        '''Test date calculations and role of settings when evaluation date
        set to current date.


        '''

        todays_date = today()

        settings = Settings()
        settings.evaluation_date = todays_date

        calendar = TARGET()
        effective_date = Date(10, Jul, 2006)
        termination_date = calendar.advance(
            effective_date, 10, Years, convention=Unadjusted)

        settlement_days = 3
        face_amount = 100.0
        coupon_rate = 0.05
        redemption = 100.0

        fixed_bond_schedule = Schedule.from_rule(
            effective_date,
            termination_date,
            Period(Annual),
            calendar,
            ModifiedFollowing,
            ModifiedFollowing,
            Rule.Backward
        )

        issue_date = effective_date

        bond = FixedRateBond(
            settlement_days,
		    face_amount,
		    fixed_bond_schedule,
		    [coupon_rate],
            ActualActual(ISMA),
		    Following,
            redemption,
            issue_date
        )

        self.assertEqual(
            calendar.advance(todays_date, 3, Days), bond.settlement_date())
Ejemplo n.º 35
0
    def setUp(self):
        calendar = TARGET()
        today_date = today()

        Settings().evaluation_date = today_date

        hazard_rate = SimpleQuote(0.01234)
        probability_curve = FlatHazardRate(0, calendar, hazard_rate, Actual360())
        discount_curve = FlatForward(today_date, 0.06, Actual360())
        issue_date  = today_date
        #calendar.advance(today_date, -1, Years)
        maturity = calendar.advance(issue_date, 10, Years)
        self.convention = Following
        self.schedule = Schedule(issue_date, maturity, Period("3M"), calendar,
                self.convention, self.convention, Rule.TwentiethIMM)
        recovery_rate = 0.4
        self.engine = MidPointCdsEngine(probability_curve, recovery_rate, discount_curve, True)
Ejemplo n.º 36
0
    def test_simulate_heston_1(self):

        settings = self.settings
        settlement_date = today()
        settings.evaluation_date = settlement_date

        # simulate Heston paths
        paths = 4
        steps = 10
        horizon = 1
        seed = 12345

        grid = TimeGrid(horizon, steps)
        res = simulate_process(self.heston_process, paths, grid, seed)

        time = list(grid)
        time_expected = np.arange(0, 1.1, .1)

        np.testing.assert_array_almost_equal(time, time_expected, decimal=4)
Ejemplo n.º 37
0
    def test_create_libor_index(self):

        settings = Settings.instance()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)

        index = Libor("USD Libor", Period(6, Months), settlement_days, USDCurrency(), calendar, Actual360())

        self.assertEquals("USD Libor6M Actual/360", index.name)
Ejemplo n.º 38
0
    def test_simulate_heston_1(self):

        settings = self.settings
        settlement_date = today()
        settings.evaluation_date = settlement_date

        # simulate Heston paths
        paths = 4
        steps = 10
        horizon = 1
        seed = 12345

        grid = TimeGrid(horizon, steps)
        res = simulate_process(self.heston_process, paths, grid, seed)

        time = list(grid) 
        time_expected = np.arange(0, 1.1, .1)

        np.testing.assert_array_almost_equal(time, time_expected, decimal=4)
Ejemplo n.º 39
0
    def test_create_libor_index(self):

        settings = Settings.instance()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)

        index = Libor('USD Libor', Period(6, Months), settlement_days,
                      USDCurrency(), calendar, Actual360())

        self.assertEquals('USD Libor6M Actual/360', index.name)
Ejemplo n.º 40
0
    def test_simulate_heston_1(self):

        settings = self.settings
        settlement_date = today()
        settings.evaluation_date = settlement_date

        # simulate Heston paths
        paths = 4
        steps = 10
        horizon = 1
        seed = 12345

        model = HestonModel(self.heston_process)

        res = simulate_model(model, paths, steps, horizon, seed)

        time = res[0, :]
        time_expected = np.arange(0, 1.1, .1)
        simulations = res[1:, :].T

        np.testing.assert_array_almost_equal(time, time_expected, decimal=4)
Ejemplo n.º 41
0
    def test_simulate_heston_1(self):

        settings = self.settings
        settlement_date = today()
        settings.evaluation_date = settlement_date

        # simulate Heston paths
        paths = 4
        steps = 10
        horizon = 1
        seed = 12345

        model = HestonModel(self.heston_process)

        res = simulateHeston(model, paths, steps, horizon, seed)

        time = res[0, :]
        time_expected = np.arange(0, 1.1, 0.1)
        simulations = res[1:, :].T

        np.testing.assert_array_almost_equal(time, time_expected, decimal=4)
    def test_zanette(self):
        """
        From paper by A. Zanette et al.
        """

        dc = Actual365Fixed()

        todays_date = today()
        settings = Settings()
        settings.evaluation_date = todays_date

        # constant yield and div curves

        dates = [todays_date + Period(i, Years) for i in range(3)]
        rates = [0.04 for i in range(3)]
        divRates = [0.03 for i in range(3)]
        r_ts = ZeroCurve(dates, rates, dc)
        q_ts = ZeroCurve(dates, divRates, dc)

        s0 = SimpleQuote(100)

        # Heston model

        v0 = .1
        kappa_v = 2
        theta_v = 0.1
        sigma_v = 0.3
        rho_sv = -0.5

        hestonProcess = HestonProcess(
            risk_free_rate_ts=r_ts,
            dividend_ts=q_ts,
            s0=s0,
            v0=v0,
            kappa=kappa_v,
            theta=theta_v,
            sigma=sigma_v,
            rho=rho_sv)

        hestonModel = HestonModel(hestonProcess)

        # Hull-White

        kappa_r = 1
        sigma_r = .2

        hullWhiteProcess = HullWhiteProcess(r_ts, a=kappa_r, sigma=sigma_r)

        strike = 100
        maturity = 1
        type = Call

        maturity_date = todays_date + Period(maturity, Years)

        exercise = EuropeanExercise(maturity_date)

        payoff = PlainVanillaPayoff(type, strike)

        option = VanillaOption(payoff, exercise)

        def price_cal(rho, tGrid):
            fd_hestonHwEngine = FdHestonHullWhiteVanillaEngine(
                hestonModel,
                hullWhiteProcess,
                rho,
                tGrid, 100, 40, 20, 0, True, FdmSchemeDesc.Hundsdorfer())
            option.set_pricing_engine(fd_hestonHwEngine)
            return option.npv

        calc_price = []
        for rho in [-0.5, 0, .5]:
            for tGrid in [50, 100, 150, 200]:
                tmp = price_cal(rho, tGrid)
                print("rho (S,r): %f Ns: %d Price: %f" %
                      (rho, tGrid, tmp))
                calc_price.append(tmp)

        expected_price = [11.38, ] * 4 + [12.79, ] * 4 + [14.06, ] * 4

        np.testing.assert_almost_equal(calc_price, expected_price, 2)
Ejemplo n.º 43
0
# The Heston Process
# ------------------

# <codecell>


def flat_rate(forward, daycounter):
    return FlatForward(
        quote           = SimpleQuote(forward),
        settlement_days = 0,
        calendar        = NullCalendar(),
        daycounter      = daycounter
    )

settings = Settings.instance()
settlement_date = today()
settings.evaluation_date = settlement_date

daycounter = ActualActual()
calendar = NullCalendar()

interest_rate = .1
dividend_yield = .04

risk_free_ts = flat_rate(interest_rate, daycounter)
dividend_ts = flat_rate(dividend_yield, daycounter)

s0 = SimpleQuote(100.0)

# Heston model
Ejemplo n.º 44
0
    def test_bsm_hw(self):
        print("Testing European option pricing for a BSM process" +
              " with one-factor Hull-White model...")

        dc = Actual365Fixed()
        todays_date = today()
        maturity_date = todays_date + Period(20, Years)

        settings = Settings()
        settings.evaluation_date = todays_date

        spot = SimpleQuote(100)

        q_ts = flat_rate(todays_date, 0.04, dc)
        r_ts = flat_rate(todays_date, 0.0525, dc)
        vol_ts = BlackConstantVol(todays_date, NullCalendar(), 0.25, dc)

        hullWhiteModel = HullWhite(r_ts, 0.00883, 0.00526)

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

        exercise = EuropeanExercise(maturity_date)

        fwd = spot.value * q_ts.discount(maturity_date) / \
            r_ts.discount(maturity_date)

        payoff = PlainVanillaPayoff(Call, fwd)

        option = VanillaOption(payoff, exercise)

        tol = 1e-8
        corr = [-0.75, -0.25, 0.0, 0.25, 0.75]
        expectedVol = [
            0.217064577, 0.243995801, 0.256402830, 0.268236596, 0.290461343
        ]

        for c, v in zip(corr, expectedVol):
            bsm_hw_engine = AnalyticBSMHullWhiteEngine(c, bsm_process,
                                                       hullWhiteModel)

            option = VanillaOption(payoff, exercise)
            option.set_pricing_engine(bsm_hw_engine)
            npv = option.npv

            compVolTS = BlackConstantVol(todays_date, NullCalendar(), v, dc)

            bs_process = BlackScholesMertonProcess(spot, q_ts, r_ts, compVolTS)
            bsEngine = AnalyticEuropeanEngine(bs_process)

            comp = VanillaOption(payoff, exercise)
            comp.set_pricing_engine(bsEngine)

            impliedVol = comp.implied_volatility(npv,
                                                 bs_process,
                                                 1e-10,
                                                 500,
                                                 min_vol=0.1,
                                                 max_vol=0.4)

            if (abs(impliedVol - v) > tol):
                print("Failed to reproduce implied volatility cor: %f" % c)
                print("calculated: %f" % impliedVol)
                print("expected  : %f" % v)

            if abs((comp.npv - npv) / npv) > tol:
                print("Failed to reproduce NPV")
                print("calculated: %f" % comp.npv)
                print("expected  : %f" % npv)

            self.assertAlmostEqual(impliedVol, v, delta=tol)
            self.assertAlmostEqual(comp.npv / npv, 1, delta=tol)
Ejemplo n.º 45
0
    def test_zanette(self):
        """
        From paper by A. Zanette et al.
        """

        dc = Actual365Fixed()

        todays_date = today()
        settings = Settings()
        settings.evaluation_date = todays_date

        # constant yield and div curves

        dates = [todays_date + Period(i, Years) for i in range(3)]
        rates = [0.04 for i in range(3)]
        divRates = [0.03 for i in range(3)]
        r_ts = ZeroCurve(dates, rates, dc)
        q_ts = ZeroCurve(dates, divRates, dc)

        s0 = SimpleQuote(100)

        # Heston model

        v0 = .1
        kappa_v = 2
        theta_v = 0.1
        sigma_v = 0.3
        rho_sv = -0.5

        hestonProcess = HestonProcess(risk_free_rate_ts=r_ts,
                                      dividend_ts=q_ts,
                                      s0=s0,
                                      v0=v0,
                                      kappa=kappa_v,
                                      theta=theta_v,
                                      sigma=sigma_v,
                                      rho=rho_sv)

        hestonModel = HestonModel(hestonProcess)

        # Hull-White

        kappa_r = 1
        sigma_r = .2

        hullWhiteProcess = HullWhiteProcess(r_ts, a=kappa_r, sigma=sigma_r)

        strike = 100
        maturity = 1
        type = Call

        maturity_date = todays_date + Period(maturity, Years)

        exercise = EuropeanExercise(maturity_date)

        payoff = PlainVanillaPayoff(type, strike)

        option = VanillaOption(payoff, exercise)

        def price_cal(rho, tGrid):
            fd_hestonHwEngine = FdHestonHullWhiteVanillaEngine(
                hestonModel, hullWhiteProcess, rho, tGrid, 100, 40, 20, 0,
                True, FdmSchemeDesc.Hundsdorfer())
            option.set_pricing_engine(fd_hestonHwEngine)
            return option.npv

        calc_price = []
        for rho in [-0.5, 0, .5]:
            for tGrid in [50, 100, 150, 200]:
                tmp = price_cal(rho, tGrid)
                print("rho (S,r): %f Ns: %d Price: %f" % (rho, tGrid, tmp))
                calc_price.append(tmp)

        expected_price = [
            11.38,
        ] * 4 + [
            12.79,
        ] * 4 + [
            14.06,
        ] * 4

        np.testing.assert_almost_equal(calc_price, expected_price, 2)
Ejemplo n.º 46
0
    def test_black_calibration(self):

        # calibrate a Heston model to a constant volatility surface without
        # smile. expected result is a vanishing volatility of the volatility.
        # In addition theta and v0 should be equal to the constant variance

        todays_date = today()

        self.settings.evaluation_date = todays_date

        daycounter = Actual360()
        calendar = NullCalendar()

        risk_free_ts = flat_rate(0.04, daycounter)
        dividend_ts = flat_rate(0.50, daycounter)

        option_maturities = [
            Period(1, Months),
            Period(2, Months),
            Period(3, Months),
            Period(6, Months),
            Period(9, Months),
            Period(1, Years),
            Period(2, Years)
        ]

        options = []

        s0 = SimpleQuote(1.0)
        vol = SimpleQuote(0.1)

        volatility = vol.value

        for maturity in option_maturities:
            for moneyness in np.arange(-1.0, 2.0, 1.):
                tau = daycounter.year_fraction(
                    risk_free_ts.reference_date,
                    calendar.advance(
                        risk_free_ts.reference_date,
                        period=maturity)
                )
                forward_price = s0.value * dividend_ts.discount(tau) / \
                                risk_free_ts.discount(tau)
                strike_price = forward_price * np.exp(
                    -moneyness * volatility * np.sqrt(tau)
                )
                options.append(
                    HestonModelHelper(
                        maturity, calendar, s0.value, strike_price, vol,
                        risk_free_ts, dividend_ts
                    )
                )

        for sigma in np.arange(0.1, 0.7, 0.2):
            v0    = 0.01
            kappa = 0.2
            theta = 0.02
            rho   = -0.75

            process = HestonProcess(
                risk_free_ts, dividend_ts, s0, v0, kappa, theta, sigma, rho
            )

            self.assertEqual(v0, process.v0)
            self.assertEqual(kappa, process.kappa)
            self.assertEqual(theta, process.theta)
            self.assertEqual(sigma, process.sigma)
            self.assertEqual(rho, process.rho)
            self.assertEqual(1.0, process.s0().value)

            model = HestonModel(process)
            engine = AnalyticHestonEngine(model, 96)

            for option in options:
                option.set_pricing_engine(engine)

            optimisation_method = LevenbergMarquardt(1e-8, 1e-8, 1e-8)

            end_criteria = EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8)
            model.calibrate(options, optimisation_method, end_criteria)

            tolerance = 3.0e-3

            self.assertFalse(model.sigma > tolerance)

            self.assertAlmostEqual(
                model.kappa * model.theta,
                model.kappa * volatility ** 2,
                delta=tolerance
            )
            self.assertAlmostEqual(model.v0, volatility ** 2, delta=tolerance)
Ejemplo n.º 47
0
from quantlib.pricingengines.vanilla import AnalyticEuropeanEngine
from quantlib.processes.black_scholes_process import BlackScholesMertonProcess
from quantlib.quotes import SimpleQuote
from quantlib.settings import Settings
from quantlib.time.api import TARGET, Actual365Fixed, today, Date as QlDate
from quantlib.termstructures.yields.api import FlatForward
from quantlib.termstructures.volatility.equityfx.black_vol_term_structure \
    import BlackConstantVol


settings = Settings.instance()
calendar = TARGET()

offset = 366

todays_date = today() - offset
settlement_date = todays_date + 2

settings.evaluation_date = todays_date


class OptionValuation(HasTraits):

    # options parameters
    option_type = Enum(Put, Call)
    underlying = Float(36)
    strike = Float(40)
    dividend_yield = Range(0.0, 0.5)
    risk_free_rate = Range(0.0, 0.2)
    volatility = Range(0.0, 0.5)
    maturity = Date(datetime.date.today())
Ejemplo n.º 48
0
    def test_bates_det_jump(self):
        # this looks like a bug in QL:
        # Bates Det Jump model does not have sigma as parameter, yet
        # changing sigma changes the result!

        settlement_date = today()
        self.settings.evaluation_date = settlement_date

        daycounter = ActualActual()

        exercise_date = settlement_date + 6 * Months

        payoff = PlainVanillaPayoff(Put, 1290)
        exercise = EuropeanExercise(exercise_date)
        option = VanillaOption(payoff, exercise)

        risk_free_ts = flat_rate(0.02, daycounter)
        dividend_ts = flat_rate(0.04, daycounter)

        spot = 1290

        ival = {'delta': 3.6828677022272715e-06,
        'kappa': 19.02581428347027,
        'kappaLambda': 1.1209758060939223,
        'lambda': 0.06524550732595163,
        'nu': -1.8968106563601956,
        'rho': -0.7480898462264719,
        'sigma': 1.0206363887835108,
        'theta': 0.01965384459461113,
        'thetaLambda': 0.028915397380738218,
        'v0': 0.06566800935242285}

        process = BatesProcess(
        risk_free_ts, dividend_ts, SimpleQuote(spot),
        ival['v0'], ival['kappa'],
        ival['theta'], ival['sigma'], ival['rho'],
        ival['lambda'], ival['nu'], ival['delta'])

        model = BatesDetJumpModel(process,
                ival['kappaLambda'], ival['thetaLambda'])

        engine = BatesDetJumpEngine(model, 64)

        option.set_pricing_engine(engine)

        calc_1 = option.net_present_value

        ival['sigma'] = 1.e-6

        process = BatesProcess(
        risk_free_ts, dividend_ts, SimpleQuote(spot),
        ival['v0'], ival['kappa'],
        ival['theta'], ival['sigma'], ival['rho'],
        ival['lambda'], ival['nu'], ival['delta'])

        model = BatesDetJumpModel(process,
                ival['kappaLambda'], ival['thetaLambda'])
        engine = BatesDetJumpEngine(model, 64)

        option.set_pricing_engine(engine)

        calc_2 = option.net_present_value

        if(abs(calc_1-calc_2) > 1.e-5):
            print('calc 1 %f calc 2 %f' % (calc_1, calc_2))
        self.assertNotEqual(calc_1, calc_2)
Ejemplo n.º 49
0
    def test_smith(self):
        # test against result published in
        # Journal of Computational Finance Vol. 11/1 Fall 2007
        # An almost exact simulation method for the heston model

        settlement_date = today()
        self.settings.evaluation_date = settlement_date

        daycounter = ActualActual()
        timeToMaturity = 4

        exercise_date = settlement_date + timeToMaturity * 365

        c_payoff = PlainVanillaPayoff(Call, 100)

        exercise = EuropeanExercise(exercise_date)

        risk_free_ts = flat_rate(0., daycounter)
        dividend_ts = flat_rate(0., daycounter)

        s0 = SimpleQuote(100.0)

        v0    = 0.0194
        kappa = 1.0407
        theta = 0.0586
        sigma = 0.5196
        rho   = -.6747

        nb_steps_a = 100
        nb_paths = 20000
        seed = 12347

        process = HestonProcess(
            risk_free_ts, dividend_ts, s0, v0, kappa, theta,
            sigma, rho, QUADRATICEXPONENTIAL)

        model = HestonModel(process)

        option = VanillaOption(c_payoff, exercise)

        engine = AnalyticHestonEngine(model, 144)

        option.set_pricing_engine(engine)

        price_fft  = option.net_present_value

        engine = MCVanillaEngine(
              trait='MCEuropeanHestonEngine',
              generator='PseudoRandom',
              process=process,
              doAntitheticVariate=True,
              stepsPerYear=nb_steps_a,
              requiredSamples=nb_paths,
              seed=seed)

        option.set_pricing_engine(engine)
        price_mc = option.net_present_value

        expected = 15.1796
        tolerance = .05

        self.assertAlmostEqual(price_fft, expected, delta=tolerance)
        self.assertAlmostEqual(price_mc, expected, delta=tolerance)
Ejemplo n.º 50
0
    def test_black_calibration(self):

        # calibrate a Heston model to a constant volatility surface without
        # smile. expected result is a vanishing volatility of the volatility.
        # In addition theta and v0 should be equal to the constant variance

        todays_date = today()

        self.settings.evaluation_date = todays_date

        daycounter = Actual360()
        calendar = NullCalendar()

        risk_free_ts = flat_rate(0.04, daycounter)
        dividend_ts = flat_rate(0.50, daycounter)

        option_maturities = [
            Period(1, Months),
            Period(2, Months),
            Period(3, Months),
            Period(6, Months),
            Period(9, Months),
            Period(1, Years),
            Period(2, Years)
        ]

        options = []

        s0 = SimpleQuote(1.0)
        vol = SimpleQuote(0.1)

        volatility = vol.value

        for maturity in option_maturities:
            for moneyness in np.arange(-1.0, 2.0, 1.):
                tau = daycounter.year_fraction(
                    risk_free_ts.reference_date,
                    calendar.advance(
                        risk_free_ts.reference_date,
                        period=maturity)
                )
                forward_price = s0.value * dividend_ts.discount(tau) / \
                                risk_free_ts.discount(tau)
                strike_price = forward_price * np.exp(
                    -moneyness * volatility * np.sqrt(tau)
                )
                options.append(
                    HestonModelHelper(
                        maturity, calendar, s0.value, strike_price, vol,
                        risk_free_ts, dividend_ts
                    )
                )

        for sigma in np.arange(0.1, 0.7, 0.2):
            v0    = 0.01
            kappa = 0.2
            theta = 0.02
            rho   = -0.75

            process = HestonProcess(
                risk_free_ts, dividend_ts, s0, v0, kappa, theta, sigma, rho
            )

            self.assertEqual(v0, process.v0)
            self.assertEqual(kappa, process.kappa)
            self.assertEqual(theta, process.theta)
            self.assertEqual(sigma, process.sigma)
            self.assertEqual(rho, process.rho)
            self.assertEqual(1.0, process.s0.value)

            model = HestonModel(process)
            engine = AnalyticHestonEngine(model, 96)

            for option in options:
                option.set_pricing_engine(engine)

            optimisation_method = LevenbergMarquardt(1e-8, 1e-8, 1e-8)

            end_criteria = EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8)
            model.calibrate(options, optimisation_method, end_criteria)

            tolerance = 3.0e-3

            self.assertFalse(model.sigma > tolerance)

            self.assertAlmostEqual(
                model.kappa * model.theta,
                model.kappa * volatility ** 2,
                delta=tolerance
            )
            self.assertAlmostEqual(model.v0, volatility ** 2, delta=tolerance)
Ejemplo n.º 51
0
    def test_bates_det_jump(self):
        # this looks like a bug in QL:
        # Bates Det Jump model does not have sigma as parameter, yet
        # changing sigma changes the result!

        settlement_date = today()
        self.settings.evaluation_date = settlement_date

        daycounter = ActualActual()

        exercise_date = settlement_date + 6 * Months

        payoff = PlainVanillaPayoff(Put, 1290)
        exercise = EuropeanExercise(exercise_date)
        option = VanillaOption(payoff, exercise)

        risk_free_ts = flat_rate(0.02, daycounter)
        dividend_ts = flat_rate(0.04, daycounter)

        spot = 1290

        ival = {'delta': 3.6828677022272715e-06,
        'kappa': 19.02581428347027,
        'kappaLambda': 1.1209758060939223,
        'lambda': 0.06524550732595163,
        'nu': -1.8968106563601956,
        'rho': -0.7480898462264719,
        'sigma': 1.0206363887835108,
        'theta': 0.01965384459461113,
        'thetaLambda': 0.028915397380738218,
        'v0': 0.06566800935242285}

        process = BatesProcess(
        risk_free_ts, dividend_ts, SimpleQuote(spot),
        ival['v0'], ival['kappa'],
        ival['theta'], ival['sigma'], ival['rho'],
        ival['lambda'], ival['nu'], ival['delta'])

        model = BatesDetJumpModel(process,
                ival['kappaLambda'], ival['thetaLambda'])

        engine = BatesDetJumpEngine(model, 64)

        option.set_pricing_engine(engine)

        calc_1 = option.net_present_value

        ival['sigma'] = 1.e-6

        process = BatesProcess(
        risk_free_ts, dividend_ts, SimpleQuote(spot),
        ival['v0'], ival['kappa'],
        ival['theta'], ival['sigma'], ival['rho'],
        ival['lambda'], ival['nu'], ival['delta'])

        model = BatesDetJumpModel(process,
                ival['kappaLambda'], ival['thetaLambda'])
        engine = BatesDetJumpEngine(model, 64)

        option.set_pricing_engine(engine)

        calc_2 = option.net_present_value

        if(abs(calc_1-calc_2) > 1.e-5):
            print('calc 1 %f calc 2 %f' % (calc_1, calc_2))
        self.assertNotEqual(calc_1, calc_2)
Ejemplo n.º 52
0
    def test_deposit_swap(self):

        settings = Settings()

        # Market information
        calendar = TARGET()

        # must be a business day
        eval_date = calendar.adjust(today())
        settings.evaluation_date = eval_date

        settlement_days = 2
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date);

        depositData = [[ 1, Months, 4.581 ],
                       [ 2, Months, 4.573 ],
                       [ 3, Months, 4.557 ],
                       [ 6, Months, 4.496 ],
                       [ 9, Months, 4.490 ]]

        swapData = [[ 1, Years, 4.54 ],
                    [ 5, Years, 4.99 ],
                    [ 10, Years, 5.47 ],
                    [ 20, Years, 5.89 ],
                    [ 30, Years, 5.96 ]]

        rate_helpers = []

        end_of_month = True

        for m, period, rate in depositData:
            tenor = Period(m, Months)

            helper = DepositRateHelper(rate/100, tenor, settlement_days,
                     calendar, ModifiedFollowing, end_of_month,
                     Actual360())

            rate_helpers.append(helper)

        liborIndex = Libor('USD Libor', Period(6, Months), settlement_days,
                           USDCurrency(), calendar, Actual360())

        spread = SimpleQuote(0)
        fwdStart = Period(0, Days)

        for m, period, rate in swapData:
            rate = SimpleQuote(rate/100)

            helper = SwapRateHelper(rate, Period(m, Years),
                calendar, Annual,
                Unadjusted, Thirty360(),
                liborIndex, spread, fwdStart)

            rate_helpers.append(helper)

        ts_day_counter = ActualActual(ISDA)
        tolerance = 1.0e-15

        ts = term_structure_factory(
            'discount', 'loglinear', settlement_date, rate_helpers,
            ts_day_counter, tolerance)

        # this is not a real test ...
        self.assertAlmostEquals(0.9103,
             ts.discount(calendar.advance(today(), 2, Years)),3)
        self.assertAlmostEquals(0.7836,
             ts.discount(calendar.advance(today(), 5, Years)),3)
        self.assertAlmostEquals(0.5827,
             ts.discount(calendar.advance(today(), 10, Years)),3)
        self.assertAlmostEquals(0.4223,
             ts.discount(calendar.advance(today(), 15, Years)),3)
Ejemplo n.º 53
0
def get_term_structure(df_libor, dtObs):
    
    settings = Settings()

    # Market information
    calendar = TARGET()

    # must be a business day
    eval_date = calendar.adjust(today())
    settings.evaluation_date = eval_date

    settlement_days = 2
    settlement_date = calendar.advance(eval_date, settlement_days, Days)
    # must be a business day
    settlement_date = calendar.adjust(settlement_date);

    depositData =[[1, Months, 'Libor1M'],
                  [3, Months, 'Libor3M'],
                  [6, Months, 'Libor6M']]

    swapData = [[ 1, Years, 'Swap1Y'],
                [ 2, Years, 'Swap2Y'],
                [ 3, Years, 'Swap3Y'],
                [ 4, Years, 'Swap4Y'],
                [ 5, Years, 'Swap5Y'],
                [ 7, Years, 'Swap7Y'],
                [ 10, Years,'Swap10Y'],
                [ 30, Years,'Swap30Y']]

    rate_helpers = []

    end_of_month = True

    for m, period, label in depositData:
        tenor = Period(m, Months)
        rate = df_libor.get_value(dtObs, label)
        helper = DepositRateHelper(float(rate/100), tenor,
                 settlement_days,
                 calendar, ModifiedFollowing, end_of_month,
                 Actual360())

        rate_helpers.append(helper)

    endOfMonth = True

    liborIndex = Libor('USD Libor', Period(6, Months),
                       settlement_days,
                       USDCurrency(), calendar,
                       ModifiedFollowing,
                       endOfMonth, Actual360())

    spread = SimpleQuote(0)
    fwdStart = Period(0, Days)

    for m, period, label in swapData:
        rate = df_libor.get_value(dtObs, label)
        helper = SwapRateHelper(SimpleQuote(rate/100),
                 Period(m, Years), 
            calendar, Annual,
            Unadjusted, Thirty360(),
            liborIndex, spread, fwdStart)

        rate_helpers.append(helper)

    ts_day_counter = ActualActual(ISDA)
    tolerance = 1.0e-15

    ts = term_structure_factory(
        'discount', 'loglinear', settlement_date, rate_helpers,
        ts_day_counter, tolerance)

    return ts
Ejemplo n.º 54
0
    def test_zero_curve_on_swap_index(self):

        todays_date = today()

        calendar = UnitedStates() # INPUT
        dayCounter = Actual360() # INPUT
        currency = USDCurrency() # INPUT

        Settings.instance().evaluation_date = todays_date
        settlement_days	= 2

        settlement_date =  calendar.advance(
            todays_date, period=Period(settlement_days, Days)
        )

        liborRates = [ SimpleQuote(0.002763), SimpleQuote(0.004082), SimpleQuote(0.005601), SimpleQuote(0.006390), SimpleQuote(0.007125),
            SimpleQuote(0.007928), SimpleQuote(0.009446), SimpleQuote(0.01110)]
        liborRatesTenor = [Period(tenor, Months) for tenor in [1,2,3,4,5,6,9,12]]
        Libor_dayCounter = Actual360();


        swapRates = [SimpleQuote(0.005681), SimpleQuote(0.006970), SimpleQuote(0.009310), SimpleQuote(0.012010), SimpleQuote(0.014628),
                 SimpleQuote(0.016881), SimpleQuote(0.018745), SimpleQuote(0.020260), SimpleQuote(0.021545)]
        swapRatesTenor = [Period(i, Years) for i in range(2, 11)]
        # description of the fixed leg of the swap
        Swap_fixedLegTenor = Period(12, Months)      # INPUT
        Swap_fixedLegConvention = ModifiedFollowing  # INPUT
        Swap_fixedLegDayCounter = Actual360()        # INPUT
        # description of the float leg of the swap
        Swap_iborIndex = Libor(
            "USDLibor", Period(3, Months), settlement_days, USDCurrency(),
            UnitedStates(), Actual360()
        )

        SwapFamilyName = currency.name + "swapIndex"
        instruments = []

        # ++++++++++++++++++++ Creation of the vector of RateHelper (need for the Yield Curve construction)
        # ++++++++++++++++++++ Libor
        LiborFamilyName = currency.name + "Libor"
        instruments = []
        for rate, tenor in zip(liborRates, liborRatesTenor):
            # Index description ___ creation of a Libor index
            liborIndex =  Libor(
                LiborFamilyName, tenor, settlement_days, currency, calendar,
                Libor_dayCounter
            )
            # Initialize rate helper
            # the DepositRateHelper link the recording rate with the Libor
            # index

            instruments.append(DepositRateHelper(rate, index=liborIndex))


        for tenor, rate in zip(swapRatesTenor, swapRates):
            # swap description ___ creation of a swap index. The floating leg is described in the index 'Swap_iborIndex'
            swapIndex = SwapIndex (
                SwapFamilyName, tenor, settlement_days, currency, calendar,
                Swap_fixedLegTenor, Swap_fixedLegConvention,
                Swap_fixedLegDayCounter, Swap_iborIndex
            )
            # Initialize rate helper __ the SwapRateHelper links the swap index width his rate
            instruments.append(SwapRateHelper.from_index(rate,swapIndex))

        # ++++++++++++++++++  Now the creation of the yield curve

        tolerance = 1.0e-15

        ts = PiecewiseYieldCurve.from_reference_date(
            BootstrapTrait.ZeroYield, Interpolator.Linear, settlement_date, instruments, dayCounter,
            tolerance
        )

        self.assertEqual(settlement_date, ts.reference_date)
Ejemplo n.º 55
0
# The Heston Process
# ------------------

# <codecell>


def flat_rate(forward, daycounter):
    return FlatForward(
        forward=SimpleQuote(forward),
        settlement_days=0,
        calendar=NullCalendar(),
        daycounter=daycounter
    )

settings = Settings.instance()
settlement_date = today()
settings.evaluation_date = settlement_date

daycounter = ActualActual()
calendar = NullCalendar()

interest_rate = .1
dividend_yield = .04

risk_free_ts = flat_rate(interest_rate, daycounter)
dividend_ts = flat_rate(dividend_yield, daycounter)

s0 = SimpleQuote(100.0)

# Heston model
Ejemplo n.º 56
0
    def test_zero_curve_on_swap_index(self):

        todays_date = today()

        calendar = UnitedStates() # INPUT
        dayCounter = Actual360() # INPUT
        currency = USDCurrency() # INPUT	

        Settings.instance().evaluation_date = todays_date
        settlement_days	= 2

        settlement_date =  calendar.advance(
            todays_date, period=Period(settlement_days, Days)
        )

        liborRates = [ SimpleQuote(0.002763), SimpleQuote(0.004082), SimpleQuote(0.005601), SimpleQuote(0.006390), SimpleQuote(0.007125), 
            SimpleQuote(0.007928), SimpleQuote(0.009446), SimpleQuote(0.01110)]
        liborRatesTenor = [Period(tenor, Months) for tenor in [1,2,3,4,5,6,9,12]]
        Libor_dayCounter = Actual360();


        swapRates = [SimpleQuote(0.005681), SimpleQuote(0.006970), SimpleQuote(0.009310), SimpleQuote(0.012010), SimpleQuote(0.014628),
                 SimpleQuote(0.016881), SimpleQuote(0.018745), SimpleQuote(0.020260), SimpleQuote(0.021545)]
        swapRatesTenor = [Period(i, Years) for i in range(2, 11)]
        # description of the fixed leg of the swap
        Swap_fixedLegTenor = Period(12, Months)      # INPUT
        Swap_fixedLegConvention = ModifiedFollowing  # INPUT
        Swap_fixedLegDayCounter = Actual360()        # INPUT
        # description of the float leg of the swap
        Swap_iborIndex = Libor(
            "USDLibor", Period(3, Months), settlement_days, USDCurrency(),
            UnitedStates(), Actual360()
        )

        SwapFamilyName = currency.name + "swapIndex"
        instruments = []

        # ++++++++++++++++++++ Creation of the vector of RateHelper (need for the Yield Curve construction)
        # ++++++++++++++++++++ Libor 
        LiborFamilyName = currency.name + "Libor"
        instruments = []
        for rate, tenor in zip(liborRates, liborRatesTenor):
            # Index description ___ creation of a Libor index
            liborIndex =  Libor(
                LiborFamilyName, tenor, settlement_days, currency, calendar,
                Libor_dayCounter
            )
            # Initialize rate helper
            # the DepositRateHelper link the recording rate with the Libor
            # index

            instruments.append(DepositRateHelper(rate, index=liborIndex))


        for tenor, rate in zip(swapRatesTenor, swapRates):
            # swap description ___ creation of a swap index. The floating leg is described in the index 'Swap_iborIndex'
            swapIndex = SwapIndex (
                SwapFamilyName, tenor, settlement_days, currency, calendar,
                Swap_fixedLegTenor, Swap_fixedLegConvention,
                Swap_fixedLegDayCounter, Swap_iborIndex
            )
            # Initialize rate helper __ the SwapRateHelper links the swap index width his rate
            instruments.append(SwapRateHelper.from_index(rate,swapIndex))

        # ++++++++++++++++++  Now the creation of the yield curve

        tolerance = 1.0e-15

        ts = PiecewiseYieldCurve(
            'zero', 'linear', settlement_date, instruments, dayCounter,
            tolerance
        )

        self.assertEqual(settlement_date, ts.reference_date)