Пример #1
0
    def __init__(self,
                 start_date,
                 end_date,
                 coupon_spec,
                 first_coupon_date=None,
                 penultimate_coupon_date=None,
                 dtype=None,
                 name=None):
        """Initialize a batch of floating cashflow streams.

    Args:
      start_date: A rank 1 `DateTensor` specifying the starting dates of the
        accrual of the first coupon of the cashflow stream. The shape of the
        input correspond to the numbercof streams being created.
      end_date: A rank 1 `DateTensor` specifying the end dates for accrual of
        the last coupon in each cashflow stream. The shape of the input should
        be the same as that of `start_date`.
      coupon_spec: A list of `FloatCouponSpecs` specifying the details of the
        coupon payment for the cashflow stream. The length of the list should
        be the same as the number of streams being created. Each coupon within
        the list must have the same daycount_convention and businessday_rule.
      first_coupon_date: An optional rank 1 `DateTensor` specifying the payment
        dates of the first coupon of the cashflow stream. Use this input for
        cashflows with irregular first coupon.
        Default value: None which implies regular first coupon.
      penultimate_coupon_date: An optional rank 1 `DateTensor` specifying the
        payment date of the penultimate (next to last) coupon of the cashflow
        stream. Use this input for cashflows with irregular last coupon.
        Default value: None which implies regular last coupon.
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the FloatingCashflowStream object or created by the
        object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'floating_cashflow_stream'.
    """

        super(FloatingCashflowStream, self).__init__()
        self._name = name or 'floating_cashflow_stream'

        with tf.name_scope(self._name):
            self._start_date = dates.convert_to_date_tensor(start_date)
            self._end_date = dates.convert_to_date_tensor(end_date)
            self._batch_size = self._start_date.shape[0]
            if first_coupon_date is None:
                self._first_coupon_date = None
            else:
                self._first_coupon_date = dates.convert_to_date_tensor(
                    first_coupon_date)

            if penultimate_coupon_date is None:
                self._penultimate_coupon_date = None
            else:
                self._penultimate_coupon_date = dates.convert_to_date_tensor(
                    penultimate_coupon_date)

            self._dtype = dtype

            self._setup(coupon_spec)
Пример #2
0
    def __init__(self,
                 settlement_date,
                 maturity_date,
                 coupon_spec,
                 start_date=None,
                 first_coupon_date=None,
                 penultimate_coupon_date=None,
                 holiday_calendar=None,
                 dtype=None,
                 name=None):
        """Initialize a batch of fixed coupon bonds.

    Args:
      settlement_date: A rank 1 `DateTensor` specifying the settlement date of
        the bonds.
      maturity_date: A rank 1 `DateTensor` specifying the maturity dates of the
        bonds. The shape of the input should be the same as that of
        `settlement_date`.
      coupon_spec: A list of `FixedCouponSpecs` specifying the coupon payments.
        The length of the list should be the same as the number of bonds
        being created.
      start_date: An optional `DateTensor` specifying the dates when the
        interest starts to accrue for the coupons. The input can be used to
        specify a forward start date for the coupons. The shape of the input
        correspond to the numbercof instruments being created.
        Default value: None in which case the coupons start to accrue from the
        `settlement_date`.
      first_coupon_date: An optional rank 1 `DateTensor` specifying the dates
        when first coupon will be paid for bonds with irregular first coupon.
      penultimate_coupon_date: An optional rank 1 `DateTensor` specifying the
        dates when the penultimate coupon (or last regular coupon) will be paid
        for bonds with irregular last coupon.
      holiday_calendar: An instance of `dates.HolidayCalendar` to specify
        weekends and holidays.
        Default value: None in which case a holiday calendar would be created
        with Saturday and Sunday being the holidays.
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the bond object or created by the bond object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'bond'.
    """
        self._name = name or 'bond'

        if holiday_calendar is None:
            holiday_calendar = dates.HolidayCalendar2(
                weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY)

        with tf.name_scope(self._name):
            self._dtype = dtype
            self._settlement_date = dates.convert_to_date_tensor(
                settlement_date)
            self._maturity_date = dates.convert_to_date_tensor(maturity_date)
            self._holiday_calendar = holiday_calendar
            self._setup(coupon_spec, start_date, first_coupon_date,
                        penultimate_coupon_date)
Пример #3
0
    def __init__(self,
                 start_date,
                 maturity_date,
                 pay_leg,
                 receive_leg,
                 holiday_calendar=None,
                 dtype=None,
                 name=None):
        """Initialize a batch of IRS contracts.

    Args:
      start_date: A rank 1 `DateTensor` specifying the dates for the inception
        (start of the accrual) of the swap contracts. The shape of the input
        correspond to the number of instruments being created.
      maturity_date: A rank 1 `DateTensor` specifying the maturity dates for
        each contract. The shape of the input should be the same as that of
        `start_date`.
      pay_leg: A scalar or a list of either `FixedCouponSpecs` or
        `FloatCouponSpecs` specifying the coupon payments for the payment leg
        of the swap. If specified as a list then the length of the list should
        be the same as the number of instruments being created. If specified as
        a scalar, then the elements of the namedtuple must be of the same shape
        as (or compatible to) the shape of `start_date`.
      receive_leg: A scalar or a list of either `FixedCouponSpecs` or
        `FloatCouponSpecs` specifying the coupon payments for the receiving leg
        of the swap. If specified as a list then the length of the list should
        be the same as the number of instruments being created. If specified as
        a scalar, then the elements of the namedtuple must be of the same shape
        as (or compatible with) the shape of `start_date`.
      holiday_calendar: An instance of `dates.HolidayCalendar` to specify
        weekends and holidays.
        Default value: None in which case a holiday calendar would be created
        with Saturday and Sunday being the holidays.
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the IRS object or created by the IRS object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'interest_rate_swap'.
    """
        self._name = name or 'interest_rate_swap'

        if holiday_calendar is None:
            holiday_calendar = dates.HolidayCalendar2(
                weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY)

        with tf.name_scope(self._name):
            self._dtype = dtype
            self._start_date = dates.convert_to_date_tensor(start_date)
            self._maturity_date = dates.convert_to_date_tensor(maturity_date)
            self._holiday_calendar = holiday_calendar
            self._floating_leg = None
            self._fixed_leg = None
            self._pay_leg = self._setup_leg(pay_leg)
            self._receive_leg = self._setup_leg(receive_leg)
            self._is_payer = isinstance(self._pay_leg, cs.FixedCashflowStream)
Пример #4
0
  def test_convert_to_date_tensor_ordinals(self):
    inputs = [1, 2, 3, 4, 5]
    inputs2 = tf.constant(inputs)
    date_tensor = dateslib.convert_to_date_tensor(inputs)
    date_tensor2 = dateslib.convert_to_date_tensor(inputs2)
    self.assert_date_tensor_equals(date_tensor, [1, 1, 1, 1, 1],
                                   [1, 1, 1, 1, 1], [1, 2, 3, 4, 5], inputs)

    self.assert_date_tensor_equals(date_tensor2, [1, 1, 1, 1, 1],
                                   [1, 1, 1, 1, 1], [1, 2, 3, 4, 5], inputs)
Пример #5
0
    def price(self,
              valuation_date,
              market,
              model=None,
              pricing_context=None,
              name=None):
        """Returns the present value of the instrument on the valuation date.

    Args:
      valuation_date: A scalar `DateTensor` specifying the date on which
        valuation is being desired.
      market: A namedtuple of type `InterestRateMarket` which contains the
        necessary information for pricing the interest rate swap.
      model: Reserved for future use.
      pricing_context: Additional context relevant for pricing.
      name: Python str. The name to give to the ops created by this function.
        Default value: `None` which maps to 'price'.

    Returns:
      A Rank 1 `Tensor` of real type containing the modeled price of each IRS
      contract based on the input market data.
    """

        name = name or (self._name + '_price')
        with tf.name_scope(name):
            valuation_date = dates.convert_to_date_tensor(valuation_date)
            pay_cf = self._pay_leg.price(valuation_date, market, model,
                                         pricing_context)
            receive_cf = self._receive_leg.price(valuation_date, market, model,
                                                 pricing_context)
            return receive_cf - pay_cf
Пример #6
0
    def __init__(self, swap, expiry_date=None, dtype=None, name=None):
        """Initialize a batch of European swaptions.

    Args:
      swap: An instance of `InterestRateSwap` specifying the interest rate
        swaps underlying the swaptions. The batch size of the swaptions being
        created would be the same as the batch size of the `swap`.
      expiry_date: An optional rank 1 `DateTensor` specifying the expiry dates
        for each swaption. The shape of the input should be the same as the
        batch size of the `swap` input.
        Default value: None in which case the option expity date is the same as
        the start date of each underlying swap.
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the Swaption object or created by the Swaption
        object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'swaption'.
    """
        self._name = name or 'swaption'

        with tf.name_scope(self._name):
            self._dtype = dtype
            self._expiry_date = dates.convert_to_date_tensor(expiry_date)
            self._swap = swap
Пример #7
0
    def price(self, valuation_date, market, model=None):
        """Returns the present value of the instrument on the valuation date.

    Args:
      valuation_date: A scalar `DateTensor` specifying the date on which
        valuation is being desired.
      market: A namedtuple of type `InterestRateMarket` which contains the
        necessary information for pricing the FRA instrument.
      model: Reserved for future use.

    Returns:
      A scalar `Tensor` of real type containing the modeled price of the FRA
      based on the input market data.
    """

        del model
        valuation_date = dates.convert_to_date_tensor(valuation_date)
        settlement_t = elapsed_time(valuation_date, self._settlement_date,
                                    self._dtype)
        accrual_start_t = elapsed_time(valuation_date,
                                       self._accrual_start_date, self._dtype)
        accrual_end_t = elapsed_time(valuation_date, self._accrual_end_date,
                                     self._dtype)

        reference_curve = market.reference_curve
        discount_curve = market.discount_curve

        fwd_rate = reference_curve.get_forward_rate(accrual_start_t,
                                                    accrual_end_t,
                                                    self._daycount_fraction)
        discount_at_settlement = discount_curve.get_discount(settlement_t)

        return discount_at_settlement * self._notional * (
            fwd_rate - self._fixed_rate) * self._daycount_fraction / (
                1. + self._daycount_fraction * fwd_rate)
Пример #8
0
    def par_rate(self, valuation_date, market, model=None):
        """Returns the par swap rate for the swap."""

        valuation_date = dates.convert_to_date_tensor(valuation_date)
        swap_annuity = self._annuity(valuation_date, market, model, False)
        float_pv = self._floating_leg.price(valuation_date, market, model)

        return float_pv / swap_annuity
Пример #9
0
 def test_convert_to_date_tensor_tensor_tuples(self):
   inputs = [
       tf.constant([2018, 2042, 1947]),
       tf.constant([5, 11, 8]),
       tf.constant([4, 22, 15])
   ]
   date_tensor = dateslib.convert_to_date_tensor(inputs)
   y, m, d = [2018, 2042, 1947], [5, 11, 8], [4, 22, 15]
   self.assert_date_tensor_equals(date_tensor, y, m, d, None)
Пример #10
0
 def test_convert_to_date_tensor_datetimes(self):
   inputs = [
       datetime.date(2018, 5, 4),
       datetime.date(2042, 11, 22),
       datetime.date(1947, 8, 15)
   ]
   date_tensor = dateslib.convert_to_date_tensor(inputs)
   y, m, d = [2018, 2042, 1947], [5, 11, 8], [4, 22, 15]
   self.assert_date_tensor_equals(date_tensor, y, m, d, None)
Пример #11
0
 def test_providing_holidays(self, holidays, convert_to_date_tensor=False):
   if convert_to_date_tensor:
     holidays = dates.convert_to_date_tensor(holidays)
   cal = self.impl(
       weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY, holidays=holidays)
   date_tensor = dates.from_tuples([(2020, 1, 1), (2020, 5, 1), (2020, 12, 25),
                                    (2021, 3, 8), (2021, 1, 1)])
   self.assertAllEqual([False, True, False, True, False],
                       cal.is_business_day(date_tensor))
Пример #12
0
 def test_convert_to_date_tensor_npdatetime(self):
   inputs = np.array([
       datetime.date(2018, 5, 4),
       datetime.date(2042, 11, 22),
       datetime.date(1947, 8, 15)
   ],
                     dtype='datetime64')
   date_tensor = dateslib.convert_to_date_tensor(inputs)
   y, m, d = [2018, 2042, 1947], [5, 11, 8], [4, 22, 15]
   self.assert_date_tensor_equals(date_tensor, y, m, d, None)
Пример #13
0
def ratecurve_from_discounting_function(discount_fn, dtype=None):
    """Returns `RateCurve` object using the supplied function for discounting.

  Args:
    discount_fn: A python callable which takes a `DateTensor` as an input and
      returns the corresponding discount factor as an output.
    dtype: `tf.Dtype`. Optional input specifying the dtype of the real tensors
      and ops.

  Returns:
    An object of class `RateCurveFromDiscountingFunction` which uses the
    supplied function for discounting.
  """

    dtype = dtype or tf.constant(0.0).dtype
    pseudo_maturity_dates = dates.convert_to_date_tensor([(2020, 1, 1)])
    pseudo_rates = tf.convert_to_tensor([0.0], dtype=dtype)
    pseudo_valuation_date = dates.convert_to_date_tensor((2020, 1, 1))

    return RateCurveFromDiscountingFunction(pseudo_maturity_dates,
                                            pseudo_rates,
                                            pseudo_valuation_date, discount_fn,
                                            dtype)
Пример #14
0
    def get_forward_rate(self,
                         start_date,
                         maturity_date,
                         daycount_fraction=None):
        """Returns the simply accrued forward rate between [start_dt, maturity_dt].

    Args:
      start_date: A `DateTensor` specifying the start of the accrual period
        for the forward rate.
      maturity_date: A `DateTensor` specifying the end of the accrual period
        for the forward rate. The shape of `maturity_date` must be the same
        as the shape of the `DateTensor` `start_date`.
      daycount_fraction: An optional `Tensor` of real dtype specifying the
        time between `start_date` and `maturity_date` in years computed using
        the forward rate's day count basis. The shape of the input should be
        the same as that of `start_date` and `maturity_date`.
        Default value: `None`, in which case the daycount fraction is computed
        using `ACTUAL_365` convention.

    Returns:
      A real tensor of same shape as the inputs containing the simply compounded
      forward rate.
    """
        start_date = dates.convert_to_date_tensor(start_date)
        maturity_date = dates.convert_to_date_tensor(maturity_date)
        if daycount_fraction is None:
            daycount_fraction = dates.daycounts.actual_365_fixed(
                start_date=start_date,
                end_date=maturity_date,
                dtype=self._dtype)
        else:
            daycount_fraction = tf.convert_to_tensor(daycount_fraction,
                                                     self._dtype)
        dfstart = self.get_discount_factor(start_date)
        dfmaturity = self.get_discount_factor(maturity_date)
        return (dfstart / dfmaturity - 1.) / daycount_fraction
Пример #15
0
    def __init__(self,
                 start_date,
                 end_date,
                 coupon_spec,
                 dtype=None,
                 name=None):
        """Initialize a batch of fixed cashflow streams.

    Args:
      start_date: A rank 1 `DateTensor` specifying the starting dates of the
        accrual of the first coupon of the cashflow stream. The shape of the
        input correspond to the numbercof streams being created.
      end_date: A rank 1 `DateTensor` specifying the end dates for accrual of
        the last coupon in each cashflow stream. The shape of the input should
        be the same as that of `start_date`.
      coupon_spec: A list of `FixedCouponSpecs` specifying the details of the
        coupon payment for the cashflow stream. The length of the list should
        be the same as the number of streams being created. Each coupon within
        the list must have the same daycount_convention and businessday_rule.
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the FixedCashflowStream object or created by the
        object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'fixed_cashflow_stream'.
    """

        self._name = name or 'fixed_cashflow_stream'

        with tf.name_scope(self._name):
            self._start_date = dates.convert_to_date_tensor(start_date)
            self._end_date = dates.convert_to_date_tensor(end_date)
            self._batch_size = self._start_date.shape[0]
            self._dtype = dtype
            self._setup(coupon_spec)
Пример #16
0
    def price(self, valuation_date, market, model=None):
        """Returns the present value of the instrument on the valuation date.

    Args:
      valuation_date: A scalar `DateTensor` specifying the date on which
        valuation is being desired.
      market: A namedtuple of type `InterestRateMarket` which contains the
        necessary information for pricing the interest rate swap.
      model: Reserved for future use.

    Returns:
      A Rank 1 `Tensor` of real type containing the modeled price of each IRS
      contract based on the input market data.
    """

        valuation_date = dates.convert_to_date_tensor(valuation_date)
        pay_cf = self._pay_leg.price(valuation_date, market, model)
        receive_cf = self._receive_leg.price(valuation_date, market, model)
        return receive_cf - pay_cf
Пример #17
0
  def price(self, valuation_date, market, model=None, pricing_context=None,
            name=None):
    """Returns the present value of the Cap/Floor on the valuation date.

    Args:
      valuation_date: A scalar `DateTensor` specifying the date on which
        valuation is being desired.
      market: A namedtuple of type `InterestRateMarket` which contains the
        necessary information for pricing the Cap/Floor.
      model: An optional input of type `InterestRateModelType` to specify which
        model to use for pricing.
        Default value: `None` in which case `LOGNORMAL_RATE` model is used.
      pricing_context: An optional input to provide additional parameters (such
        as model parameters) relevant for pricing.
      name: Python str. The name to give to the ops created by this function.
        Default value: `None` which maps to `"price"`.

    Returns:
      A Rank 1 `Tensor` of real type containing the modeled price of each cap
      (or floor) based on the input market data.

    Raises:
      ValueError: If an unsupported model is supplied to the function.
    """

    model = model or rc.InterestRateModelType.LOGNORMAL_RATE
    name = name or (self._name + '_price')
    with tf.name_scope(name):
      valuation_date = dates.convert_to_date_tensor(valuation_date)
      if model == rc.InterestRateModelType.LOGNORMAL_RATE:
        caplet_prices = self._price_lognormal_rate(valuation_date, market,
                                                   pricing_context)
      else:
        raise ValueError(f'Unsupported model {model}.')

      return tf.math.segment_sum(caplet_prices, self._contract_index)
Пример #18
0
    def __init__(self,
                 contract_start_date,
                 contract_end_date,
                 daycount_convention=None,
                 averaging_type=None,
                 contract_unit=1.,
                 holiday_calendar=None,
                 dtype=None,
                 name=None):
        """Initialize the Overnight index futures object.

    Args:
      contract_start_date: A Rank 1 `DateTensor` specifying the start dates of
        the reference period (or delivery period) of each futures contract. The
        published overnight index during the reference period determines the
        final settlement price of the futures contract.
      contract_end_date: A Rank 1 `DateTensor` specifying the ending dates of
        the reference period (or delivery period) of each futures contract.
      daycount_convention: An optional scalar `DayCountConvention` corresponding
        to the day count convention for the underlying rate for each contract.
        Default value: None in which case each the day count convention equal to
        DayCountConvention.ACTUAL_360 is used.
      averaging_type: An optional `AverageType` corresponding to how the
        final settlement rate is computed from daily rates.
        Default value: None, in which case `AverageType.COMPOUNDING` is used.
      contract_unit: An optional scalar or Rank 1 `Tensor` of real dtype
        specifying the notional amount for the contract. If the notional is
        entered as a scalar, it is assumed that all of the contracts have a
        notional equal to the input value.
        Default value: 1.0
      holiday_calendar: An instance of `dates.HolidayCalenday` to specify
        weekends and holidays.
        Default value: None in which case a holiday calendar would be created
        with Saturday and Sunday being the holidays.
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the EurodollarFuture object or created by the
        EurodollarFuture object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'eurodollar_future'.
    """
        self._name = name or 'overnight_rate_futures'

        with tf.compat.v2.name_scope(self._name):
            self._contract_unit = tf.convert_to_tensor(contract_unit,
                                                       dtype=dtype)
            self._dtype = dtype if dtype else self._contract_unit.dtype
            self._start_date = dates.convert_to_date_tensor(
                contract_start_date)
            self._end_date = dates.convert_to_date_tensor(contract_end_date)
            self._batch_size = self._start_date.shape[0]

            if daycount_convention is None:
                daycount_convention = rc.DayCountConvention.ACTUAL_360

            if averaging_type is None:
                averaging_type = rc.AverageType.COMPOUNDING

            if holiday_calendar is None:
                holiday_calendar = dates.HolidayCalendar2(
                    weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY)

            self._daycount_convention = daycount_convention
            self._averaging_type = averaging_type
            self._holiday_calendar = holiday_calendar
            self._rate_tenor = dates.periods.PeriodTensor(
                1, dates.PeriodType.DAY)

            self._setup()
Пример #19
0
  def __init__(self,
               start_date,
               maturity_date,
               reset_frequency,
               strike,
               daycount_convention=None,
               notional=None,
               is_cap=None,
               dtype=None,
               name=None):
    """Initializes a batch of Interest rate Caps (or Floors).

    Args:
      start_date: A scalar `InterestRateSwap` specifying the interest rate swaps
        underlying the swaptions. The batch size of the swaptions being created
        would be the same as the bacth size of the `swap`. For receiver
        swaptions the receive_leg of the underlying swaps should be
      maturity_date: A rank 1 `DateTensor` specifying the expiry dates
        for each swaption. The shape of the input should be the same as the
        batch size of the `swap` input.
        Default value: None in which case the option expity date is the same as
        the start date of each underlying swap.
      reset_frequency: A rank 1 `PeriodTensor` specifying the frequency of
        caplet resets and caplet payments.
      strike: A scalar `Tensor` of real dtype specifying the strike rate against
        which each caplet within the cap are exercised. The shape should be
        compatible to the shape of `start_date`
      daycount_convention: An optional `DayCountConvention` associated with the
        underlying rate for the cap. Daycount is assumed to be the same for all
        contracts in a given batch.
        Default value: None in which case the daycount convention will default
        to DayCountConvention.ACTUAL_360 for all contracts.
      notional: An optional `Tensor` of real dtype specifying the notional
        amount for the cap.
        Default value: None in which case the notional is set to 1.
      is_cap: An optional boolean `Tensor` of a shape compatible with
        `start_date`. Indicates whether to compute the price of a Cap (if True)
        or a Floor (if False).
        Default value: None, it is assumed that every element is a Cap.
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the Swaption object or created by the Swaption
        object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'cap_and_floor'.
    """
    self._name = name or 'cap_and_floor'

    with tf.name_scope(self._name):
      self._dtype = dtype
      self._start_date = dates.convert_to_date_tensor(start_date)
      self._maturity_date = dates.convert_to_date_tensor(maturity_date)
      if daycount_convention is None:
        daycount_convention = rc.DayCountConvention.ACTUAL_360
      self._daycount_convention = daycount_convention
      self._strike = tf.convert_to_tensor(strike, dtype=self._dtype)
      self._reset_frequency = reset_frequency
      notional = notional or 1.0
      self._notional = tf.convert_to_tensor(notional, dtype=self._dtype)
      self._batch_size = self._start_date.shape.as_list()[0]
      if is_cap is None:
        is_cap = True
      self._is_cap = tf.broadcast_to(
          tf.convert_to_tensor(is_cap, dtype=tf.bool), self._start_date.shape)
      self._setup_tensors()
Пример #20
0
    def price(self,
              valuation_date,
              market,
              model=None,
              pricing_context=None,
              name=None):
        """Returns the present value of the stream on the valuation date.

    Args:
      valuation_date: A scalar `DateTensor` specifying the date on which
        valuation is being desired.
      market: A namedtuple of type `InterestRateMarket` which contains the
        necessary information for pricing the cashflow stream.
      model: An optional input of type `InterestRateModelType` to specify which
        model to use for pricing.
        Default value: `None` in which case `NORMAL_RATE` model is used.
      pricing_context: An optional input to provide additional parameters (such
        as model parameters) relevant for pricing.
      name: Python str. The name to give to the ops created by this function.
        Default value: `None` which maps to 'price'.

    Returns:
      A Rank 1 `Tensor` of real type containing the modeled price of each stream
      contract based on the input market data.
    """

        name = name or (self._name + '_price')
        with tf.name_scope(name):
            valuation_date = dates.convert_to_date_tensor(valuation_date)
            discount_curve = market.discount_curve
            past_fixing = rc.get_rate_index(market,
                                            self._start_date,
                                            rc.RateIndexType.SWAP,
                                            dtype=self._dtype)
            past_fixing = tf.repeat(
                tf.convert_to_tensor(past_fixing, dtype=self._dtype),
                self._num_cashflows)

            discount_factors = discount_curve.get_discount_factor(
                self._payment_dates)
            cms_rates = self._swap.par_rate(valuation_date, market, model)

            cms_rates = tf.where(self._daycount_fractions > 0., cms_rates,
                                 tf.zeros_like(cms_rates))
            # If coupon end date is before the valuation date, the payment is in the
            # past. If valuation date is between coupon start date and coupon end
            # date, then the rate has been fixed but not paid. Otherwise the rate is
            # not fixed and should be read from the curve.
            cms_rates = tf.where(
                self._coupon_end_dates < valuation_date,
                tf.constant(0., dtype=self._dtype),
                tf.where(self._coupon_start_dates < valuation_date,
                         past_fixing, cms_rates))
            cms_rates = self._adjust_convexity(valuation_date, market, model,
                                               pricing_context, cms_rates,
                                               discount_factors)

            coupon_rate = self._coupon_multiplier * (cms_rates +
                                                     self._coupon_basis)

            cashflow_pvs = self._notional * (self._daycount_fractions *
                                             coupon_rate * discount_factors)
            return tf.math.segment_sum(cashflow_pvs, self._contract_index)
    def __init__(self,
                 settlement_date,
                 fixing_date,
                 fixed_rate,
                 notional=1.,
                 daycount_basis=None,
                 rate_term=None,
                 maturity_date=None,
                 dtype=None,
                 name=None):
        """Initialize the batch of FRA contracts.

    Args:
      settlement_date: A rank 1 `DateTensor` specifying the dates on which
        cashflows are settled. The shape of the input correspond to the number
        of instruments being created.
      fixing_date: A rank 1 `DateTensor` specifying the dates on which forward
        rate will be fixed. The shape of the inout should be the same as that of
        `settlement_date`.
      fixed_rate: A rank 1 `Tensor` of real dtype specifying the fixed rate
        payment agreed at the initiation of the individual contracts. The shape
        should be the same as that of `settlement_date`.
      notional: A scalar or a rank 1 `Tensor` of real dtype specifying the
        notional amount for each contract. When the notional is specified as a
        scalar, it is assumed that all contracts have the same notional. If the
        notional is in the form of a `Tensor`, then the shape must be the same
        as `settlement_date`.
        Default value: 1.0
      daycount_basis: An optional list of `DayCountBasis` to determine how
        cashflows are accrued for each contract. The length of the list must be
        the same as the number of FRAs being created.
        Default value: None in which case the daycount basis will default to
        DayCountBasis.ACTUAL_360 for all contracts.
      rate_term: An optional rank 1 `PeriodTensor` specifying the term (or the
        tenor) of the Libor rate that determines the floating cashflow. The
        shape of the input should be the same as `settlement_date`.
        Default value: `None` in which case the the forward rate is determined
        for the period [settlement_date, maturity_date].
      maturity_date: An optional rank 1 `DateTensor` specifying the maturity of
        the underlying forward rate for each contract. This input is only used
        if the input `rate_term` is `None`.
        Default value: `None`
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the FRA object or created by the FRA object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'forward_rate_agreement'.

    Raises:
      ValueError: If both `maturity_date` and `rate_term` are unspecified.
    """
        self._name = name or 'forward_rate_agreement'

        if rate_term is None and maturity_date is None:
            raise ValueError(
                'Error creating FRA. Either rate_term or maturity_date is required.'
            )

        with tf.name_scope(self._name):
            self._dtype = dtype
            self._notional = tf.convert_to_tensor(notional, dtype=self._dtype)
            self._fixing_date = dates.convert_to_date_tensor(fixing_date)
            self._settlement_date = dates.convert_to_date_tensor(
                settlement_date)
            self._accrual_start_date = dates.convert_to_date_tensor(
                settlement_date)
            if rate_term is None:
                self._accrual_end_date = dates.convert_to_date_tensor(
                    maturity_date)
            else:
                self._accrual_end_date = self._accrual_start_date + rate_term

            # TODO (b/150216422): Fix tf.repeat to work with python enums
            if daycount_basis is None:
                daycount_basis = np.repeat(rc.DayCountBasis.ACTUAL_360,
                                           settlement_date.shape)

            self._fixed_rate = tf.convert_to_tensor(fixed_rate,
                                                    dtype=self._dtype,
                                                    name='fixed_rate')
            self._daycount_basis = daycount_basis
            self._daycount_fraction = rc.get_daycount_fraction(
                self._accrual_start_date, self._accrual_end_date,
                self._daycount_basis, self._dtype)
Пример #22
0
 def test_convert_to_date_tensor_tuples(self):
   inputs = [(2018, 5, 4), (2042, 11, 22), (1947, 8, 15)]
   date_tensor = dateslib.convert_to_date_tensor(inputs)
   y, m, d = zip(*inputs)
   self.assert_date_tensor_equals(date_tensor, y, m, d, None)
Пример #23
0
  def get_discount(self, interpolation_dates):
    """Returns discount factors at `interpolation_dates`."""

    idates = dates.convert_to_date_tensor(interpolation_dates)
    times = self._get_time(idates)
    return tf.math.exp(-self.get_rates(idates) * times)
Пример #24
0
  def get_rates(self, interpolation_dates):
    """Returns interpolated rates at `interpolation_dates`."""

    idates = dates.convert_to_date_tensor(interpolation_dates)
    times = self._get_time(idates)
    return self._interpolator(times, self._times, self._rates)
Пример #25
0
 def annuity(self, valuation_date, market, model=None):
     """Returns the annuity of each swap on the vauation date."""
     valuation_date = dates.convert_to_date_tensor(valuation_date)
     return self._annuity(valuation_date, market, model, True)
Пример #26
0
    def __init__(self,
                 expiry_date,
                 contract_notional=1.,
                 daycount_basis=None,
                 rate_term=None,
                 maturity_date=None,
                 dtype=None,
                 name=None):
        """Initialize the Eurodollar futures object.

    Args:
      expiry_date: A Rank 1 `DateTensor` specifying the dates on which the
        futures contracts expire.
      contract_notional: An optional scalar or Rank 1 `Tensor` of real dtype
        specifying the unit (or size) for the contract. For example for
        eurodollar futures traded on CME, the contract notional is $2500. If
        `contract_notional` is entered as a scalar, it is assumed that the input
        is the same for all of the contracts.
        Default value: 1.0
      daycount_basis: An optional scalar `DayCountBasis` corresponding to the
        day count basis for the underlying rate for each contract. Daycount is
        assumed to be the same for all contracts in a given batch.
        Default value: None in which case each the day count basis of
        DayCountBasis.ACTUAL_360 is used for each contract.
      rate_term: An optional Rank 1 `PeriodTensor` specifying the term (or
        tenor) of the rate that determines the settlement of each contract.
        Default value: `None` in which case the the rate is assumed to be for
        the period [expiry_date, maturity_date].
      maturity_date: An optional Rank 1 `DateTensor` specifying the maturity of
        the underlying forward rate for each contract. This input should be
        specified if the input `rate_term` is `None`. If both `maturity_date`
        and `rate_term` are specified, an error is raised.
        Default value: `None`
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the EurodollarFuture object or created by the
        EurodollarFuture object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'eurodollar_future'.

    Raises:
      ValueError: If both `maturity_date` and `rate_term` are unspecified or
      if both `maturity_date` and `rate_term` are specified.
    """
        self._name = name or 'eurodollar_futures'

        if (rate_term is None) == (maturity_date is None):
            msg = ('Error creating the EurodollarFutures contract. '
                   'Either rate_term or maturity_date is required.')
            raise ValueError(msg)

        if rate_term is not None and maturity_date is not None:
            msg = ('Error creating the EurodollarFutures contract.'
                   ' Both rate_term or maturity_date are specified.')
            raise ValueError(msg)

        with tf.name_scope(self._name):
            self._dtype = dtype
            self._contract_notional = tf.convert_to_tensor(contract_notional,
                                                           dtype=self._dtype)
            self._expiry_date = dates.convert_to_date_tensor(expiry_date)
            self._accrual_start_date = self._expiry_date
            if rate_term is None:
                self._accrual_end_date = dates.convert_to_date_tensor(
                    maturity_date)
            else:
                # TODO (b/150291959): Add businessday and holiday conventions
                self._accrual_end_date = self._accrual_start_date + rate_term

            if daycount_basis is None:
                daycount_basis = rc.DayCountBasis.ACTUAL_360
            daycount_basis = [daycount_basis]

            self._daycount_basis = daycount_basis
            self._daycount_fraction = rc.get_daycount_fraction(
                self._accrual_start_date, self._accrual_end_date,
                self._daycount_basis, self._dtype)
Пример #27
0
  def __init__(self,
               maturity_dates,
               rates,
               valuation_date,
               compounding=None,
               interpolator=None,
               dtype=None,
               name=None):
    """Initializes the interest rate curve.

    Args:
      maturity_dates: A `DateTensor` containing the maturity dates on which the
        curve is specified.
      rates: A `Tensor` of real dtype specifying the rates (or yields)
        corresponding to the input maturities. The shape of this input should
        match the shape of `maturity_dates`.
      valuation_date: A scalar `DateTensor` specifying the valuation (or
        settlement) date for the curve.
      compounding: Optional scalar `Tensor` of dtype int32 specifying the
        componding frequency of the input rates. Use compounding=0 for
        continuously compounded rates. If compounding is different than 0, then
        rates are converted to continuously componded rates to perform
        interpolation.
        Default value: If omitted, the default value is 0.
      interpolator: Optional Python callable specifying the desired
        interpolation method. It should have the following interface: yi =
        interpolator(xi, x, y) `x`, `y`, 'xi', 'yi' are all `Tensors` of real
        dtype. `x` and `y` are the sample points and values (respectively) of
        the function to be interpolated. `xi` are the points at which the
        interpolation is desired and `yi` are the corresponding interpolated
        values returned by the function.
        Default value: None in which case linear interpolation is used.
      dtype: `tf.Dtype`. Optional input specifying the dtype of the `rates`
        input.
      name: Python str. The name to give to the ops created by this function.
        Default value: `None` which maps to 'rate_curve'.
    """
    self._name = name or 'rate_curve'
    with tf.compat.v1.name_scope(self._name):
      self._dtype = dtype
      if interpolator is None:
        def default_interpolator(xi, x, y):
          return linear.interpolate(xi, x, y, dtype=dtype)
        interpolator = default_interpolator

      if compounding is None:
        compounding = 0

      self._dates = dates.convert_to_date_tensor(maturity_dates)
      self._valuation_date = dates.convert_to_date_tensor(
          valuation_date)

      self._times = self._get_time(self._dates)
      self._rates = tf.convert_to_tensor(rates, dtype=self._dtype,
                                         name='curve_rates')

      if compounding > 0:
        self._rates = tf.where(
            self._times > 0.,
            tf.math.log(
                (1. + self._rates / compounding)**(compounding * self._rates)) /
            self._times, self._rates)
      self._interpolator = interpolator
Пример #28
0
    def __init__(self,
                 settlement_date,
                 fixing_date,
                 fixed_rate,
                 notional=1.,
                 daycount_basis=DayCountBasis.ACTUAL_360,
                 rate_term=None,
                 maturity_date=None,
                 dtype=None,
                 name=None):
        """Initialize the forward rate agreement object.

    Args:
      settlement_date: A scalar `DateTensor` specifying the date on which
        cashflows are settled.
      fixing_date: A scalar `DateTensor` specifying the date on which forward
        rate will be fixed.
      fixed_rate: A scalar `Tensor` of real dtype specifying the fixed rate
        payment agreed at the initiation of the contract.
      notional: An optional scalar of real dtype specifying the notional amount
        for the contract.
        Default value: 1.0
      daycount_basis: An optional scalar `DayCountBasis` to determine how
        cashflows are accrued.
        Default value: DayCountBasis.ACTUAL_360.
      rate_term: An optional scalar `PeriodTensor` specifying the term (or
        tenor) of the Libor rate that determines the floating cashflow.
        Default value: `None` in which case the the forward rate is determined
        for the period [settlement_date, maturity_date].
      maturity_date: An optional scalar `DateTensor` specifying the maturity of
        the underlying forward rate. This input is only used if the input
        `rate_term` is `None`.
        Default value: `None`
      dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops
        either supplied to the FRA object or created by the FRA object.
        Default value: None which maps to the default dtype inferred by
        TensorFlow.
      name: Python str. The name to give to the ops created by this class.
        Default value: `None` which maps to 'forward_rate_agreement'.

    Raises:
      ValueError: If both `maturity_date` and `rate_term` are unspecified.
    """
        self._name = name or 'forward_rate_agreement'
        with tf.compat.v1.name_scope(self._name,
                                     values=[
                                         notional, settlement_date,
                                         fixing_date, maturity_date,
                                         daycount_basis, fixed_rate, rate_term
                                     ]):
            self._dtype = dtype
            self._notional = tf.convert_to_tensor(notional, dtype=self._dtype)
            self._fixing_date = dates.convert_to_date_tensor(fixing_date)
            self._settlement_date = dates.convert_to_date_tensor(
                settlement_date)
            self._accrual_start_date = dates.convert_to_date_tensor(
                settlement_date)
            if rate_term is None:
                self._accrual_end_date = dates.convert_to_date_tensor(
                    maturity_date)
            else:
                self._accrual_end_date = self._accrual_start_date + rate_term
            self._fixed_rate = tf.convert_to_tensor(fixed_rate,
                                                    dtype=self._dtype,
                                                    name='fixed_rate')
            self._daycount_basis = daycount_basis
            self._daycount_fraction = get_daycount_fraction(
                self._accrual_start_date, self._accrual_end_date,
                self._daycount_basis, self._dtype)