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

        discounting_term_structure = YieldTermStructure()

        settlement_days = 3
        flat_term_structure = FlatForward(settlement_days=settlement_days,
            forward=0.044, calendar=NullCalendar(), daycounter=Actual360())

        discounting_term_structure.link_to(flat_term_structure)

        evaluation_date = Settings().evaluation_date +100
        self.assertEqual(
            flat_term_structure.discount(evaluation_date),
            discounting_term_structure.discount(evaluation_date)
        )


        another_flat_term_structure = FlatForward(settlement_days=10,
            forward=0.067, calendar=NullCalendar(), daycounter=Actual365Fixed())

        discounting_term_structure.link_to(another_flat_term_structure)

        self.assertEqual(
            another_flat_term_structure.discount(evaluation_date),
            discounting_term_structure.discount(evaluation_date)
        )

        self.assertNotEqual(
            flat_term_structure.discount(evaluation_date),
            discounting_term_structure.discount(evaluation_date)
        )
Ejemplo n.º 2
0
    def test_relinkable_structures(self):

        discounting_term_structure = YieldTermStructure(relinkable=True)

        settlement_days = 3
        flat_term_structure = FlatForward(settlement_days=settlement_days,
            forward=0.044, calendar=NullCalendar(), daycounter=Actual360())

        discounting_term_structure.link_to(flat_term_structure)

        evaluation_date = Settings().evaluation_date +100
        self.assertEqual(
            flat_term_structure.discount(evaluation_date),
            discounting_term_structure.discount(evaluation_date)
        )


        another_flat_term_structure = FlatForward(settlement_days=10,
            forward=0.067, calendar=NullCalendar(), daycounter=Actual365Fixed())

        discounting_term_structure.link_to(another_flat_term_structure)

        self.assertEqual(
            another_flat_term_structure.discount(evaluation_date),
            discounting_term_structure.discount(evaluation_date)
        )

        self.assertNotEqual(
            flat_term_structure.discount(evaluation_date),
            discounting_term_structure.discount(evaluation_date)
        )
Ejemplo n.º 3
0
class IborMarket(FixedIncomeMarket):
    def __init__(self, name, market, **kwargs):

        params = swap_params(market)
        params = params._replace(**kwargs)
        self._params = params
        self._name = name
        self._market = market

        # floating rate index
        index = IborIndex.from_name(market, **kwargs)
        self._floating_rate_index = index

        self._deposit_daycount = params.floating_leg_daycount
        self._termstructure_daycount = 'ACT/365'

        self._eval_date = None
        self._quotes = None
        self._termstructure = None

        self._discount_term_structure = None
        self._forecast_term_structure = None

        self._rate_helpers = []
        self._quotes = []

    def _set_evaluation_date(self, dt_obs):

        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
        self._eval_date = eval_date
        return eval_date

    def set_quotes(self, dt_obs, quotes):

        self._quotes.extend(quotes)
        eval_date = self._set_evaluation_date(dt_obs)

        for quote in quotes:
            # construct rate helper
            helper = make_rate_helper(self, quote, eval_date)
            self._rate_helpers.append(helper)

    def set_bonds(self, dt_obs, quotes):
        """ Supply the market with a set of bond quotes.

        The `quotes` parameter must be a list of quotes of the form
        (clean_price, coupons, tenor, issue_date, maturity). For more
        information about the format of the individual fields, see
        the documentation for :meth:`add_bond_quote`.

        """

        self._quotes.extend(quotes)
        self._set_evaluation_date(dt_obs)

        for quote in quotes:
            self.add_bond_quote(*quote)

    def add_bond_quote(self, clean_price, coupons, tenor, issue_date,
                       maturity):
        """
        Add a bond quote to the market.

        Parameters
        ----------
        clean_price : real
            Clean price of the bond.
        coupons : real or list(real)
            Interest rates paid by the bond.
        tenor : str
            Tenor of the bond.
        issue_date, maturity : Date instance
            Issue date and maturity of the bond.

        """

        if not isinstance(coupons, (list, tuple)):
            coupons = [coupons]

        helper = make_eurobond_helper(self, clean_price, coupons, tenor,
                                      issue_date, maturity)
        self._rate_helpers.append(helper)

    @property
    def calendar(self):
        return self._params.calendar

    @property
    def settlement_days(self):
        return self._params.settlement_days

    @property
    def fixed_leg_period(self):
        return self._params.fixed_leg_period

    @property
    def fixed_leg_convention(self):
        return self._params.fixed_leg_convention

    @property
    def fixed_leg_daycount(self):
        return self._params.fixed_leg_daycount

    @property
    def termstructure_daycounter(self):
        return self._termstructure_daycounter

    @property
    def reference_date(self):
        return 0

    @property
    def max_date(self):
        return 0

    def __str__(self):
        output = \
            "Ibor Market %s\n" % self._name + \
            "Number of settlement days: %d\n" % self._params.settlement_days +\
            "Fixed leg period: %s\n" % self._params.fixed_leg_period +\
            "Fixed leg convention: %s\n" % self._params.fixed_leg_convention +\
            "Fixed leg daycount: %s\n" % self._params.fixed_leg_daycount +\
            "Term structure daycount: %s\n" % self._termstructure_daycount + \
            "Floating rate index: %s\n" % self._floating_rate_index + \
            "Deposit daycount: %s\n" % self._deposit_daycount + \
            "Calendar: %s\n" % self._params.calendar

        return output

    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 discount(self, date_maturity, extrapolate=True):
        return self._discount_term_structure.discount(date_maturity)

    def create_fixed_float_swap(self, settlement_date, length, fixed_rate,
                                floating_spread, **kwargs):
        """
        Create a fixed-for-float swap given:
        - settlement date
        - length in years
        - additional arguments to modify market default parameters
        """

        _params = self._params._replace(**kwargs)

        index = IborIndex.from_name(self._market,
                                    self._forecast_term_structure, **kwargs)

        swap_type = Payer
        nominal = 100.0
        fixed_convention = \
            BusinessDayConvention.from_name(_params.fixed_leg_convention)
        floating_convention = \
            BusinessDayConvention.from_name(_params.floating_leg_convention)
        fixed_frequency = \
            Period(_params.fixed_leg_period)
        floating_frequency = Period(_params.floating_leg_period)
        fixed_daycount = DayCounter.from_name(_params.fixed_leg_daycount)
        float_daycount = DayCounter.from_name(_params.floating_leg_daycount)
        calendar = calendar_from_name(_params.calendar)

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

        fixed_schedule = Schedule.from_rule(settlement_date, maturity,
                                            fixed_frequency, calendar,
                                            fixed_convention, fixed_convention,
                                            Rule.Forward, False)

        float_schedule = Schedule.from_rule(settlement_date, maturity,
                                            floating_frequency, calendar,
                                            floating_convention,
                                            floating_convention, Rule.Forward,
                                            False)

        swap = VanillaSwap(swap_type, nominal, fixed_schedule, fixed_rate,
                           fixed_daycount, float_schedule, index,
                           floating_spread, float_daycount, fixed_convention)

        engine = DiscountingSwapEngine(self._discount_term_structure,
                                       False,
                                       settlement_date=settlement_date,
                                       npv_date=settlement_date)

        swap.set_pricing_engine(engine)

        return swap
Ejemplo n.º 4
0
    def test_default_constructor(self):

        term_structure = YieldTermStructure()

        with self.assertRaises(ValueError):
            term_structure.discount(Settings().evaluation_date)
Ejemplo n.º 5
0
    def test_default_constructor(self):

        term_structure = YieldTermStructure()

        with self.assertRaises(ValueError):
            term_structure.discount(Settings().evaluation_date)
Ejemplo n.º 6
0
class IborMarket(FixedIncomeMarket):

    def __init__(self, name, market, **kwargs):

        params = swap_params(market)
        params = params._replace(**kwargs)
        self._params = params
        self._name = name
        self._market = market

        # floating rate index
        index = IborIndex.from_name(market, **kwargs)
        self._floating_rate_index = index

        self._deposit_daycount = params.floating_leg_daycount
        self._termstructure_daycount = 'ACT/365'

        self._eval_date = None
        self._quotes = None
        self._termstructure = None

        self._discount_term_structure = None
        self._forecast_term_structure = None

        self._rate_helpers = []
        self._quotes = []

    def _set_evaluation_date(self, dt_obs):

        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
        self._eval_date = eval_date
        return eval_date

    def set_quotes(self, dt_obs, quotes):

        self._quotes.extend(quotes)
        eval_date = self._set_evaluation_date(dt_obs)

        for quote in quotes:
            # construct rate helper
            helper = make_rate_helper(self, quote, eval_date)
            self._rate_helpers.append(helper)

    def set_bonds(self, dt_obs, quotes):
        """ Supply the market with a set of bond quotes.

        The `quotes` parameter must be a list of quotes of the form
        (clean_price, coupons, tenor, issue_date, maturity). For more
        information about the format of the individual fields, see
        the documentation for :meth:`add_bond_quote`.

        """

        self._quotes.extend(quotes)
        self._set_evaluation_date(dt_obs)

        for quote in quotes:
            self.add_bond_quote(*quote)

    def add_bond_quote(self, clean_price, coupons, tenor, issue_date,
                       maturity):
        """
        Add a bond quote to the market.

        Parameters
        ----------
        clean_price : real
            Clean price of the bond.
        coupons : real or list(real)
            Interest rates paid by the bond.
        tenor : str
            Tenor of the bond.
        issue_date, maturity : Date instance
            Issue date and maturity of the bond.

        """

        if not isinstance(coupons, (list, tuple)):
            coupons = [coupons]

        helper = make_eurobond_helper(
            self, clean_price, coupons, tenor, issue_date, maturity)
        self._rate_helpers.append(helper)

    @property
    def calendar(self):
        return self._params.calendar

    @property
    def settlement_days(self):
        return self._params.settlement_days

    @property
    def fixed_rate_frequency(self):
        return self._params.fixed_rate_frequency

    @property
    def fixed_rate_convention(self):
        return self._params.fixed_instrument_convention

    @property
    def fixed_rate_daycounter(self):
        return self._params.fixed_rate_daycounter

    @property
    def termstructure_daycounter(self):
        return self._termstructure_daycounter

    @property
    def reference_date(self):
        return 0

    @property
    def max_date(self):
        return 0

    def __str__(self):
        output = \
            "Ibor Market %s\n" % self._name + \
            "Number of settlement days: %d\n" % self._params.settlement_days +\
            "Fixed rate frequency: %s\n" % self._params.fixed_rate_frequency +\
            "Fixed rate convention: %s\n" % self._params.fixed_instrument_convention +\
            "Fixed rate daycount: %s\n" % self._params.fixed_instrument_daycounter +\
            "Term structure daycount: %s\n" % self._termstructure_daycount + \
            "Floating rate index: %s\n" % self._floating_rate_index + \
            "Deposit daycount: %s\n" % self._deposit_daycount + \
            "Calendar: %s\n" % self._params.calendar

        return output

    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

    def discount(self, date_maturity, extrapolate=True):
        return self._discount_term_structure.discount(date_maturity)

    def create_fixed_float_swap(self, settlement_date, length, fixed_rate,
                                floating_spread, **kwargs):
        """
        Create a fixed-for-float swap given:
        - settlement date
        - length in years
        - additional arguments to modify market default parameters
        """

        _params = self._params._replace(**kwargs)

        index = IborIndex.from_name(self._market,
                                    self._forecast_term_structure,
                                    **kwargs)

        swap_type = Payer
        nominal = 100.0
        fixed_convention = \
            BusinessDayConvention.from_name(_params.fixed_leg_convention)
        floating_convention = \
            BusinessDayConvention.from_name(_params.floating_leg_convention)
        fixed_frequency = \
            code_to_frequency(_params.fixed_leg_period)
        floating_frequency = code_to_frequency(_params.floating_leg_period)
        fixed_daycount = DayCounter.from_name(_params.fixed_leg_daycount)
        float_daycount = DayCounter.from_name(_params.floating_leg_daycount)
        calendar = calendar_from_name(_params.calendar)

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

        fixed_schedule = Schedule(settlement_date, maturity,
                                  Period(fixed_frequency), calendar,
                                  fixed_convention, fixed_convention,
                                  Forward, False)

        float_schedule = Schedule(settlement_date, maturity,
                                  Period(floating_frequency),
                                  calendar, floating_convention,
                                  floating_convention,
                                  Forward, False)

        swap = VanillaSwap(swap_type, nominal, fixed_schedule, fixed_rate,
                           fixed_daycount, float_schedule, index,
                           floating_spread, float_daycount, fixed_convention)

        engine = DiscountingSwapEngine(self._discount_term_structure,
                                       False,
                                       settlementDate=settlement_date,
                                       npvDate=settlement_date)

        swap.set_pricing_engine(engine)

        return swap
Ejemplo n.º 7
0
class IborMarket(FixedIncomeMarket):

    def __init__(self, name, market, **kwargs):

        params = SwapData.params(market)
        params = params._replace(**kwargs)
        self._params = params
        self._name = name
        self._market = market

        # floating rate index
        index = IborIndex.from_name(market, **kwargs)
        self._floating_rate_index = index

        self._deposit_daycount = params.floating_leg_daycount
        self._termstructure_daycount = 'ACT/365'

        self._eval_date = None
        self._quotes = None
        self._termstructure = None

        self._discount_term_structure = None
        self._forecast_term_structure = None

    def __str__(self):
        return 'Fixed Income Market: %s' % self._name

    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)

    @property
    def calendar(self):
        return self._params.calendar

    @property
    def settlement_days(self):
        return self._params.settlement_days

    @property
    def fixed_rate_frequency(self):
        return self._params.fixed_rate_frequency

    @property
    def fixed_rate_convention(self):
        return self._params.fixed_instrument_convention

    @property
    def fixed_rate_daycounter(self):
        return self._params.fixed_rate_daycounter

    @property
    def termstructure_daycounter(self):
        return self._termstructure_daycounter

    @property
    def reference_date(self):
        return 0

    @property
    def max_date(self):
        return 0

    def to_str(self):
        str = \
            "Ibor Market %s\n" % self._name + \
            "Number of settlement days: %d\n" % self._params.settlement_days +\
            "Fixed rate frequency: %s\n" % self._params.fixed_rate_frequency +\
            "Fixed rate convention: %s\n" % self._params.fixed_instrument_convention +\
            "Fixed rate daycount: %s\n" % self._params.fixed_instrument_daycounter +\
            "Term structure daycount: %s\n" % self._termstructure_daycount + \
            "Floating rate index: %s\n" % self._floating_rate_index + \
            "Deposit daycount: %s\n" % self._deposit_daycount + \
            "Calendar: %s\n" % self._params.calendar

        return str

    def bootstrap_term_structure(self):
        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 = term_structure_factory(
            'discount', 'loglinear',
            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._forecasting_term_structure = YieldTermStructure(relinkable=True)
        self._forecasting_term_structure.link_to(ts)

        return 0

    def discount(self, date_maturity, extrapolate=True):
        return self._discount_term_structure.discount(date_maturity)

    def create_fixed_float_swap(self, settlement_date, length, fixed_rate,
                                floating_spread, **kwargs):
        """
        Create a fixed-for-float swap given:
        - settlement date
        - length in years
        - additional arguments to modify market default parameters
        """

        _params = self._params._replace(**kwargs)

        index = IborIndex.from_name(self._market,
                                    self._forecasting_term_structure,
                                    **kwargs)

        swap_type = Payer
        nominal = 100.0
        fixed_convention = \
            BusinessDayConvention.from_name(_params.fixed_leg_convention)
        floating_convention = \
            BusinessDayConvention.from_name(_params.floating_leg_convention)
        fixed_frequency = \
            code_to_frequency(_params.fixed_leg_period)
        floating_frequency = code_to_frequency(_params.floating_leg_period)
        fixed_daycount = DayCounter.from_name(_params.fixed_leg_daycount)
        float_daycount = DayCounter.from_name(_params.floating_leg_daycount)
        calendar = Calendar.from_name(_params.calendar)

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

        fixed_schedule = Schedule(settlement_date, maturity,
                                  Period(fixed_frequency), calendar,
                                  fixed_convention, fixed_convention,
                                  Forward, False)

        float_schedule = Schedule(settlement_date, maturity,
                                  Period(floating_frequency),
                                  calendar, floating_convention,
                                  floating_convention,
                                  Forward, False)

        swap = VanillaSwap(swap_type, nominal, fixed_schedule, fixed_rate,
                           fixed_daycount, float_schedule, index,
                           floating_spread, float_daycount, fixed_convention)

        engine = DiscountingSwapEngine(self._discount_term_structure,
                                       False,
                                       settlementDate=settlement_date,
                                       npvDate=settlement_date)

        swap.set_pricing_engine(engine)

        return swap