Beispiel #1
0
  def _compute_rolled_dates_table_without_cache(self, convention):
    is_bus_day = self._compute_is_bus_day_table()
    cumul_bus_days = self._compute_cumul_bus_days_table()
    bus_day_ordinals = self._compute_bus_day_ordinals_table()

    if convention == constants.BusinessDayConvention.FOLLOWING:
      return tf.gather(bus_day_ordinals, cumul_bus_days)

    if convention == constants.BusinessDayConvention.PRECEDING:
      return tf.gather(bus_day_ordinals,
                       cumul_bus_days - (1 - is_bus_day))

    following = self._compute_rolled_dates_table(
        constants.BusinessDayConvention.FOLLOWING)
    preceding = self._compute_rolled_dates_table(
        constants.BusinessDayConvention.PRECEDING)
    dates_following = dt.from_ordinals(following)
    dates_preceding = dt.from_ordinals(preceding)
    original_dates = dt.from_ordinals(
        tf.range(self._ordinal_offset - 1,
                 self._ordinal_offset + self._calendar_size + 1))

    if convention == constants.BusinessDayConvention.MODIFIED_FOLLOWING:
      return tf.where(tf.equal(dates_following.month(), original_dates.month()),
                      following, preceding)

    if convention == constants. BusinessDayConvention.MODIFIED_PRECEDING:
      return tf.where(tf.equal(dates_preceding.month(), original_dates.month()),
                      preceding, following)

    raise ValueError("Unrecognized convention: {}".format(convention))
    def add_business_days(
            self,
            date_tensor,
            num_days,
            roll_convention=constants.BusinessDayConvention.NONE):
        """Adds given number of business days to given dates.

    Note that this is different from calling `add_period_and_roll` with
    PeriodType.DAY. For example, adding 5 business days to Monday gives the next
    Monday (unless there are holidays on this week or next Monday). Adding 5
    days and rolling means landing on Saturday and then rolling either to next
    Monday or to Friday of the same week, depending on the roll convention.

    If any of the dates in `date_tensor` are not business days, they will be
    rolled to business days before doing the addition. If `roll_convention` is
    `NONE`, and any dates are not business days, an exception is raised.

    Args:
      date_tensor: DateTensor of dates to advance from.
      num_days: Tensor of int32 type broadcastable to `date_tensor`.
      roll_convention: BusinessDayConvention. Determines how to roll a date that
        falls on a holiday.

    Returns:
      The resulting DateTensor.
    """
        control_deps = []
        if roll_convention == constants.BusinessDayConvention.NONE:
            message = ("Some dates in date_tensor are not business days. "
                       "Please specify the roll_convention argument.")
            is_bus_day = self.is_business_day(date_tensor)
            control_deps.append(
                tf.debugging.assert_equal(is_bus_day, True, message=message))
        else:
            date_tensor = self.roll_to_business_day(date_tensor,
                                                    roll_convention)

        with tf.compat.v1.control_dependencies(control_deps):
            cumul_bus_days_table = self._compute_cumul_bus_days_table()
            cumul_bus_days = self._gather(
                cumul_bus_days_table,
                date_tensor.ordinal() - self._ordinal_offset)
            target_cumul_bus_days = cumul_bus_days + num_days

            bus_day_ordinals_table = self._compute_bus_day_ordinals_table()
            ordinals = self._gather(bus_day_ordinals_table,
                                    target_cumul_bus_days)
            return dt.from_ordinals(ordinals, validate=False)
  def roll_to_business_day(self, date_tensor, roll_convention):
    """Rolls the given dates to business dates according to given convention.

    Args:
      date_tensor: `DateTensor` of dates to roll from.
      roll_convention: BusinessDayConvention. Determines how to roll a date that
        falls on a holiday.

    Returns:
      The resulting `DateTensor`.
    """
    if roll_convention == constants.BusinessDayConvention.NONE:
      return date_tensor
    ordinals = dt.convert_to_date_tensor(date_tensor).ordinal()
    biz_days, is_bizday = self._to_biz_space(ordinals)
    biz_days_rolled = self._apply_roll_biz_space(date_tensor, biz_days,
                                                 is_bizday, roll_convention)
    return dt.from_ordinals(self._from_biz_space(biz_days_rolled))
Beispiel #4
0
  def roll_to_business_day(self, date_tensor, roll_convention):
    """Rolls the given dates to business dates according to given convention.

    Args:
      date_tensor: DateTensor of dates to roll from.
      roll_convention: BusinessDayConvention. Determines how to roll a date that
        falls on a holiday.

    Returns:
      The resulting DateTensor.
    """
    if roll_convention == constants.BusinessDayConvention.NONE:
      return date_tensor
    adjusted_ordinals_table = self._compute_rolled_dates_table(roll_convention)
    ordinals_with_offset = date_tensor.ordinal() - self._ordinal_offset
    adjusted_ordinals = self._gather(adjusted_ordinals_table,
                                     ordinals_with_offset)
    return dt.from_ordinals(adjusted_ordinals, validate=False)
Beispiel #5
0
    def add_business_days(
            self,
            date_tensor,
            num_days,
            roll_convention=constants.BusinessDayConvention.NONE):
        """Adds given number of business days to given dates.

    Note that this is different from calling `add_period_and_roll` with
    PeriodType.DAY. For example, adding 5 business days to Monday gives the next
    Monday (unless there are holidays on this week or next Monday). Adding 5
    days and rolling means landing on Saturday and then rolling either to next
    Monday or to Friday of the same week, depending on the roll convention.

    If any of the dates in `date_tensor` are not business days, they will be
    rolled to business days before doing the addition. If `roll_convention` is
    `NONE`, and any dates are not business days, an exception is raised.

    Args:
      date_tensor: `DateTensor` of dates to advance from.
      num_days: Tensor of int32 type broadcastable to `date_tensor`.
      roll_convention: BusinessDayConvention. Determines how to roll a date that
        falls on a holiday.

    Returns:
      The resulting `DateTensor`.
    """
        control_deps = []
        biz_days, is_bizday = self._to_biz_space(
            dt.convert_to_date_tensor(date_tensor).ordinal())
        if roll_convention == constants.BusinessDayConvention.NONE:
            control_deps.append(
                tf.debugging.assert_equal(
                    is_bizday,
                    True,
                    message='Non business starting day with no roll convention.'
                ))

        with tf.compat.v1.control_dependencies(control_deps):
            biz_days_rolled = self._apply_roll_biz_space(
                date_tensor, biz_days, is_bizday, roll_convention)
            return dt.from_ordinals(
                self._from_biz_space(biz_days_rolled + num_days))