Ejemplo n.º 1
0
    def test_yield(self):

        rates_data = [('Libor1M',SimpleQuote(.01)),
                  ('Libor3M', SimpleQuote(.015)),
                  ('Libor6M', SimpleQuote(.017)),
                  ('Swap1Y', SimpleQuote(.02)),
                  ('Swap2Y', SimpleQuote(.03)),
                  ('Swap3Y', SimpleQuote(.04)),
                  ('Swap5Y', SimpleQuote(.05)),
                  ('Swap7Y', SimpleQuote(.06)),
                  ('Swap10Y', SimpleQuote(.07)),
                  ('Swap20Y', SimpleQuote(.08))]

        settlement_date = pydate_to_qldate('01-Dec-2013')
        rate_helpers = []
        for label, rate in rates_data:
            h = make_rate_helper(label, rate, settlement_date)
            rate_helpers.append(h)

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

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

        zc = zero_rate(ts, (200, 300), settlement_date)
        # not a real test - just verify execution
        self.assertAlmostEqual(zc[1][0], 0.0189, 2)
Ejemplo n.º 2
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)
Ejemplo n.º 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('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
Ejemplo n.º 4
0
def example03():
    print("example 3:\n")
    todays_date = Date(13, 6, 2011)
    Settings.instance().evaluation_date = todays_date
    quotes = [0.00445, 0.00949, 0.01234, 0.01776, 0.01935, 0.02084]
    tenors = [1, 2, 3, 6, 9, 12]
    calendar = WeekendsOnly()
    deps = [
        DepositRateHelper(q, Period(t, Months), 2, calendar, ModifiedFollowing,
                          False, Actual360()) for q, t in zip(quotes, tenors)
    ]
    quotes = [
        0.01652, 0.02018, 0.02303, 0.02525, 0.0285, 0.02931, 0.03017, 0.03092,
        0.03160, 0.03231, 0.03367, 0.03419, 0.03411, 0.03411, 0.03412
    ]
    tenors = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 20, 25, 30]
    swaps = [
        SwapRateHelper.from_tenor(q, Period(t, Years), calendar, Annual,
                                  ModifiedFollowing, Thirty360(), Euribor6M(),
                                  SimpleQuote(0))
        for q, t in zip(quotes, tenors)
    ]
    yield_helpers = deps + swaps
    isda_yts = PiecewiseYieldCurve(BootstrapTrait.Discount,
                                   Interpolator.LogLinear, 0, WeekendsOnly(),
                                   yield_helpers, Actual365Fixed())

    spreads = [0.007927, 0.012239, 0.016979, 0.019271, 0.020860]
    tenors = [1, 3, 5, 7, 10]
    spread_helpers = [SpreadCdsHelper(0.007927, Period(6, Months), 1,
                                      WeekendsOnly(), Quarterly, Following, Rule.CDS2015,
                                      Actual360(), 0.4, isda_yts, True, True,
                                      Date(), Actual360(True), True, PricingModel.ISDA)] + \
    [SpreadCdsHelper(s, Period(t, Years), 1, WeekendsOnly(), Quarterly, Following, Rule.CDS2015,
                     Actual360(), 0.4, isda_yts, True, True, Date(), Actual360(True), True,
                     PricingModel.ISDA)
     for s, t in zip(spreads, tenors)]
    isda_cts = PiecewiseDefaultCurve(ProbabilityTrait.SurvivalProbability,
                                     Interpolator.LogLinear, 0, WeekendsOnly(),
                                     spread_helpers, Actual365Fixed())
    isda_pricer = IsdaCdsEngine(isda_cts, 0.4, isda_yts)
    print("Isda yield curve:")
    for h in yield_helpers:
        d = h.latest_date
        t = isda_yts.time_from_reference(d)
        print(d, t, isda_yts.zero_rate(d, Actual365Fixed()).rate)

    print()
    print("Isda credit curve:")
    for h in spread_helpers:
        d = h.latest_date
        t = isda_cts.time_from_reference(d)
        print(d, t, isda_cts.survival_probability(d))
Ejemplo n.º 5
0
def make_term_structure(rates, dt_obs):
    """
    rates is a dictionary-like structure with labels as keys
    and rates (decimal) as values.
    TODO: Make it more generic
    """

    settlement_date = pydate_to_qldate(dt_obs)
    rate_helpers = []
    for label in rates.keys():
        r = rates[label]
        h = make_rate_helper(label, r, settlement_date)
        rate_helpers.append(h)

    ts_day_counter = ActualActual(ISDA)
    tolerance = 1.0e-15
    ts = PiecewiseYieldCurve('discount', 'loglinear', settlement_date,
                             rate_helpers, ts_day_counter, tolerance)

    return ts
Ejemplo n.º 6
0
    def bootstrap_term_structure(self, 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(
            'discount', interpolator, settlement_date, self._rate_helpers,
            DayCounter.from_name(self._termstructure_daycount), tolerance)
        self._term_structure = ts
        self._discount_term_structure = YieldTermStructure(relinkable=True)
        self._discount_term_structure.link_to(ts)

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

        return ts
Ejemplo n.º 7
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('zero', '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)
Ejemplo n.º 8
0
floatingLegTenor = Period(6, Months)
floatingLegAdjustment = ModifiedFollowing
swapHelpers = [
    SwapRateHelper.from_tenor(swaps[(n, unit)], Period(n, unit), calendar,
                              fixedLegFrequency,
                              fixedLegAdjustment, fixedLegDayCounter,
                              Euribor6M()) for n, unit in swaps.keys()
]

### Curve building

ts_daycounter = ActualActual(ISDA)

# term-structure construction
helpers = depositHelpers + swapHelpers
depoSwapCurve = PiecewiseYieldCurve('discount', 'loglinear', settlementDate,
                                    helpers, ts_daycounter)

helpers = depositHelpers[:2] + futuresHelpers + swapHelpers[1:]
depoFuturesSwapCurve = PiecewiseYieldCurve('discount', 'loglinear',
                                           settlementDate, helpers,
                                           ts_daycounter)

helpers = depositHelpers[:3] + fraHelpers + swapHelpers
depoFraSwapCurve = PiecewiseYieldCurve('discount', 'loglinear', settlementDate,
                                       helpers, ts_daycounter)

# Term structures that will be used for pricing:
discountTermStructure = YieldTermStructure(relinkable=True)
forecastTermStructure = YieldTermStructure(relinkable=True)

### SWAPS TO BE PRICED
Ejemplo n.º 9
0
    def test_zero_curve(self):

        try:

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

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

            swapData = [[1, Years, 'Swap1Y', 5.31], [2, Years, 'Swap2Y', 5.06],
                        [3, Years, 'Swap3Y', 5.00], [4, Years, 'Swap4Y', 5.01],
                        [5, Years, 'Swap5Y', 5.04], [7, Years, 'Swap7Y', 5.12],
                        [10, Years, 'Swap10Y', 5.22],
                        [30, Years, 'Swap30Y', 5.44]]

            rate_helpers = []

            end_of_month = True

            for m, period, label, rate in depositData:
                tenor = Period(m, Months)
                helper = DepositRateHelper(SimpleQuote(rate / 100.0), tenor,
                                           settlement_days, calendar,
                                           ModifiedFollowing, end_of_month,
                                           Actual360())

                rate_helpers.append(helper)

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

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

            for m, period, label, rate in swapData:
                helper = SwapRateHelper.from_tenor(SimpleQuote(rate / 100.0),
                                                   Period(m, Years), calendar,
                                                   Semiannual,
                                                   ModifiedFollowing,
                                                   Thirty360(), liborIndex,
                                                   spread, fwdStart)

                rate_helpers.append(helper)

            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...
            dtMax = ts.max_date
            print('max date: %s' % dtMax)

        except RuntimeError as e:
            print('Exception (expected):\n%s' % e)

            self.assertTrue(True)

        except Exception:
            self.assertFalse()