Example #1
0
    def test_extrapolation(self):
        rate_helpers = build_helpers()
        settings = Settings()

        calendar = TARGET()

        # must be a business Days
        dtObs = date(2007, 4, 27)
        eval_date = calendar.adjust(pydate_to_qldate(dtObs))
        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)

        print('dt Obs: %s\ndt Eval: %s\ndt Settle: %s' %
              (dtObs, eval_date, settlement_date))
        ts_day_counter = ActualActual(ISDA)
        tolerance = 1.0e-2

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

        # max_date raises an exception without extrapolaiton...
        self.assertFalse(ts.extrapolation)
        with self.assertRaisesRegexp(RuntimeError,
                                     "1st iteration: failed at 2nd alive instrument"):
            dtMax = ts.max_date
Example #2
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
Example #3
0
    def test_extrapolation(self):
        rate_helpers = build_helpers()
        settings = Settings()

        calendar = TARGET()

        # must be a business Days
        dtObs = date(2007, 4, 27)
        eval_date = calendar.adjust(pydate_to_qldate(dtObs))
        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)

        print('dt Obs: %s\ndt Eval: %s\ndt Settle: %s' %
              (dtObs, eval_date, settlement_date))
        ts_day_counter = ActualActual(ISDA)
        tolerance = 1.0e-2

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

        # max_date raises an exception without extrapolaiton...
        self.assertFalse(ts.extrapolation)
        with self.assertRaises(RuntimeError) as ctx:
            ts.discount(ts.max_date + 1)
        self.assertTrue(str(ctx.exception) in (
            "time (30.011) is past max curve time (30.0082)",
            "1st iteration: failed at 2nd alive instrument"))
Example #4
0
    def test_zero_curve(self):
        rate_helpers = build_helpers()
        settings = Settings()

        calendar = TARGET()

        # must be a business Days
        dtObs = date(2007, 4, 27)
        eval_date = calendar.adjust(pydate_to_qldate(dtObs))
        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)

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

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

        # max_date raises an exception...
        ts.extrapolation = True
        zr = ts.zero_rate(Date(10, 5, 2027), ts_day_counter, 2)
        self.assertAlmostEqual(zr.rate, 0.0539332)
    def test_discount_curve(self):
        settings = Settings()
        settings.evaluation_date = Date(6, 10, 2016)

        # Market information
        calendar = TARGET()

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

        deposit_day_counter = Actual365Fixed()
        convention = ModifiedFollowing
        end_of_month = True
        fixing_days = 3
        rate_helpers = [DepositRateHelper(
            quote, Period(month, Months), fixing_days, calendar, convention, end_of_month,
            deposit_day_counter) for quote, month in zip(quotes, tenors)]

        ts_day_counter = ActualActual(ISDA)

        tolerance = 1.0e-15

        ts = PiecewiseYieldCurve(
            BootstrapTrait.ForwardRate, Interpolator.BackwardFlat, 2, calendar, rate_helpers,
            ts_day_counter, tolerance
        )

        dates = [rh.latest_date for rh in rate_helpers]
        dfs = [ts.discount(d) for d in dates]
        dates.insert(0, ts.reference_date)
        dfs.insert(0, 1)
        ts_discount = DiscountCurve(dates, dfs, ts_day_counter, calendar)
        self.assertTrue(ts.discount(0.75), ts_discount.discount(0.75))
Example #6
0
    def bootstrap_term_structure(self, interpolator=Interpolator.LogLinear):
        tolerance = 1.0e-15
        settings = Settings()
        calendar = JointCalendar(UnitedStates(), UnitedKingdom())
        # must be a business day
        eval_date = self._eval_date
        settings.evaluation_date = eval_date
        settlement_days = self._params.settlement_days
        settlement_date = calendar.advance(eval_date, settlement_days, Days)
        # must be a business day
        settlement_date = calendar.adjust(settlement_date)
        ts = PiecewiseYieldCurve.from_reference_date(
            BootstrapTrait.Discount,
            interpolator,
            settlement_date,
            self._rate_helpers,
            DayCounter.from_name(self._termstructure_daycount),
            tolerance,
        )
        self._term_structure = ts
        self._discount_term_structure = YieldTermStructure()
        self._discount_term_structure.link_to(ts)

        self._forecast_term_structure = YieldTermStructure()
        self._forecast_term_structure.link_to(ts)

        return ts
    def test_bump_yieldcurve(self):
        settings = Settings()
        settings.evaluation_date = Date(6, 10, 2016)

        # Market information
        calendar = TARGET()

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

        deposit_day_counter = Actual365Fixed()
        convention = ModifiedFollowing
        end_of_month = True
        fixing_days = 3
        rate_helpers = [DepositRateHelper(
            quote, Period(month, Months), fixing_days, calendar, convention, end_of_month,
            deposit_day_counter) for quote, month in zip(quotes, tenors)]

        ts_day_counter = ActualActual(ISDA)

        tolerance = 1.0e-15

        ts = PiecewiseYieldCurve(
            BootstrapTrait.Discount, Interpolator.LogLinear, 2, calendar, rate_helpers,
            ts_day_counter, tolerance
        )
        old_discount = ts.discount(ts.max_date)
        # parallel shift of 1 bps
        for rh in rate_helpers:
            rh.quote.value += 1e-4
        self.assertEqual([q.value for q in quotes], [rh.quote.value for rh in rate_helpers])
        new_discount = ts.discount(ts.max_date)
        self.assertTrue(new_discount < old_discount)
Example #8
0
    def test_settings_instance_method(self):

        Settings.instance().evaluation_date = today()

        self.assertEqual(
                today(),
                Settings.instance().evaluation_date
        )
Example #9
0
 def _set_evaluation_date(self, dt_obs):
     if(~isinstance(dt_obs, Date)):
         dt_obs = pydate_to_qldate(dt_obs)
     settings = Settings()
     calendar = JointCalendar(UnitedStates(), UnitedKingdom())
     # must be a business day
     eval_date = calendar.adjust(dt_obs)
     settings.evaluation_date = eval_date
     self._eval_date = eval_date
     return eval_date
Example #10
0
def zbt_libor_yield(instruments, yields, pricing_date,
                    basis='Actual/Actual (Bond)',
                    compounding_freq='Continuous',
                    maturity_dates=None):
    """
    Bootstrap a zero-coupon curve from libor rates and swap yields

    Args:

    insruments:    list of instruments, of the form Libor?M for Libor rates
                   and Swap?Y for swap rates
    yields:        market rates
    pricing_date:  the date where market data is observed. Settlement
                   is by default 2 days after pricing_date

    Optional:

    compounding_frequency: ... of zero-coupon rates. By default:
                   'Continuous'

    Returns:

    zero_rate:     zero-coupon rate
    maturity_date: ... of corresponding rate
    """

    calendar = TARGET()

    settings = Settings()
    # must be a business day
    eval_date = calendar.adjust(pydate_to_qldate(pricing_date))
    settings.evaluation_date = eval_date

    rates = dict(zip(instruments, yields))
    ts = make_term_structure(rates, pricing_date)

    cnt = DayCounter.from_name(basis)

    if maturity_dates is None:
        # schedule of maturity dates from settlement date to last date on
        # the term structure

        s = Schedule(effective_date=ts.reference_date,
                     termination_date=ts.max_date,
                     tenor=Period(1, Months),
                     calendar=TARGET())
        maturity_dates = [qldate_to_pydate(dt) for dt in s.dates()]

    cp_freq = compounding_from_name(compounding_freq)
    zc = [ts.zero_rate(date=pydate_to_qldate(dt),
                       day_counter=cnt,
                       compounding=cp_freq).rate for dt in maturity_dates]

    return (maturity_dates, zc)
Example #11
0
    def test_excel_example_with_fixed_rate_bond(self):
        """Port the QuantLib Excel adding bond example to Python. """

        todays_date = Date(25, August, 2011)

        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(
            effective_date, termination_date, Period(Annual), calendar, ModifiedFollowing, ModifiedFollowing, Backward
        )

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

        discounting_term_structure = YieldTermStructure(relinkable=True)
        flat_term_structure = FlatForward(
            settlement_days=1,
            forward=0.044,
            calendar=NullCalendar(),
            daycounter=Actual365Fixed(),
            compounding=Continuous,
            frequency=Annual,
        )

        discounting_term_structure.link_to(flat_term_structure)

        engine = DiscountingBondEngine(discounting_term_structure)

        bond.set_pricing_engine(engine)

        self.assertEquals(Date(10, Jul, 2016), termination_date)
        self.assertEquals(calendar.advance(todays_date, 3, Days), bond.settlement_date())
        self.assertEquals(Date(11, Jul, 2016), bond.maturity_date)
        self.assertAlmostEqual(0.6849, bond.accrued_amount(bond.settlement_date()), 4)
        self.assertAlmostEqual(102.1154, bond.clean_price, 4)
Example #12
0
def _cfamounts(coupon_rate, pricing_date, maturity_date,
              period, basis):
    """
    cash flow schedule
    """

    _period = str_to_frequency(period)

    evaluation_date = pydate_to_qldate(pricing_date)

    settings = Settings()
    settings.evaluation_date = evaluation_date

    calendar = TARGET()
    termination_date = pydate_to_qldate(maturity_date)

    # effective date must be before settlement date, but do not
    # care about exact issuance date of bond

    effective_date = Date(termination_date.day, termination_date.month,
                          evaluation_date.year)
    effective_date = calendar.advance(
        effective_date, -1, Years, convention=Unadjusted)

    face_amount = 100.0
    redemption = 100.0

    fixed_bond_schedule = Schedule(
        effective_date,
        termination_date,
        Period(_period),
        calendar,
        ModifiedFollowing,
        ModifiedFollowing,
        Backward
    )

    issue_date = effective_date
    cnt = DayCounter.from_name(basis)
    settlement_days = 2

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

    res = zip(*bond.cashflows)

    return(res)
    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)
    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)
Example #15
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'))
Example #16
0
def make_rate_helper(label, rate, dt_obs, currency='USD'):
    """
    Wrapper for deposit and swaps rate helpers makers
    For Swaps: assume USD swap fixed rates vs. 6M Libor
    TODO: make this more general
    """

    if(currency.upper() != 'USD'):
        raise Exception("Only supported currency is USD.")

    rate_type, tenor, period = _parse_rate_label(label)

    if not isinstance(dt_obs, Date):
        dt_obs = pydate_to_qldate(dt_obs)
        
    settings = Settings()
    calendar = JointCalendar(UnitedStates(), UnitedKingdom())
    # must be a business day
    eval_date = calendar.adjust(dt_obs)
    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)
    end_of_month = True

    if((rate_type == 'SWAP') & (period == 'Y')):
        liborIndex = Libor(
            'USD Libor', Period(6, Months), settlement_days,
            USDCurrency(), calendar, Actual360()
        )
        spread = SimpleQuote(0)
        fwdStart = Period(0, Days)
        helper = SwapRateHelper.from_tenor(
            SimpleQuote(rate),
            Period(tenor, Years),
            calendar, Annual,
            Unadjusted, Thirty360(),
            liborIndex, spread, fwdStart)
    elif((rate_type == 'LIBOR') & (period == 'M')):
        helper = DepositRateHelper(SimpleQuote(rate),
                                   Period(tenor, Months),
                                   settlement_days,
                                   calendar,
                                   ModifiedFollowing,
                                   end_of_month,
                                   Actual360())
    else:
        raise Exception("Rate type %s not supported" % label)

    return (helper)
Example #17
0
def heston_helpers(spot, df_option, dtTrade, df_rates):
    """
    Create array of heston options helpers
    """

    DtSettlement = dateToQLDate(dtTrade)
    
    settings = Settings()
    settings.evaluation_date = DtSettlement

    calendar = TARGET()

    # convert data frame (date/value) into zero curve
    # expect the index to be a date, and 1 column of values

    risk_free_ts = dfToZeroCurve(df_rates['iRate'], dtTrade)
    dividend_ts = dfToZeroCurve(df_rates['iDiv'], dtTrade)

    # loop through rows in option data frame, construct
    # helpers for bid/ask

    oneDay = datetime.timedelta(days=1)
    dtExpiry = [dtTrade + int(t*365)*oneDay for t in df_option['TTM']]
    df_option['dtExpiry'] = dtExpiry

    options = []
    for index, row in df_option.T.iteritems():

        strike = row['Strike']
        if (strike/spot.value > 1.3) | (strike/spot.value < .7):
            continue

        days = int(365*row['TTM'])
        maturity = Period(days, Days)

        options.append(
                HestonModelHelper(
                    maturity, calendar, spot.value,
                    strike, SimpleQuote(row['IVBid']),
                    risk_free_ts, dividend_ts,
                    ImpliedVolError))
        
        options.append(
                HestonModelHelper(
                    maturity, calendar, spot.value,
                    strike, SimpleQuote(row['IVAsk']),
                    risk_free_ts, dividend_ts,
                    ImpliedVolError))

    return {'options':options, 'spot': spot}
Example #18
0
    def test_bond_schedule_anotherday(self):
        '''Test date calculations and role of settings when evaluation date
        set to arbitrary date.

        This test is known to fail with boost 1.42.

        '''

        todays_date = Date(30, August, 2011)

        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())
    def test_all_types_of_piecewise_curves(self):

        settings = Settings()

        # Market information
        calendar = TARGET()

        todays_date = Date(12, September, 2008)
        # must be a business day
        settings.evaluation_date = calendar.adjust(todays_date)

        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 = []

        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)


        tolerance = 1.0e-15 

        for trait in VALID_TRAITS:
            for interpolation in VALID_INTERPOLATORS:
                ts = PiecewiseYieldCurve(
                    trait, interpolation, settlement_date, rate_helpers,
                    deposit_day_counter, tolerance
                )

                self.assertIsNotNone(ts)
                self.assertEqual( Date(18, September, 2008), ts.reference_date)
Example #20
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))
Example #21
0
def create_helper():

    calendar = TARGET()

    todays_date = Date(15, May, 2007)
    todays_date = calendar.adjust(todays_date)

    Settings.instance().evaluation_date = todays_date

    flat_rate = SimpleQuote(0.01)
    ts_curve = FlatForward(todays_date, flat_rate, Actual365Fixed())

    recovery_rate = 0.5
    quoted_spreads = 0.0150
    tenor = Period(3, Months)

    helper = SpreadCdsHelper(
        quoted_spreads,
        tenor,
        0,
        calendar,
        Quarterly,
        Following,
        TwentiethIMM,
        Actual365Fixed(),
        recovery_rate,
        ts_curve,
    )

    return todays_date, helper
Example #22
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)
Example #23
0
    def test_create_interpolated_hazard(self):
        Settings.instance().evaluation_date = self.todays_date

        dates = [self.todays_date + Period(i, Years) for i in [3, 5, 7]]
        hazard_rates =  [0.01, 0.03, 0.05]

        interpolation_date = self.todays_date + Period(4, Years)

        trait = Interpolator.Linear
        interpolated_curve = InterpolatedHazardRateCurve(trait, dates,
                                                         hazard_rates,
                                                         Actual365Fixed())
        t0 = interpolated_curve.time_from_reference(dates[0])
        t1 = interpolated_curve.time_from_reference(interpolation_date)
        t2 = interpolated_curve.time_from_reference(dates[1])
        interpolated_value = hazard_rates[0] + (t1-t0) /(t2-t0) * \
                             (hazard_rates[1] - hazard_rates[0])

        self.assertAlmostEqual(interpolated_value,
                               interpolated_curve.hazard_rate(interpolation_date))
        trait = Interpolator.BackwardFlat
        interpolated_curve = InterpolatedHazardRateCurve(trait, dates,
                                                         hazard_rates,
                                                         Actual365Fixed())
        interpolated_value = hazard_rates[1]
        self.assertAlmostEqual(interpolated_value,
                               interpolated_curve.hazard_rate(interpolation_date))
        trait = Interpolator.LogLinear
        interpolated_curve = InterpolatedHazardRateCurve(trait, dates,
                                                         hazard_rates,
                                                         Actual365Fixed())
        with self.assertRaisesRegexp(RuntimeError,
                                     'LogInterpolation primitive not implemented'):
            hazard_rate = interpolated_curve.hazard_rate(interpolation_date)
Example #24
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)
Example #25
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)
Example #26
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)
Example #27
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(
            effective_date,
            termination_date,
            Period(Annual),
            calendar,
            ModifiedFollowing,
            ModifiedFollowing,
            Backward
        )

        issue_date = effective_date

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

        self.assertEquals(
            calendar.advance(todays_date, 3, Days), bond.settlement_date())
Example #28
0
    def set_quotes(self, dt_obs, quotes):
        self._quotes = quotes
        if(~isinstance(dt_obs, Date)):
            dt_obs = pydate_to_qldate(dt_obs)
        settings = Settings()
        calendar = JointCalendar(UnitedStates(), UnitedKingdom())
        # must be a business day
        eval_date = calendar.adjust(dt_obs)
        settings.evaluation_date = eval_date

        self._eval_date = eval_date

        self._rate_helpers = []
        for quote in quotes:
            # construct rate helper
            helper = make_rate_helper(self, quote, eval_date)
            self._rate_helpers.append(helper)
Example #29
0
def heston_pricer(trade_date, options, params, rates, spot):
    """
    Price a list of European options with heston model.

    """

    spot = SimpleQuote(spot)

    risk_free_ts = df_to_zero_curve(rates[nm.INTEREST_RATE], trade_date)
    dividend_ts = df_to_zero_curve(rates[nm.DIVIDEND_YIELD], trade_date)

    process = HestonProcess(risk_free_ts, dividend_ts, spot, **params)

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

    settlement_date = pydate_to_qldate(trade_date)

    settings = Settings()
    settings.evaluation_date = settlement_date

    modeled_values = np.zeros(len(options))

    for index, row in options.T.iteritems():

        expiry_date = row[nm.EXPIRY_DATE]
        strike = row[nm.STRIKE]

        option_type = Call if row[nm.OPTION_TYPE] == nm.CALL_OPTION else Put

        payoff = PlainVanillaPayoff(option_type, strike)

        expiry_qldate = pydate_to_qldate(expiry_date)
        exercise = EuropeanExercise(expiry_qldate)

        option = VanillaOption(payoff, exercise)
        option.set_pricing_engine(engine)

        modeled_values[index] = option.net_present_value

    prices = options.filter(items=[nm.EXPIRY_DATE, nm.STRIKE,
                                   nm.OPTION_TYPE, nm.SPOT])
    prices[nm.PRICE] = modeled_values
    prices[nm.TRADE_DATE] = trade_date

    return prices
Example #30
0
 def test_flat_hazard_with_quote(self):
     Settings.instance().evaluation_date = self.todays_date
     hazard_rate = SimpleQuote()
     flat_curve = FlatHazardRate(2, self.calendar, hazard_rate, Actual365Fixed())
     for h in [0.01, 0.02, 0.03]:
         hazard_rate.value =  h
         self.assertAlmostEqual(flat_curve.survival_probability(self.d),
                                math.exp(-h * flat_curve.time_from_reference(self.d)))
Example #31
0
    def test_swap_from_market(self):
        """
        Test that a swap with fixed coupon = fair rate has an NPV=0
        Create from market
        """

        eval_date = Date(2, January, 2014)
        settings = Settings()
        settings.evaluation_date = eval_date

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

        length = 5
        fixed_rate = .05
        floating_spread = 0.0

        m = libor_market('USD(NY)')

        quotes = [('DEP', '1W', SimpleQuote(0.0382)),
                  ('DEP', '1M', SimpleQuote(0.0372)),
                  ('DEP', '3M', SimpleQuote(0.0363)),
                  ('DEP', '6M', SimpleQuote(0.0353)),
                  ('DEP', '9M', SimpleQuote(0.0348)),
                  ('DEP', '1Y', SimpleQuote(0.0345)),
                  ('SWAP', '2Y', SimpleQuote(0.037125)),
                  ('SWAP', '3Y', SimpleQuote(0.0398)),
                  ('SWAP', '5Y', SimpleQuote(0.0443)),
                  ('SWAP', '10Y', SimpleQuote(0.05165)),
                  ('SWAP', '15Y', SimpleQuote(0.055175))]

        m.set_quotes(eval_date, quotes)

        m.bootstrap_term_structure()

        dt = Date(2, January, 2015)
        df = m.discount(dt)
        print('discount factor for %s (USD Libor): %f' % (dt, df))

        swap = m.create_fixed_float_swap(settlement_date, length, fixed_rate,
                                         floating_spread)

        fixed_l = swap.fixed_leg

        float_l = swap.floating_leg

        f = swap.fair_rate
        print('fair rate: %f' % f)
        p = swap.net_present_value
        print('NPV: %f' % p)

        fixed_npv = swap.fixed_leg_npv
        float_npv = swap.floating_leg_npv

        # verify calculation by discounting both legs
        tot = 0.0
        for frc in fixed_l:
            df = m.discount(frc.date)
            tot += frc.amount * df
        print('fixed npv: %f discounted cf: %f' % (fixed_npv, tot))
        self.assertAlmostEqual(fixed_npv, -tot)

        tot = 0.0
        for ic in float_l:
            df = m.discount(ic.date)
            tot += ic.amount * df
        print('float npv: %f discounted cf: %f' % (float_npv, tot))
        self.assertAlmostEqual(float_npv, tot)
Example #32
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)
Example #33
0
def get_term_structure(df_libor, dtObs):

    settings = Settings()

    # libor as fixed in London, but cash-flows are determined according to
    # US calendar, hence the need to combine both holidays lists
    calendar = JointCalendar(UnitedStates(), UnitedKingdom())

    # must be a business day
    eval_date = calendar.adjust(dateToDate(dtObs))
    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, Actual360())

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

    for m, period, label in swapData:
        rate = df_libor.get_value(dtObs, label)
        helper = SwapRateHelper.from_tenor(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
Example #34
0
    def test_settings_instance_method(self):

        Settings.instance().evaluation_date = today()

        self.assertEqual(today(), Settings.instance().evaluation_date)
Example #35
0
def get_term_structure(df_libor, dtObs):
    
    settings = Settings()

    # Market information
    calendar = TARGET()

    # must be a business day
    eval_date = calendar.adjust(dateToDate(dtObs))
    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
Example #36
0
    def setUp(self):
        self.calendar = UnitedKingdom()
        today = Date(25, 11, 2009)
        evaluation_date = self.calendar.adjust(today)
        Settings().evaluation_date = evaluation_date
        day_counter = ActualActual()

        rpi_schedule = Schedule.from_rule(Date(20, 7,
                                               2007), Date(20, 11, 2009),
                                          Period(1, Months), self.calendar,
                                          ModifiedFollowing)
        self.cpi_ts = ZeroInflationTermStructure()
        self.yts = FlatForward(evaluation_date, 0.05, day_counter)
        self.ii = UKRPI(False, self.cpi_ts)
        fix_data = [
            206.1, 207.3, 208.0, 208.9, 209.7, 210.9, 209.8, 211.4, 212.1,
            214.0, 215.1, 216.8, 216.5, 217.2, 218.4, 217.7, 216, 212.9, 210.1,
            211.4, 211.3, 211.5, 212.8, 213.4, 213.4, 213.4, 214.4
        ]

        for date, data in zip(rpi_schedule, fix_data):
            self.ii.add_fixing(date, data)

        dates = [
            Date(25, 11, 2010),
            Date(25, 11, 2011),
            Date(26, 11, 2012),
            Date(25, 11, 2013),
            Date(25, 11, 2014),
            Date(25, 11, 2015),
            Date(25, 11, 2016),
            Date(25, 11, 2017),
            Date(25, 11, 2018),
            Date(25, 11, 2019),
            Date(25, 11, 2021),
            Date(25, 11, 2024),
            Date(26, 11, 2029),
            Date(27, 11, 2034),
            Date(25, 11, 2039),
            Date(25, 11, 2049),
            Date(25, 11, 2059)
        ]

        rates = [
            3.0495, 2.93, 2.9795, 3.029, 3.1425, 3.211, 3.2675, 3.3625, 3.405,
            3.48, 3.576, 3.649, 3.751, 3.77225, 3.77, 3.734, 3.714
        ]

        observation_lag = Period('2M')
        self.helpers = [ZeroCouponInflationSwapHelper(
            SimpleQuote(r / 100),
            observation_lag,
            maturity, self.calendar, ModifiedFollowing, day_counter, self.ii, self.yts) \
                        for maturity, r in zip(dates, rates)]
        base_zero_rate = rates[0] / 100

        self.cpi_ts.link_to(
            PiecewiseZeroInflationCurve(Interpolator.Linear, evaluation_date,
                                        self.calendar, day_counter,
                                        observation_lag, self.ii.frequency,
                                        self.ii.interpolated, base_zero_rate,
                                        self.helpers))
Example #37
0
    def test_default_constructor(self):

        term_structure = YieldTermStructure()

        with self.assertRaises(ValueError):
            term_structure.discount(Settings().evaluation_date)
Example #38
0
    def test_pricing_bond(self):
        '''Inspired by the C++ code from http://quantcorner.wordpress.com/.'''

        settings = Settings()

        # Date setup
        calendar = TARGET()

        # Settlement date
        settlement_date = calendar.adjust(Date(28, January, 2011))

        # Evaluation date
        fixing_days = 1
        settlement_days = 1

        todays_date = calendar.advance(settlement_date, -fixing_days, Days)

        settings.evaluation_date = todays_date

        # Bound attributes
        face_amount = 100.0
        redemption = 100.0
        issue_date = Date(27, January, 2011)
        maturity_date = Date(31, August, 2020)
        coupon_rate = 0.03625
        bond_yield = 0.034921

        discounting_term_structure = YieldTermStructure(relinkable=True)
        flat_term_structure = FlatForward(
            reference_date=settlement_date,
            forward=bond_yield,
            daycounter=Actual365Fixed(
            ),  #actual_actual.ActualActual(actual_actual.Bond),
            compounding=Compounded,
            frequency=Semiannual)
        # have a look at the FixedRateBondHelper to simplify this
        # construction
        discounting_term_structure.link_to(flat_term_structure)

        #Rate
        fixed_bond_schedule = Schedule.from_rule(
            issue_date, maturity_date, Period(Semiannual),
            UnitedStates(market=GOVERNMENTBOND), Unadjusted, Unadjusted,
            Backward, False)

        bond = FixedRateBond(settlement_days, face_amount,
                             fixed_bond_schedule, [coupon_rate],
                             ActualActual(Bond), Unadjusted, redemption,
                             issue_date)

        bond.set_pricing_engine(discounting_term_structure)

        # tests
        self.assertTrue(Date(27, January, 2011), bond.issue_date)
        self.assertTrue(Date(31, August, 2020), bond.maturity_date)
        self.assertTrue(settings.evaluation_date, bond.valuation_date)

        # the following assertion fails but must be verified
        self.assertAlmostEqual(101.1, bond.clean_price, 1)
        self.assertAlmostEqual(101.1, bond.net_present_value, 1)
        self.assertAlmostEqual(101.1, bond.dirty_price)
        self.assertAlmostEqual(0.009851, bond.accrued_amount())

        print(settings.evaluation_date)
        print('Principal: {}'.format(face_amount))
        print('Issuing date: {} '.format(bond.issue_date))
        print('Maturity: {}'.format(bond.maturity_date))
        print('Coupon rate: {:.4%}'.format(coupon_rate))
        print('Yield: {:.4%}'.format(bond_yield))
        print('Net present value: {:.4f}'.format(bond.net_present_value))
        print('Clean price: {:.4f}'.format(bond.clean_price))
        print('Dirty price: {:.4f}'.format(bond.dirty_price))
        print('Accrued coupon: {:.6f}'.format(bond.accrued_amount()))
        print('Accrued coupon: {:.6f}'.format(
            bond.accrued_amount(Date(1, March, 2011))))
Example #39
0
    def test_compare_BsmHW_HestonHW(self):
        """
        From Quantlib test suite
        """

        print("Comparing European option pricing for a BSM " +
              "process with one-factor Hull-White model...")

        dc = Actual365Fixed()

        todays_date = today()
        settings = Settings()
        settings.evaluation_date = todays_date
        tol = 1.e-2

        spot = SimpleQuote(100)

        dates = [todays_date + Period(i, Years) for i in range(40)]

        rates = [0.01 + 0.0002 * np.exp(np.sin(i / 4.0)) for i in range(40)]
        divRates = [0.02 + 0.0001 * np.exp(np.sin(i / 5.0)) for i in range(40)]

        s0 = SimpleQuote(100)

        r_ts = ZeroCurve(dates, rates, dc)
        q_ts = ZeroCurve(dates, divRates, dc)

        vol = SimpleQuote(0.25)
        vol_ts = BlackConstantVol(todays_date, NullCalendar(), vol.value, dc)

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

        variance = vol.value * vol.value
        hestonProcess = HestonProcess(risk_free_rate_ts=r_ts,
                                      dividend_ts=q_ts,
                                      s0=s0,
                                      v0=variance,
                                      kappa=5.0,
                                      theta=variance,
                                      sigma=1e-4,
                                      rho=0.0)

        hestonModel = HestonModel(hestonProcess)

        hullWhiteModel = HullWhite(r_ts, a=0.01, sigma=0.01)

        bsmhwEngine = AnalyticBSMHullWhiteEngine(0.0, bsm_process,
                                                 hullWhiteModel)

        hestonHwEngine = AnalyticHestonHullWhiteEngine(hestonModel,
                                                       hullWhiteModel, 128)

        tol = 1e-5
        strikes = [0.25, 0.5, 0.75, 0.8, 0.9, 1.0, 1.1, 1.2, 1.5, 2.0, 4.0]
        maturities = [1, 2, 3, 5, 10, 15, 20, 25, 30]
        types = [Put, Call]

        for type in types:
            for strike in strikes:
                for maturity in maturities:
                    maturity_date = todays_date + Period(maturity, Years)

                    exercise = EuropeanExercise(maturity_date)

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

                    payoff = PlainVanillaPayoff(type, fwd)

                    option = VanillaOption(payoff, exercise)

                    option.set_pricing_engine(bsmhwEngine)
                    calculated = option.npv

                    option.set_pricing_engine(hestonHwEngine)
                    expected = option.npv

                    if ((np.abs(expected - calculated) > calculated * tol)
                            and (np.abs(expected - calculated) > tol)):

                        cp = PAYOFF_TO_STR[type]
                        print("Failed to reproduce npv")
                        print("strike    : %f" % strike)
                        print("maturity  : %d" % maturity)
                        print("type      : %s" % cp)

                    self.assertAlmostEqual(expected, calculated, delta=tol)
Example #40
0
    def test_excel_example_with_floating_rate_bond(self):

        todays_date = Date(25, August, 2011)

        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_date = calendar.adjust(Date(28, January, 2011))
        settlement_days = 3  #1
        face_amount = 13749769.27  #2
        coupon_rate = 0.05
        redemption = 100.0

        float_bond_schedule = Schedule.from_rule(effective_date,
                                                 termination_date,
                                                 Period(Annual), calendar,
                                                 ModifiedFollowing,
                                                 ModifiedFollowing,
                                                 Backward)  #3

        flat_discounting_term_structure = YieldTermStructure()
        forecastTermStructure = YieldTermStructure()

        dc = Actual360()
        ibor_index = Euribor6M(forecastTermStructure)  #5

        fixing_days = 2  #6
        gearings = [1, 0.0]  #7
        spreads = [1, 0.05]  #8
        caps = []  #9
        floors = []  #10
        pmt_conv = ModifiedFollowing  #11

        issue_date = effective_date

        float_bond = FloatingRateBond(settlement_days, face_amount,
                                      float_bond_schedule, ibor_index, dc,
                                      fixing_days, gearings, spreads, caps,
                                      floors, pmt_conv, True, redemption,
                                      issue_date)

        flat_term_structure = FlatForward(settlement_days=1,
                                          forward=0.055,
                                          calendar=NullCalendar(),
                                          daycounter=Actual365Fixed(),
                                          compounding=Continuous,
                                          frequency=Annual)
        flat_discounting_term_structure.link_to(flat_term_structure)
        forecastTermStructure.link_to(flat_term_structure)

        engine = DiscountingBondEngine(flat_discounting_term_structure)

        float_bond.set_pricing_engine(engine)
        cons_option_vol = ConstantOptionletVolatility(settlement_days,
                                                      UnitedStates(Settlement),
                                                      pmt_conv, 0.95,
                                                      Actual365Fixed())
        coupon_pricer = BlackIborCouponPricer(cons_option_vol)

        set_coupon_pricer(float_bond, coupon_pricer)

        self.assertEqual(Date(10, Jul, 2016), termination_date)
        self.assertEqual(calendar.advance(todays_date, 3, Days),
                         float_bond.settlement_date())
        self.assertEqual(Date(11, Jul, 2016), float_bond.maturity_date)
        self.assertAlmostEqual(
            0.6944, float_bond.accrued_amount(float_bond.settlement_date()), 4)
        self.assertAlmostEqual(98.2485, float_bond.dirty_price, 4)
        self.assertAlmostEqual(13500805.2469, float_bond.npv, 4)
from quantlib.quotes import SimpleQuote
from quantlib.termstructures.yields.rate_helpers import DepositRateHelper, FraRateHelper, SwapRateHelper
from quantlib.termstructures.yields.ois_rate_helper import OISRateHelper, DatedOISRateHelper
from quantlib.termstructures.yields.piecewise_yield_curve import PiecewiseYieldCurve
from quantlib.termstructures.yields.bootstraptraits import Discount
from quantlib.termstructures.yields.api import YieldTermStructure
from quantlib.math.interpolation import Cubic
from quantlib.indexes.ibor.eonia import Eonia
from quantlib.indexes.api import Euribor6M
from quantlib.instruments.swap import SwapType
from quantlib.instruments.vanillaswap import VanillaSwap
from quantlib.pricingengines.swap import DiscountingSwapEngine

calendar = TARGET()
todays_date = Date(11, 12, 2012)
Settings().evaluation_date = todays_date

fixing_days = 2
settlement_date = calendar.advance(todays_date, fixing_days, Days)
settlement_date = calendar.adjust(settlement_date)

# deposits
dONRate = SimpleQuote(0.0004)
dTNRate = SimpleQuote(0.0004)
dSNRate = SimpleQuote(0.0004)

# OIS
ois1WRate = SimpleQuote(0.00070)
ois2WRate = SimpleQuote(0.00069)
ois3WRate = SimpleQuote(0.00078)
ois1MRate = SimpleQuote(0.00074)
Example #42
0
    def test_excel_example_with_fixed_rate_bond(self):
        '''Port the QuantLib Excel adding bond example to Python. '''


        todays_date = Date(25, August, 2011)


        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,
            Backward
        )

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

        discounting_term_structure = YieldTermStructure()
        flat_term_structure = FlatForward(
            settlement_days = 1,
            forward         = 0.044,
            calendar        = NullCalendar(),
            daycounter      = Actual365Fixed(),
            compounding     = Continuous,
            frequency       = Annual)

        discounting_term_structure.link_to(flat_term_structure)

        engine = DiscountingBondEngine(discounting_term_structure)

        bond.set_pricing_engine(engine)


        self.assertEqual(Date(10, Jul, 2016), termination_date)
        self.assertEqual(
            calendar.advance(todays_date, 3, Days), bond.settlement_date()
        )
        self.assertEqual(Date(11, Jul, 2016), bond.maturity_date)
        self.assertAlmostEqual(
            0.6849, bond.accrued_amount(bond.settlement_date()), 4
        )
        self.assertAlmostEqual(102.1154, bond.clean_price, 4)
Example #43
0
def dividendOption():
    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # ++++++++++++++++++++ General Parameter for all the computation +++++++++++++++++++++++
    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    # declaration of the today's date (date where the records are done)
    todaysDate = Date(24, Jan, 2012)  # INPUT
    Settings.instance(
    ).evaluation_date = todaysDate  #!\ IMPORTANT COMMAND REQUIRED FOR ALL VALUATIONS
    calendar = UnitedStates()  # INPUT
    settlement_days = 2  # INPUT
    # Calcul of the settlement date : need to add a period of 2 days to the todays date
    settlementDate = calendar.advance(todaysDate,
                                      period=Period(settlement_days, Days))
    dayCounter = Actual360()  # INPUT
    currency = USDCurrency()  # INPUT

    print("Date of the evaluation:			", todaysDate)
    print("Calendar used:         			", calendar.name)
    print("Number of settlement Days:		", settlement_days)
    print("Date of settlement:       		", settlementDate)
    print("Convention of day counter:		", dayCounter.name)
    print("Currency of the actual context:\t\t", currency.name)

    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # ++++++++++++++++++++ Description of the underlying +++++++++++++++++++++++++++++++++++
    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    underlying_name = "IBM"
    underlying_price = 191.75  # INPUT
    underlying_vol = 0.2094  # INPUT

    print("**********************************")
    print("Name of the underlying:			", underlying_name)
    print("Price of the underlying at t0:	", underlying_price)
    print("Volatility of the underlying:		", underlying_vol)

    # For a great managing of price and vol objects --> Handle
    underlying_priceH = SimpleQuote(underlying_price)

    # We suppose the vol constant : his term structure is flat --> BlackConstantVol object
    flatVolTS = BlackConstantVol(settlementDate, calendar, underlying_vol,
                                 dayCounter)

    # ++++++++++++++++++++ Description of Yield Term Structure

    #  Libor data record
    print("**********************************")
    print("Description of the Libor used for the Yield Curve construction")

    Libor_dayCounter = Actual360()

    liborRates = []
    liborRatesTenor = []
    # INPUT : all the following data are input : the rate and the corresponding tenor
    #		You could make the choice of more or less data
    #		--> However you have tho choice the instruments with different maturities
    liborRates = [
        0.002763, 0.004082, 0.005601, 0.006390, 0.007125, 0.007928, 0.009446,
        0.01110
    ]
    liborRatesTenor = [
        Period(tenor, Months) for tenor in [1, 2, 3, 4, 5, 6, 9, 12]
    ]

    for tenor, rate in zip(liborRatesTenor, liborRates):
        print(tenor, "\t\t\t", rate)

    # Swap data record

    # 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())

    print("Description of the Swap used for the Yield Curve construction")
    print("Tenor of the fixed leg:			", Swap_fixedLegTenor)
    print("Index of the floated leg: 		", Swap_iborIndex.name)
    print("Maturity		Rate				")

    swapRates = []
    swapRatesTenor = []
    # INPUT : all the following data are input : the rate and the corresponding tenor
    #		You could make the choice of more or less data
    #		--> However you have tho choice the instruments with different maturities
    swapRates = [
        0.005681, 0.006970, 0.009310, 0.012010, 0.014628, 0.016881, 0.018745,
        0.020260, 0.021545
    ]
    swapRatesTenor = [Period(i, Years) for i in range(2, 11)]

    for tenor, rate in zip(swapRatesTenor, swapRates):
        print(tenor, "\t\t\t", rate)

    # ++++++++++++++++++++ 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))

    # +++++++++++++++++++++ Swap
    SwapFamilyName = currency.name + "swapIndex"
    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

    riskFreeTS = PiecewiseYieldCurve.from_reference_date(
        BootstrapTrait.ZeroYield, Interpolator.Linear, settlementDate,
        instruments, dayCounter)

    # ++++++++++++++++++  build of the underlying process : with a Black-Scholes model

    print('Creating process')

    bsProcess = BlackScholesProcess(underlying_priceH, riskFreeTS, flatVolTS)

    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # ++++++++++++++++++++ Description of the option +++++++++++++++++++++++++++++++++++++++
    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    Option_name = "IBM Option"
    maturity = Date(26, Jan, 2013)
    strike = 190
    option_type = Call

    # Here, as an implementation exemple, we make the test with borth american and european exercise
    europeanExercise = EuropeanExercise(maturity)
    # The emericanExercise need also the settlement date, as his right to exerce the buy or call start at the settlement date!
    #americanExercise = AmericanExercise(settlementDate, maturity)
    americanExercise = AmericanExercise(maturity, settlementDate)

    print("**********************************")
    print("Description of the option:		", Option_name)
    print("Date of maturity:     			", maturity)
    print("Type of the option:   			", option_type)
    print("Strike of the option:		    ", strike)

    # ++++++++++++++++++ Description of the discrete dividends
    # INPUT You have to determine the frequece and rates of the discrete dividend. Here is a sollution, but she's not the only one.
    # Last know dividend:
    dividend = 0.75  #//0.75
    next_dividend_date = Date(10, Feb, 2012)
    # HERE we have make the assumption that the dividend will grow with the quarterly croissance:
    dividendCroissance = 1.03
    dividendfrequence = Period(3, Months)
    dividendDates = []
    dividends = []

    d = next_dividend_date
    while d <= maturity:
        dividendDates.append(d)
        dividends.append(dividend)
        d = d + dividendfrequence
        dividend *= dividendCroissance

    print("Discrete dividends				")
    print("Dates				Dividends		")
    for date, div in zip(dividendDates, dividends):
        print(date, "		", div)

    # ++++++++++++++++++ Description of the final payoff
    payoff = PlainVanillaPayoff(option_type, strike)

    # ++++++++++++++++++ The OPTIONS : (American and European) with their dividends description:
    dividendEuropeanOption = DividendVanillaOption(payoff, europeanExercise,
                                                   dividendDates, dividends)
    dividendAmericanOption = DividendVanillaOption(payoff, americanExercise,
                                                   dividendDates, dividends)

    # just too test
    europeanOption = VanillaOption(payoff, europeanExercise)
    americanOption = VanillaOption(payoff, americanExercise)

    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # ++++++++++++++++++++ Description of the pricing  +++++++++++++++++++++++++++++++++++++
    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    # For the european options we have a closed analytic formula: The Black Scholes:
    dividendEuropeanEngine = AnalyticDividendEuropeanEngine(bsProcess)

    # For the american option we have make the choice of the finite difference model with the CrankNicolson scheme
    #		this model need to precise the time and space step
    #		More they are greater, more the calul will be precise.
    americanGirdPoints = 600
    americanTimeSteps = 600
    dividendAmericanEngine = FDDividendAmericanEngine('CrankNicolson',
                                                      bsProcess,
                                                      americanTimeSteps,
                                                      americanGirdPoints)

    # just to test
    europeanEngine = AnalyticEuropeanEngine(bsProcess)
    americanEngine = FDAmericanEngine('CrankNicolson', bsProcess,
                                      americanTimeSteps, americanGirdPoints)

    # ++++++++++++++++++++ Valorisation ++++++++++++++++++++++++++++++++++++++++

    # Link the pricing Engine to the option
    dividendEuropeanOption.set_pricing_engine(dividendEuropeanEngine)
    dividendAmericanOption.set_pricing_engine(dividendAmericanEngine)

    # just	to test
    europeanOption.set_pricing_engine(europeanEngine)
    americanOption.set_pricing_engine(americanEngine)

    # Now we make all the needing calcul
    # ... and final results
    print(
        "NPV of the European Option with discrete dividends=0:	{:.4f}".format(
            dividendEuropeanOption.npv))
    print("NPV of the European Option without dividend:		{:.4f}".format(
        europeanOption.npv))
    print(
        "NPV of the American Option with discrete dividends=0:	{:.4f}".format(
            dividendAmericanOption.npv))
    print("NPV of the American Option without dividend:		{:.4f}".format(
        americanOption.npv))
    # just a single test
    print("ZeroRate with a maturity at ", maturity, ": ", \
            riskFreeTS.zero_rate(maturity, dayCounter, Simple))
Example #44
0
    def test_display(self):

        settings = Settings()

        # Date setup
        calendar = TARGET()

        # Settlement date
        settlement_date = calendar.adjust(Date(28, January, 2011))

        # Evaluation date
        fixing_days = 1
        settlement_days = 1

        todays_date = calendar.advance(
            settlement_date, -fixing_days, Days
        )

        settings.evaluation_date = todays_date

        # Bound attributes
        face_amount = 100.0
        redemption = 100.0
        issue_date = Date(27, January, 2011)
        maturity_date = Date(31, August, 2020)
        coupon_rate = 0.03625
        bond_yield = 0.034921

        flat_discounting_term_structure = YieldTermStructure()
        flat_term_structure = FlatForward(
            reference_date = settlement_date,
            forward        = bond_yield,
            daycounter     = Actual365Fixed(), #actual_actual.ActualActual(actual_actual.Bond),
            compounding    = Compounded,
            frequency      = Semiannual)
        # have a look at the FixedRateBondHelper to simplify this
        # construction
        flat_discounting_term_structure.link_to(flat_term_structure)


	#Rate
        fixed_bond_schedule = Schedule(
            issue_date,
            maturity_date,
            Period(Semiannual),
            UnitedStates(market=GOVERNMENTBOND),
            Unadjusted,
            Unadjusted,
            Backward,
            False);


        bond = FixedRateBond(
            settlement_days,
		    face_amount,
		    fixed_bond_schedule,
		    [coupon_rate],
            ActualActual(Bond),
		    Unadjusted,
            redemption,
            issue_date
        )



        d=bf.startDate(bond)

        zspd=bf.zSpread(bond, 100.0, flat_term_structure, Actual365Fixed(),
        Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5)


        #Also need a test case for a PiecewiseTermStructure...
        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(SimpleQuote(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(),
                           YieldTermStructure(relinkable=False))

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

        for m, period, rate in swapData:

            helper = SwapRateHelper.from_tenor(
                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 = PiecewiseYieldCurve.from_reference_date(
            BootstrapTrait.Discount, Interpolator.LogLinear, settlement_date, rate_helpers,
            ts_day_counter, tolerance)

        pyc_zspd=bf.zSpread(bond, 102.0, ts, ActualActual(ISDA),
        Compounded, Semiannual, Date(1, April, 2015), 1e-6, 100, 0.5)

        pyc_zspd_disco=bf.zSpread(bond, 95.0, ts, ActualActual(ISDA),
        Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5)


        yld  = bf.yld(bond, 102.0, ActualActual(ISDA), Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5)
        dur  = bf.duration(bond, yld, ActualActual(ISDA), Compounded, Semiannual, 2, settlement_date)

        yld_disco  = bf.yld(bond, 95.0, ActualActual(ISDA), Compounded, Semiannual, settlement_date, 1e-6, 100, 0.5)
        dur_disco  = bf.duration(bond, yld_disco, ActualActual(ISDA), Compounded, Semiannual, 2, settlement_date)

        self.assertEqual(round(zspd, 6), 0.001281)
        self.assertEqual(round(pyc_zspd, 4), -0.0264)
        self.assertEqual(round(pyc_zspd_disco, 4), -0.0114)

        self.assertEqual(round(yld, 4), 0.0338)
        self.assertEqual(round(yld_disco, 4), 0.0426)

        self.assertEqual(round(dur, 4), 8.0655)
        self.assertEqual(round(dur_disco, 4), 7.9702)
Example #45
0
    def test_heston_hw_calibration(self):
        """
        From Quantlib test suite
        """

        print("Testing Heston Hull-White calibration...")

        ## Calibration of a hybrid Heston-Hull-White model using
        ## the finite difference HestonHullWhite pricing engine
        ## Input surface is based on a Heston-Hull-White model with
        ## Hull-White: a = 0.00883, \sigma = 0.00631
        ## Heston    : \nu = 0.12, \kappa = 2.0,
        ##             \theta = 0.09, \sigma = 0.5, \rho=-0.75
        ## Equity Short rate correlation: -0.5

        dc = Actual365Fixed()
        calendar = TARGET()
        todays_date = Date(28, March, 2004)
        settings = Settings()
        settings.evaluation_date = todays_date

        r_ts = flat_rate(0.05, dc)

        ## assuming, that the Hull-White process is already calibrated
        ## on a given set of pure interest rate calibration instruments.

        hw_process = HullWhiteProcess(r_ts, a=0.00883, sigma=0.00631)

        q_ts = flat_rate(0.02, dc)
        s0 = SimpleQuote(100.0)

        # vol surface

        strikes = [50, 75, 90, 100, 110, 125, 150, 200]
        maturities = [1 / 12., 3 / 12., 0.5, 1.0, 2.0, 3.0, 5.0, 7.5, 10]

        vol = [
            0.482627, 0.407617, 0.366682, 0.340110, 0.314266, 0.280241,
            0.252471, 0.325552, 0.464811, 0.393336, 0.354664, 0.329758,
            0.305668, 0.273563, 0.244024, 0.244886, 0.441864, 0.375618,
            0.340464, 0.318249, 0.297127, 0.268839, 0.237972, 0.225553,
            0.407506, 0.351125, 0.322571, 0.305173, 0.289034, 0.267361,
            0.239315, 0.213761, 0.366761, 0.326166, 0.306764, 0.295279,
            0.284765, 0.270592, 0.250702, 0.222928, 0.345671, 0.314748,
            0.300259, 0.291744, 0.283971, 0.273475, 0.258503, 0.235683,
            0.324512, 0.303631, 0.293981, 0.288338, 0.283193, 0.276248,
            0.266271, 0.250506, 0.311278, 0.296340, 0.289481, 0.285482,
            0.281840, 0.276924, 0.269856, 0.258609, 0.303219, 0.291534,
            0.286187, 0.283073, 0.280239, 0.276414, 0.270926, 0.262173
        ]

        start_v0 = 0.2 * 0.2
        start_theta = start_v0
        start_kappa = 0.5
        start_sigma = 0.25
        start_rho = -0.5

        equityShortRateCorr = -0.5

        corrConstraint = HestonHullWhiteCorrelationConstraint(
            equityShortRateCorr)

        heston_process = HestonProcess(r_ts, q_ts, s0, start_v0, start_kappa,
                                       start_theta, start_sigma, start_rho)

        h_model = HestonModel(heston_process)
        h_engine = AnalyticHestonEngine(h_model)

        options = []

        # first calibrate a heston model to get good initial
        # parameters

        for i in range(len(maturities)):
            maturity = Period(int(maturities[i] * 12.0 + 0.5), Months)

            for j, s in enumerate(strikes):

                v = SimpleQuote(vol[i * len(strikes) + j])

                helper = HestonModelHelper(maturity, calendar, s0.value, s, v,
                                           r_ts, q_ts, PriceError)

                helper.set_pricing_engine(h_engine)

                options.append(helper)

        om = LevenbergMarquardt(1e-6, 1e-8, 1e-8)

        # Heston model
        h_model.calibrate(options, om,
                          EndCriteria(400, 40, 1.0e-8, 1.0e-4, 1.0e-8))

        print("Heston calibration")
        print("v0: %f" % h_model.v0)
        print("theta: %f" % h_model.theta)
        print("kappa: %f" % h_model.kappa)
        print("sigma: %f" % h_model.sigma)
        print("rho: %f" % h_model.rho)

        h_process_2 = HestonProcess(r_ts, q_ts, s0, h_model.v0, h_model.kappa,
                                    h_model.theta, h_model.sigma, h_model.rho)

        hhw_model = HestonModel(h_process_2)

        options = []
        for i in range(len(maturities)):

            tGrid = np.max((10.0, maturities[i] * 10.0))
            hhw_engine = FdHestonHullWhiteVanillaEngine(
                hhw_model, hw_process, equityShortRateCorr, tGrid, 61, 13, 9,
                0, True, FdmSchemeDesc.Hundsdorfer())

            hhw_engine.enable_multiple_strikes_caching(strikes)

            maturity = Period(int(maturities[i] * 12.0 + 0.5), Months)

            # multiple strikes engine works best if the first option
            # per maturity has the average strike (because the first
            # option is priced first during the calibration and
            # the first pricing is used to calculate the prices
            # for all strikes

            # list of strikes by distance from moneyness

            indx = np.argsort(np.abs(np.array(strikes) - s0.value))

            for j, tmp in enumerate(indx):
                js = indx[j]
                s = strikes[js]
                v = SimpleQuote(vol[i * len(strikes) + js])
                helper = HestonModelHelper(maturity, calendar, s0.value,
                                           strikes[js], v, r_ts, q_ts,
                                           PriceError)
                helper.set_pricing_engine(hhw_engine)
                options.append(helper)

        vm = LevenbergMarquardt(1e-6, 1e-2, 1e-2)

        hhw_model.calibrate(options, vm,
                            EndCriteria(400, 40, 1.0e-8, 1.0e-4, 1.0e-8),
                            corrConstraint)

        print("Heston HW calibration with FD engine")
        print("v0: %f" % hhw_model.v0)
        print("theta: %f" % hhw_model.theta)
        print("kappa: %f" % hhw_model.kappa)
        print("sigma: %f" % hhw_model.sigma)
        print("rho: %f" % hhw_model.rho)

        relTol = 0.05
        expected_v0 = 0.12
        expected_kappa = 2.0
        expected_theta = 0.09
        expected_sigma = 0.5
        expected_rho = -0.75

        self.assertAlmostEqual(np.abs(hhw_model.v0 - expected_v0) /
                               expected_v0,
                               0,
                               delta=relTol)

        self.assertAlmostEqual(np.abs(hhw_model.theta - expected_theta) /
                               expected_theta,
                               0,
                               delta=relTol)

        self.assertAlmostEqual(np.abs(hhw_model.kappa - expected_kappa) /
                               expected_kappa,
                               0,
                               delta=relTol)

        self.assertAlmostEqual(np.abs(hhw_model.sigma - expected_sigma) /
                               expected_sigma,
                               0,
                               delta=relTol)

        self.assertAlmostEqual(np.abs(hhw_model.rho - expected_rho) /
                               expected_rho,
                               0,
                               delta=relTol)
Example #46
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
from __future__ import print_function
# simple example to demonstrate the use of Settings()


from quantlib.quotes import SimpleQuote
from quantlib.settings import Settings
from quantlib.termstructures.yields.api import FlatForward
from quantlib.time.api import Actual360, Date, NullCalendar, TARGET

calendar = TARGET()
settings = Settings()

date_today      = Date(6,9,2011)
date_payment    = Date(6,10,2011)
settlement_days = 2

settings.evaluation_date = date_today
quote = SimpleQuote(value=0.03)

term_structure = FlatForward(
    settlement_days = settlement_days,
    quote           = quote,
    calendar        = NullCalendar(),
    daycounter      = Actual360()
)

df_1 = term_structure.discount(date_payment)

date_today = Date(19,9,2011)
settings.evaluation_date = date_today
Example #48
0
    def setUp(self):

        self.settings = Settings()
Example #49
0
def heston_helpers(df_option, dtTrade=None, df_rates=None, ival=None):
    """
    Create array of heston options helpers
    """

    if dtTrade is None:
        dtTrade = df_option['dtTrade'][0]
    DtSettlement = pydate_to_qldate(dtTrade)

    settings = Settings()
    settings.evaluation_date = DtSettlement

    calendar = TARGET()

    if df_rates is None:
        df_tmp = DataFrame.filter(df_option, items=['dtExpiry', 'IR', 'IDIV'])
        grouped = df_tmp.groupby('dtExpiry')
        df_rates = grouped.agg(lambda x: x[0])

    # convert data frame (date/value) into zero curve
    # expect the index to be a date, and 1 column of values

    risk_free_ts = df_to_zero_curve(df_rates['R'], dtTrade)
    dividend_ts = df_to_zero_curve(df_rates['D'], dtTrade)

    # back out the spot from any forward
    iRate = df_option['R'][0]
    iDiv = df_option['D'][0]
    TTM = df_option['T'][0]
    Fwd = df_option['F'][0]
    spot = SimpleQuote(Fwd * np.exp(-(iRate - iDiv) * TTM))
    print('Spot: %f risk-free rate: %f div. yield: %f' % \
          (spot.value, iRate, iDiv))

    # loop through rows in option data frame, construct
    # helpers for bid/ask

    oneDay = datetime.timedelta(days=1)
    dtExpiry = [dtTrade + int(t * 365) * oneDay for t in df_option['T']]
    df_option['dtExpiry'] = dtExpiry

    options = []
    for index, row in df_option.T.iteritems():

        strike = row['K']
        if (strike / spot.value > 1.3) | (strike / spot.value < .7):
            continue

        days = int(365 * row['T'])
        maturity = Period(days, Days)

        options.append(
            HestonModelHelper(maturity, calendar, spot.value, strike,
                              SimpleQuote(row['VB']), risk_free_ts,
                              dividend_ts, ImpliedVolError))

        options.append(
            HestonModelHelper(maturity, calendar, spot.value, strike,
                              SimpleQuote(row['VA']), risk_free_ts,
                              dividend_ts, ImpliedVolError))

    return {'options': options, 'spot': spot}
Example #50
0
    def test_compare_bsm_bsmhw_hestonhw(self):

        dc = Actual365Fixed()

        todays_date = today()
        settings = Settings()
        settings.evaluation_date = todays_date
        tol = 1.e-2

        spot = SimpleQuote(100)

        dates = [todays_date + Period(i, Years) for i in range(40)]

        rates = [0.01 + 0.0002 * np.exp(np.sin(i / 4.0)) for i in range(40)]
        divRates = [0.02 + 0.0001 * np.exp(np.sin(i / 5.0)) for i in range(40)]

        s0 = SimpleQuote(100)

        r_ts = ZeroCurve(dates, rates, dc)
        q_ts = ZeroCurve(dates, divRates, dc)

        vol = SimpleQuote(0.25)
        vol_ts = BlackConstantVol(todays_date, NullCalendar(), vol.value, dc)

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

        payoff = PlainVanillaPayoff(Call, 100)
        exercise = EuropeanExercise(dates[1])

        option = VanillaOption(payoff, exercise)

        analytic_european_engine = AnalyticEuropeanEngine(bsm_process)

        option.set_pricing_engine(analytic_european_engine)
        npv_bsm = option.npv

        variance = vol.value * vol.value
        hestonProcess = HestonProcess(risk_free_rate_ts=r_ts,
                                      dividend_ts=q_ts,
                                      s0=s0,
                                      v0=variance,
                                      kappa=5.0,
                                      theta=variance,
                                      sigma=1e-4,
                                      rho=0.0)

        hestonModel = HestonModel(hestonProcess)

        hullWhiteModel = HullWhite(r_ts, a=0.01, sigma=0.01)

        bsmhwEngine = AnalyticBSMHullWhiteEngine(0.0, bsm_process,
                                                 hullWhiteModel)

        hestonHwEngine = AnalyticHestonHullWhiteEngine(hestonModel,
                                                       hullWhiteModel, 128)

        hestonEngine = AnalyticHestonEngine(hestonModel, 144)
        option.set_pricing_engine(hestonEngine)

        npv_heston = option.npv

        option.set_pricing_engine(bsmhwEngine)
        npv_bsmhw = option.npv

        option.set_pricing_engine(hestonHwEngine)
        npv_hestonhw = option.npv

        print("calculated with BSM: %f" % npv_bsm)
        print("BSM-HW: %f" % npv_bsmhw)
        print("Heston: %f" % npv_heston)
        print("Heston-HW: %f" % npv_hestonhw)

        self.assertAlmostEqual(npv_bsm, npv_bsmhw, delta=tol)
        self.assertAlmostEqual(npv_bsm, npv_hestonhw, delta=tol)
class TestOvernightIndexedSwap(unittest.TestCase):
    def setUp(self):
        self.today = Date(5, 2, 2009)
        self.settlement_days = 2
        self.nominal = 100
        self.settings = Settings().__enter__()
        self.settings.evaluation_date = self.today
        self.eonia_term_structure = YieldTermStructure()
        self.eonia_index = Eonia(self.eonia_term_structure)
        self.calendar = self.eonia_index.fixing_calendar
        self.settlement = self.calendar.advance(self.today,
                                                self.settlement_days,
                                                Following)
        self.eonia_term_structure.link_to(flat_rate(0.05))

    def make_swap(self,
                  length,
                  fixed_rate,
                  spread,
                  telescopic_value_dates,
                  effective_date=None,
                  payment_lag=0,
                  averaging_method=RateAveraging.Compound):
        return (MakeOIS(
            length, self.eonia_index, fixed_rate,
            0 * Days).with_effective_date(
                self.settlement if effective_date is None else effective_date
            ).with_overnight_leg_spread(spread).with_nominal(
                self.nominal).with_payment_lag(
                    payment_lag).with_discounting_term_structure(
                        self.eonia_term_structure).with_telescopic_value_dates(
                            telescopic_value_dates).with_averaging_method(
                                averaging_method))()

    def test_fair_rate(self):
        lengths = [1 * Years, 2 * Years, 5 * Years, 10 * Years, 20 * Years]
        spreads = [-0.001, -.01, 0.0, 0.01, 0.001]
        for length, spread in product(lengths, spreads):
            with self.subTest(length=length, spread=spread):
                swap = self.make_swap(length, 0.0, spread, False)
                swap2 = self.make_swap(length, 0.0, spread, True)
                self.assertAlmostEqual(swap.fair_rate, swap2.fair_rate)

                swap = self.make_swap(length, swap.fair_rate, spread, False)
                self.assertAlmostEqual(swap.npv, 0.0)
                swap = self.make_swap(length, swap.fair_rate, spread, True)
                self.assertAlmostEqual(swap.npv, 0.0)

    def test_fair_spread(self):
        lengths = [1 * Years, 2 * Years, 5 * Years, 10 * Years, 20 * Years]
        rates = [0.04, 0.05, 0.06, 0.07]
        for length, rate in product(lengths, rates):
            with self.subTest(length=length, rate=rate):
                swap = self.make_swap(length, rate, 0.0, False)
                swap2 = self.make_swap(length, rate, 0.0, True)
                fair_spread = swap.fair_spread
                fair_spread2 = swap.fair_spread
                self.assertAlmostEqual(swap.fair_spread, swap2.fair_spread)
                swap = self.make_swap(length, rate, fair_spread, False)
                self.assertAlmostEqual(swap.npv, 0.0)
                swap = self.make_swap(length, rate, fair_spread, True)
                self.assertAlmostEqual(swap.npv, 0.0)

    def test_cached_value(self):
        flat = 0.05
        self.eonia_term_structure.link_to(
            flat_rate(flat, Actual360(), reference_date=self.settlement))
        fixed_rate = math.exp(flat) - 1
        swap = self.make_swap(1 * Years, fixed_rate, 0.0, False)
        swap2 = self.make_swap(1 * Years, fixed_rate, 0.0, True)
        cached_npv = 0.001730450147
        self.assertAlmostEqual(swap.npv, cached_npv)
        self.assertAlmostEqual(swap2.npv, cached_npv)

    def tearUp(self):
        self.settings.__exit__(None, None, None)
Example #52
0
)
from quantlib.termstructures.credit.api import SpreadCdsHelper, PiecewiseDefaultCurve
from quantlib.termstructures.yields.api import FlatForward

if __name__ == '__main__':

    #*********************
    #***  MARKET DATA  ***
    #*********************
    calendar = TARGET()

    todays_date = Date(15, May, 2007)
    # must be a business day
    todays_date = calendar.adjust(todays_date)

    Settings.instance().evaluation_date = todays_date

    # dummy curve
    ts_curve = FlatForward(
        reference_date=todays_date, forward=0.01, daycounter=Actual365Fixed()
    )

    # In Lehmans Brothers "guide to exotic credit derivatives"
    # p. 32 there's a simple case, zero flat curve with a flat CDS
    # curve with constant market spreads of 150 bp and RR = 50%
    # corresponds to a flat 3% hazard rate. The implied 1-year
    # survival probability is 97.04% and the 2-years is 94.18%

    # market
    recovery_rate = 0.5
    quoted_spreads = [0.0150, 0.0150, 0.0150, 0.0150 ]
Example #53
0
from quantlib.instruments.payoffs import (PlainVanillaPayoff, Put, Call)

from quantlib.methods.finitedifferences.solvers.fdmbackwardsolver \
     import FdmSchemeDesc


def flat_rate(today, forward, daycounter):
    return FlatForward(reference_date=today,
                       forward=SimpleQuote(forward),
                       daycounter=daycounter)


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
Example #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)
Example #55
0
from quantlib.quotes import SimpleQuote
from quantlib.settings import Settings
from quantlib.time.api import (TARGET, Actual365Fixed, Date, UnitedStates,
                               NullCalendar)
from quantlib.math.matrix import Matrix
from quantlib.termstructures.yields.flat_forward import FlatForward
from quantlib.termstructures.volatility.equityfx.black_variance_surface import BlackVarianceSurface
from quantlib.termstructures.volatility.equityfx.local_vol_surface import LocalVolSurface

dc = Actual365Fixed()
calendar = UnitedStates()

calculation_date = Date(6, 11, 2015)

spot = 659.37
Settings.instance().evaluation_date = calculation_date

dividend_yield = SimpleQuote(0.0)
risk_free_rate = 0.01
dividend_rate = 0.0
# bootstrap the yield/dividend/vol curves
flat_term_structure = FlatForward(reference_date=calculation_date,
                                  forward=risk_free_rate,
                                  daycounter=dc)

flat_dividend_ts = FlatForward(reference_date=calculation_date,
                               forward=dividend_yield,
                               daycounter=dc)

dates = [
    Date(6, 12, 2015),
Example #56
0
    def test_swap_QL(self):
        """
        Test that a swap with fixed coupon = fair rate has an NPV=0
        Create from QL objects
        """

        nominal = 100.0
        fixedConvention = Unadjusted
        floatingConvention = ModifiedFollowing
        fixedFrequency = Annual
        floatingFrequency = Semiannual
        fixedDayCount = Thirty360()
        floatDayCount = Thirty360()
        calendar = TARGET()
        settlement_days = 2

        eval_date = Date(2, January, 2014)
        settings = Settings()
        settings.evaluation_date = eval_date

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

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

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

        length = 5
        fixedRate = .05
        floatingSpread = 0.0

        maturity = calendar.advance(settlement_date,
                                    length,
                                    Years,
                                    convention=floatingConvention)

        fixedSchedule = Schedule(settlement_date, maturity,
                                 Period(fixedFrequency), calendar,
                                 fixedConvention, fixedConvention,
                                 Rule.Forward, False)

        floatSchedule = Schedule(settlement_date, maturity,
                                 Period(floatingFrequency), calendar,
                                 floatingConvention, floatingConvention,
                                 Rule.Forward, False)
        engine = DiscountingSwapEngine(termStructure, False, settlement_date,
                                       settlement_date)
        for swap_type in [Payer, Receiver]:
            swap = VanillaSwap(swap_type, nominal, fixedSchedule, fixedRate,
                               fixedDayCount, floatSchedule, index,
                               floatingSpread, floatDayCount, fixedConvention)
            swap.set_pricing_engine(engine)
            fixed_leg = swap.fixed_leg
            floating_leg = swap.floating_leg

            f = swap.fair_rate
            print('fair rate: %f' % f)
            p = swap.net_present_value
            print('NPV: %f' % p)

            swap = VanillaSwap(swap_type, nominal, fixedSchedule, f,
                               fixedDayCount, floatSchedule, index,
                               floatingSpread, floatDayCount, fixedConvention)
            swap.set_pricing_engine(engine)

            p = swap.net_present_value
            print('NPV: %f' % p)
            self.assertAlmostEqual(p, 0)
Example #57
0
    def test_deposit_swap(self):

        settings = Settings()

        # Market information
        calendar = TARGET()

        todays_date = Date(1, Mar, 2012)

        # must be a business day
        eval_date = calendar.adjust(todays_date)
        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(SimpleQuote(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:

            helper = SwapRateHelper.from_tenor(
                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 = PiecewiseYieldCurve.from_reference_date(
            BootstrapTrait.Discount, Interpolator.LogLinear, settlement_date, rate_helpers,
            ts_day_counter, tolerance
        )

        self.assertEqual(settlement_date, ts.reference_date)

        # this is not a real test ...
        self.assertAlmostEqual(0.9103,
             ts.discount(calendar.advance(todays_date, 2, Years)),3)
        self.assertAlmostEqual(0.7836,
             ts.discount(calendar.advance(todays_date, 5, Years)),3)
        self.assertAlmostEqual(0.5827,
             ts.discount(calendar.advance(todays_date, 10, Years)),3)
        self.assertAlmostEqual(0.4223,
             ts.discount(calendar.advance(todays_date, 15, Years)),3)
Example #58
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)
Example #59
0
def example01():
    #*********************
    #***  MARKET DATA  ***
    #*********************
    calendar = TARGET()

    todays_date = Date(15, May, 2007)
    # must be a business day
    todays_date = calendar.adjust(todays_date)

    Settings.instance().evaluation_date = todays_date

    # dummy curve
    ts_curve = FlatForward(
        reference_date=todays_date, forward=0.01, daycounter=Actual365Fixed()
    )

    # In Lehmans Brothers "guide to exotic credit derivatives"
    # p. 32 there's a simple case, zero flat curve with a flat CDS
    # curve with constant market spreads of 150 bp and RR = 50%
    # corresponds to a flat 3% hazard rate. The implied 1-year
    # survival probability is 97.04% and the 2-years is 94.18%

    # market
    recovery_rate = 0.5
    quoted_spreads = [0.0150, 0.0150, 0.0150, 0.0150 ]
    tenors = [Period(i, Months) for i in [3, 6, 12, 24]]
    maturities = [
        calendar.adjust(todays_date + tenors[i], Following) for i in range(4)
    ]
    instruments = []
    for i in range(4):
        helper = SpreadCdsHelper(
            quoted_spreads[i], tenors[i], 0, calendar, Quarterly,
            Following, Rule.TwentiethIMM, Actual365Fixed(), recovery_rate, ts_curve
        )

        instruments.append(helper)

    # Bootstrap hazard rates
    hazard_rate_structure = PiecewiseDefaultCurve.from_reference_date(
            ProbabilityTrait.HazardRate, Interpolator.BackwardFlat, todays_date, instruments, Actual365Fixed()
    )

    #vector<pair<Date, Real> > hr_curve_data = hazardRateStructure->nodes();

    #cout << "Calibrated hazard rate values: " << endl ;
    #for (Size i=0; i<hr_curve_data.size(); i++) {
    #    cout << "hazard rate on " << hr_curve_data[i].first << " is "
    #         << hr_curve_data[i].second << endl;
    #}
    #cout << endl;

    target = todays_date + Period(1, Years)
    print(target)
    print("Some survival probability values: ")
    print("1Y survival probability: {:%}".format(
            hazard_rate_structure.survival_probability(target)
    ))
    print("               expected: {:%}".format(0.9704))

    print("2Y survival probability: {:%}".format(
        hazard_rate_structure.survival_probability(todays_date + Period(2, Years))
    ))
    print("               expected: {:%}".format(0.9418))

    # reprice instruments
    nominal = 1000000.0;
    #Handle<DefaultProbabilityTermStructure> probability(hazardRateStructure);
    engine = MidPointCdsEngine(hazard_rate_structure, recovery_rate, ts_curve)

    cds_schedule = Schedule.from_rule(
        todays_date, maturities[0], Period(Quarterly), calendar,
        termination_date_convention=Unadjusted,
        date_generation_rule=Rule.TwentiethIMM
    )

    cds_3m = CreditDefaultSwap(
        Side.Seller, nominal, quoted_spreads[0], cds_schedule, Following,
        Actual365Fixed()
    )

    cds_schedule = Schedule.from_rule(
        todays_date, maturities[1], Period(Quarterly), calendar,
        termination_date_convention=Unadjusted,
        date_generation_rule=Rule.TwentiethIMM
    )

    cds_6m = CreditDefaultSwap(
        Side.Seller, nominal, quoted_spreads[1], cds_schedule, Following,
        Actual365Fixed()
    )

    cds_schedule = Schedule.from_rule(
        todays_date, maturities[2], Period(Quarterly), calendar,
        termination_date_convention=Unadjusted,
        date_generation_rule=Rule.TwentiethIMM
    )

    cds_1y = CreditDefaultSwap(
        Side.Seller, nominal, quoted_spreads[2], cds_schedule, Following,
        Actual365Fixed()
    )

    cds_schedule = Schedule.from_rule(
        todays_date, maturities[3], Period(Quarterly), calendar,
        termination_date_convention=Unadjusted,
        date_generation_rule=Rule.TwentiethIMM
    )

    cds_2y = CreditDefaultSwap(
        Side.Seller, nominal, quoted_spreads[3], cds_schedule, Following,
        Actual365Fixed()
    )

    cds_3m.set_pricing_engine(engine);
    cds_6m.set_pricing_engine(engine);
    cds_1y.set_pricing_engine(engine);
    cds_2y.set_pricing_engine(engine);

    print("Repricing of quoted CDSs employed for calibration: ")
    print("3M fair spread: {}".format(cds_3m.fair_spread))
    print("   NPV:         ", cds_3m.net_present_value)
    print("   default leg: ", cds_3m.default_leg_npv)
    print("   coupon leg:  ", cds_3m.coupon_leg_npv)

    print("6M fair spread: {}".format(cds_6m.fair_spread))
    print("   NPV:         ", cds_6m.net_present_value)
    print("   default leg: ", cds_6m.default_leg_npv)
    print("   coupon leg:  ", cds_6m.coupon_leg_npv)

    print("1Y fair spread: {}".format(cds_1y.fair_spread))
    print("   NPV:         ", cds_1y.net_present_value)
    print("   default leg: ", cds_1y.default_leg_npv)
    print("   coupon leg:  ", cds_1y.coupon_leg_npv)

    print("2Y fair spread: {}".format(cds_2y.fair_spread))
    print("   NPV:         ", cds_2y.net_present_value)
    print("   default leg: ", cds_2y.default_leg_npv)
    print("   coupon leg:  ", cds_2y.coupon_leg_npv)
    print()
Example #60
0
    def test_bucketanalysis_bond(self):

        settings = Settings()

        calendar = TARGET()

        settlement_date = calendar.adjust(Date(28, January, 2011))
        simple_quotes = []

        fixing_days = 1
        settlement_days = 1

        todays_date = calendar.advance(settlement_date, -fixing_days, Days)

        settings.evaluation_date = todays_date

        face_amount = 100.0
        redemption = 100.0
        issue_date = Date(27, January, 2011)
        maturity_date = Date(1, January, 2021)
        coupon_rate = 0.055
        bond_yield = 0.034921

        flat_discounting_term_structure = YieldTermStructure()
        flat_term_structure = FlatForward(reference_date=settlement_date,
                                          forward=bond_yield,
                                          daycounter=Actual365Fixed(),
                                          compounding=Compounded,
                                          frequency=Semiannual)

        flat_discounting_term_structure.link_to(flat_term_structure)

        fixed_bond_schedule = Schedule.from_rule(
            issue_date, maturity_date, Period(Semiannual),
            UnitedStates(market=GovernmentBond), Unadjusted, Unadjusted,
            Backward, False)

        bond = FixedRateBond(settlement_days, face_amount,
                             fixed_bond_schedule, [coupon_rate],
                             ActualActual(Bond), Unadjusted, redemption,
                             issue_date)

        zspd = bf.zSpread(bond, 100.0, flat_term_structure, Actual365Fixed(),
                          Compounded, Semiannual, settlement_date, 1e-6, 100,
                          0.5)

        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)
            sq_rate = SimpleQuote(rate / 100)
            helper = DepositRateHelper(sq_rate, tenor, settlement_days,
                                       calendar, ModifiedFollowing,
                                       end_of_month, Actual360())
            simple_quotes.append(sq_rate)
            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:
            sq_rate = SimpleQuote(rate / 100)
            helper = SwapRateHelper.from_tenor(sq_rate, Period(m, Years),
                                               calendar, Annual, Unadjusted,
                                               Thirty360(), liborIndex, spread,
                                               fwdStart)
            simple_quotes.append(sq_rate)
            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)

        discounting_term_structure = YieldTermStructure()
        discounting_term_structure.link_to(ts)
        pricing_engine = DiscountingBondEngine(discounting_term_structure)
        bond.set_pricing_engine(pricing_engine)

        self.assertAlmostEqual(bond.npv, 100.83702940160767)

        ba = bucket_analysis([simple_quotes], [bond], [1], 0.0001, 1)

        self.assertTrue(2, ba)
        self.assertTrue(type(tuple), ba)
        self.assertEqual(len(simple_quotes), len(ba[0][0]))
        self.assertEqual(0, ba[0][0][8])