예제 #1
0
    def _generate_schedule(self, cpn_frequency, roll_convention):
        """Method to generate coupon dates."""
        if (self._first_coupon_date is None) and (self._penultimate_coupon_date
                                                  is None):
            cpn_dates = dates.PeriodicSchedule(
                start_date=self._start_date,
                end_date=self._end_date,
                tenor=cpn_frequency,
                roll_convention=roll_convention).dates()
        elif self._first_coupon_date is not None:
            cpn_dates = dates.PeriodicSchedule(
                start_date=self._first_coupon_date,
                end_date=self._end_date,
                tenor=cpn_frequency,
                roll_convention=roll_convention).dates()
            cpn_dates = dates.DateTensor.concat(
                [self._start_date.expand_dims(-1), cpn_dates], axis=1)
        else:
            cpn_dates = dates.PeriodicSchedule(
                start_date=self._start_date,
                end_date=self._penultimate_coupon_date,
                backward=True,
                tenor=cpn_frequency,
                roll_convention=roll_convention).dates()
            cpn_dates = dates.DateTensor.concat(
                [cpn_dates, self._end_date.expand_dims(-1)], axis=1)

        return cpn_dates
예제 #2
0
  def _generate_schedule(self, cpn_frequency, roll_convention):
    """Method to generate coupon dates.

    Args:
      cpn_frequency: A `PeriodTensor` specifying the frequency of coupon
        payments.
      roll_convention: Scalar of type `BusinessDayConvention` specifying how
        dates are rolled if they fall on holidays.

    Returns:
      A tuple containing the generated date schedule and a boolean `Tensor`
      of the same shape as the schedule specifying whether the coupons are
      regular coupons.
    """
    if (self._first_coupon_date is None) and (self._penultimate_coupon_date is
                                              None):
      cpn_dates = dates.PeriodicSchedule(
          start_date=self._start_date,
          end_date=self._end_date,
          tenor=cpn_frequency,
          roll_convention=roll_convention).dates()
      is_regular_cpn = tf.constant(
          True, dtype=bool, shape=cpn_dates[:, :-1].shape)
    elif self._first_coupon_date is not None:
      cpn_dates = dates.PeriodicSchedule(
          start_date=self._first_coupon_date,
          end_date=self._end_date,
          tenor=cpn_frequency,
          roll_convention=roll_convention).dates()
      cpn_dates = dates.DateTensor.concat(
          [self._start_date.expand_dims(-1), cpn_dates], axis=1)

      is_irregular_cpn = tf.constant(
          False, dtype=bool, shape=self._start_date.shape)
      is_regular_cpn = tf.concat([
          tf.expand_dims(is_irregular_cpn, axis=-1),
          tf.constant(True, dtype=bool, shape=cpn_dates[:, :-2].shape)
      ],
                                 axis=1)
    else:
      cpn_dates = dates.PeriodicSchedule(
          start_date=self._start_date,
          end_date=self._penultimate_coupon_date,
          backward=True,
          tenor=cpn_frequency,
          roll_convention=roll_convention).dates()
      cpn_dates = dates.DateTensor.concat(
          [cpn_dates, self._end_date.expand_dims(-1)], axis=1)

      is_irregular_cpn = tf.constant(
          False, dtype=bool, shape=self._end_date.shape)
      is_regular_cpn = tf.concat([
          tf.constant(True, dtype=bool, shape=cpn_dates[:, :-2].shape),
          tf.expand_dims(is_irregular_cpn, axis=-1)
      ],
                                 axis=1)

    return cpn_dates, is_regular_cpn
예제 #3
0
 def test_periodic_schedule(self,
                            start_dates,
                            end_dates,
                            period_quantities,
                            period_type,
                            backward,
                            expected_schedule,
                            end_of_month=False):
     start_dates = dates.from_np_datetimes(_to_np_datetimes(start_dates))
     end_dates = dates.from_np_datetimes(_to_np_datetimes(end_dates))
     tenors = dates.periods.PeriodTensor(period_quantities, period_type)
     expected_schedule = dates.from_np_datetimes(
         _to_np_datetimes(expected_schedule))
     actual_schedule = dates.PeriodicSchedule(
         start_date=start_dates,
         end_date=end_dates,
         tenor=tenors,
         holiday_calendar=dates.HolidayCalendar(
             weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY,
             start_year=2020,
             end_year=2028),
         roll_convention=dates.BusinessDayConvention.MODIFIED_FOLLOWING,
         backward=backward,
         end_of_month=end_of_month).dates()
     self.assertAllEqual(expected_schedule.ordinal(),
                         actual_schedule.ordinal())
예제 #4
0
  def _setup_tensors(self):
    """Sets up tensors for efficient computations."""
    date_schedule = dates.PeriodicSchedule(
        start_date=self._start_date,
        end_date=self._maturity_date,
        tenor=self._reset_frequency).dates()

    # rates reset at the begining of coupon period
    reset_dates = date_schedule[:, :-1]
    # payments occur at the end of the coupon period
    payment_dates = date_schedule[:, 1:]
    daycount_fractions = rc.get_daycount_fraction(
        date_schedule[:, :-1],
        date_schedule[:, 1:],
        self._daycount_convention,
        dtype=self._dtype)
    contract_index = tf.repeat(
        tf.range(0, self._batch_size),
        payment_dates.shape.as_list()[-1])

    self._num_caplets = daycount_fractions.shape.as_list()[-1]
    # TODO(b/152164086): Use the functionality from dates library
    self._rate_term = tf.repeat(tf.cast(reset_dates[:, 0].days_until(
        payment_dates[:, 0]), dtype=self._dtype) / 365.0, self._num_caplets)
    self._reset_dates = dates.DateTensor.reshape(reset_dates, [-1])
    self._payment_dates = dates.DateTensor.reshape(payment_dates, [-1])
    self._accrual_start_dates = dates.DateTensor.reshape(reset_dates, [-1])
    self._accrual_end_dates = dates.DateTensor.reshape(payment_dates, [-1])
    self._daycount_fractions = tf.reshape(daycount_fractions, [-1])
    self._contract_index = contract_index
    self._strike = tf.repeat(self._strike, self._num_caplets)
    self._is_cap = tf.repeat(self._is_cap, self._num_caplets)
예제 #5
0
    def _setup(self, coupon_spec):
        """Setup tensors for efficient computations."""

        cpn_frequency = dates.periods.PeriodTensor.stack(
            [x.coupon_frequency for x in coupon_spec], axis=0)
        cpn_dates = dates.PeriodicSchedule(
            start_date=self._start_date,
            end_date=self._end_date,
            tenor=cpn_frequency,
            roll_convention=coupon_spec[-1].businessday_rule).dates()
        accrual_start_dates = cpn_dates[:, :-1]
        ref_term = dates.periods.PeriodTensor.stack(
            [x.reference_rate_term for x in coupon_spec], axis=0)

        accrual_end_dates = cpn_dates[:, :
                                      -1] + dates.periods.PeriodTensor.expand_dims(
                                          ref_term, axis=-1).broadcast_to(
                                              accrual_start_dates.shape)
        coupon_start_dates = cpn_dates[:, :-1]
        coupon_end_dates = cpn_dates[:, 1:]
        payment_dates = cpn_dates[:, 1:]

        daycount_fractions = rc.get_daycount_fraction(
            cpn_dates[:, :-1],
            cpn_dates[:, 1:],
            coupon_spec[-1].daycount_convention,
            dtype=self._dtype)

        notional = tf.repeat(
            tf.convert_to_tensor([x.notional for x in coupon_spec],
                                 dtype=self._dtype),
            payment_dates.shape.as_list()[-1])

        coupon_basis = tf.repeat(
            tf.convert_to_tensor([x.coupon_basis for x in coupon_spec],
                                 dtype=self._dtype),
            payment_dates.shape.as_list()[-1])

        coupon_multiplier = tf.repeat(
            tf.convert_to_tensor([x.coupon_multiplier for x in coupon_spec],
                                 dtype=self._dtype),
            payment_dates.shape.as_list()[-1])

        contract_index = tf.repeat(tf.range(0, len(coupon_spec)),
                                   payment_dates.shape.as_list()[-1])

        self._num_cashflows = daycount_fractions.shape.as_list()[-1]
        self._coupon_start_dates = coupon_start_dates.reshape([-1])
        self._coupon_end_dates = coupon_end_dates.reshape([-1])
        self._payment_dates = payment_dates.reshape([-1])
        self._accrual_start_date = accrual_start_dates.reshape([-1])
        self._accrual_end_date = accrual_end_dates.reshape([-1])
        self._notional = notional
        self._daycount_fractions = tf.reshape(daycount_fractions, [-1])
        self._coupon_basis = coupon_basis
        self._coupon_multiplier = coupon_multiplier
        self._contract_index = contract_index
예제 #6
0
    def _setup(self):
        """Setup relevant tensors for efficient computations."""

        reset_dates = []
        contract_idx = []
        daycount_fractions = []
        for i in range(self._batch_size):
            instr_reset_dates = dates.PeriodicSchedule(
                start_date=self._start_date[i] + self._rate_tenor,
                end_date=self._end_date[i],
                tenor=self._rate_tenor,
                holiday_calendar=self._holiday_calendar,
                roll_convention=dates.BusinessDayConvention.FOLLOWING).dates()

            # Append the start_date of the contract
            instr_reset_dates = dates.DateTensor.concat(
                [self._start_date[i].expand_dims(axis=0), instr_reset_dates],
                axis=0)

            # Add one day beyond the end of the delivery period to compute the
            # accrual on the last day of the delivery.
            one_period_past_enddate = self._end_date[i] + self._rate_tenor
            instr_reset_dates = dates.DateTensor.concat([
                instr_reset_dates,
                one_period_past_enddate.expand_dims(axis=0)
            ],
                                                        axis=0)

            instr_daycount_fractions = rc.get_daycount_fraction(
                instr_reset_dates[:-1], instr_reset_dates[1:],
                self._daycount_convention, self._dtype)

            reset_dates.append(instr_reset_dates[:-1])
            daycount_fractions.append(instr_daycount_fractions)
            contract_idx.append(tf.fill(tf.shape(instr_daycount_fractions), i))

        self._reset_dates = dates.DateTensor.concat(reset_dates, axis=0)
        self._accrual_start_dates = self._reset_dates
        self._accrual_end_dates = self._reset_dates + self._rate_tenor
        self._accrual_daycount = rc.get_daycount_fraction(
            self._accrual_start_dates, self._accrual_end_dates,
            self._daycount_convention, self._dtype)
        self._daycount_fractions = tf.concat(daycount_fractions, axis=0)
        self._contract_idx = tf.concat(contract_idx, axis=0)
예제 #7
0
    def _setup(self, coupon_spec):
        """Setup tensors for efficient computations."""

        cpn_frequency = dates.periods.PeriodTensor.stack(
            [x.coupon_frequency for x in coupon_spec], axis=0)
        cpn_dates = dates.PeriodicSchedule(
            start_date=self._start_date,
            end_date=self._end_date,
            tenor=cpn_frequency,
            roll_convention=coupon_spec[-1].businessday_rule).dates()
        payment_dates = cpn_dates[:, 1:]
        notional = tf.expand_dims(tf.convert_to_tensor(
            [x.notional for x in coupon_spec], dtype=self._dtype),
                                  axis=-1)
        notional = tf.repeat(notional,
                             payment_dates.shape.as_list()[-1],
                             axis=-1)
        daycount_fractions = rc.get_daycount_fraction(
            cpn_dates[:, :-1],
            cpn_dates[:, 1:],
            coupon_spec[-1].daycount_convention,
            dtype=self._dtype)
        fixed_rate = tf.convert_to_tensor([x.coupon_rate for x in coupon_spec],
                                          dtype=self._dtype)
        coupon_rate = tf.expand_dims(fixed_rate, axis=-1)
        coupon_rate = tf.repeat(coupon_rate,
                                payment_dates.shape.as_list()[-1],
                                axis=-1)
        contract_index = tf.repeat(tf.range(0, len(coupon_spec)),
                                   notional.shape.as_list()[-1])

        self._payment_dates = payment_dates.reshape([-1])
        self._notional = tf.reshape(notional, [-1])
        self._daycount_fractions = tf.reshape(daycount_fractions, [-1])
        self._coupon_rate = tf.reshape(coupon_rate, [-1])
        self._fixed_rate = tf.convert_to_tensor(fixed_rate, dtype=self._dtype)
        self._contract_index = contract_index