예제 #1
0
def actual_365_fixed(*,
                     start_date,
                     end_date,
                     schedule_info=None,
                     dtype=None,
                     name=None):
    """Computes the year fraction between the specified dates.
    The actual/365 convention specifies the year fraction between the start and
    end date as the actual number of days between the two dates divided by 365.
    Note that the schedule info is not needed for this convention and is ignored
    if supplied.
    For more details see:
    https://en.wikipedia.org/wiki/Day_count_convention#Actual/365_Fixed
    Args:
        start_date: A `DateTensor` object of any shape.
        end_date: A `DateTensor` object of compatible shape with `start_date`.
        schedule_info: The schedule info. Ignored for this convention.
        dtype: The dtype of the result. Either `tf.float32` or `tf.float64`. If not
        supplied, `tf.float32` is returned.
        name: Python `str` name prefixed to ops created by this function. If not
        supplied, `actual_365_fixed` is used.
    Returns:
        A real `Tensor` of supplied `dtype` and shape of `start_date`. The year
        fraction between the start and end date as computed by Actual/365 fixed
        convention.
    """
    del schedule_info
    end_date = dt.convert_to_date_tensor(end_date)
    start_date = dt.convert_to_date_tensor(start_date)
    actual_days = start_date.days_until(end_date)
    return actual_days / 365
 def business_days_between(self, from_dates, to_dates):
     """Calculates number of business between pairs of dates.
 For each pair, the initial date is included in the difference, and the final
 date is excluded. If the final date is the same or earlier than the initial
 date, zero is returned.
 Args:
   from_dates: `DateTensor` of initial dates.
   to_dates: `DateTensor` of final dates, should be broadcastable to
     `from_dates`.
 Returns:
    An int32 Tensor with the number of business days between the
    corresponding pairs of dates.
 """
     from_biz, from_is_bizday = self._to_biz_space(
         dt.convert_to_date_tensor(from_dates).ordinal())
     to_biz, to_is_bizday = self._to_biz_space(
         dt.convert_to_date_tensor(to_dates).ordinal())
     from_biz = np.where(from_is_bizday, from_biz, from_biz + 1)
     to_biz = np.where(to_is_bizday, to_biz, to_biz + 1)
     return np.maximum(to_biz - from_biz, 0)
예제 #3
0
def actual_365_actual(*,
                      start_date,
                      end_date,
                      schedule_info=None,
                      dtype=None,
                      name=None):
    """Computes the year fraction between the specified dates.
    The actual/365 actual convention specifies the year fraction between the
    start and end date as the actual number of days between the two dates divided
    365 if no leap day is contained in the date range and 366 otherwise.
    When determining whether a leap day is contained in the date range,
    `start_date` is excluded and `end_date` is included.
    Note that the schedule info is not needed for this convention and is ignored
    if supplied.
    Args:
        start_date: A `DateTensor` object of any shape.
        end_date: A `DateTensor` object of compatible shape with `start_date`.
        schedule_info: The schedule info. Ignored for this convention.
        dtype: The dtype of the result. Either `tf.float32` or `tf.float64`. If not
        supplied, `tf.float32` is returned.
        name: Python `str` name prefixed to ops created by this function. If not
        supplied, `actual_365_actual` is used.
    Returns:
        A real `Tensor` of supplied `dtype` and shape of `start_date`. The year
        fraction between the start and end date as computed by Actual/365 Actual
        convention.
    """
    del schedule_info
    end_date = dt.convert_to_date_tensor(end_date)
    start_date = dt.convert_to_date_tensor(start_date)
    actual_days = start_date.days_until(end_date)
    # Add a day to start_date and end_date so that start_date is excluded and
    # end_date is included.
    day = periods.day()
    leap_days_between = du.leap_days_between(start_date=start_date + day,
                                             end_date=end_date + day)
    denominator = np.where(leap_days_between > 0, 366, 365)
    return actual_days / denominator
예제 #4
0
def actual_actual_isda(*,
                       start_date,
                       end_date,
                       schedule_info=None,
                       dtype=None,
                       name=None):
    """Computes the year fraction between the specified dates.
    Computes the year fraction between the dates by dividing the actual number of
    days in a leap year by 366 and the actual number of days in a standard year by
    365.
    When determining whether a leap day is contained in the date range,
    'start_date' is excluded and 'end_date' is included.
    Note that the schedule info is not needed for this convention and is ignored
    if supplied.
    https://en.wikipedia.org/wiki/Day_count_convention#Actual/Actual_ISDA
    Args:
        start_date: A `DateTensor` object of any shape.
        end_date: A `DateTensor` object of compatible shape with `start_date`.
        schedule_info: The schedule info. Ignored for this convention.
        dtype: The dtype of the result. Either `tf.float32` or `tf.float64`. If not
        supplied, `tf.float32` is returned.
        name: Python `str` name prefixed to ops created by this function. If not
        supplied, `actual_actual_isda` is used.
    Returns:
        A real `Tensor` of supplied `dtype` and shape of `start_date`. The year
        fraction between the start and end date as computed by Actual/Actual ISDA
        convention.
    """
    end_date = dt.convert_to_date_tensor(end_date)
    start_date = dt.convert_to_date_tensor(start_date)
    (days_in_leap_years,
     days_in_nonleap_years) = du.days_in_leap_and_nonleap_years_between(
         start_date, end_date)
    # Cast to the target dtype
    days_in_leap_years = days_in_leap_years
    days_in_nonleap_years = days_in_nonleap_years
    return days_in_leap_years / 366 + days_in_nonleap_years / 365
    def __init__(self,
                 weekend_mask=None,
                 holidays=None,
                 start_year=None,
                 end_year=None):
        """Initializer.
    Args:
      weekend_mask: Tensor of 7 elements, where "0" means work day and "1" -
        day off. The first element is Monday. By default, no weekends are
        applied. Some of the common weekend patterns are defined in
        `dates.WeekendMask`.
        Default value: None which maps to no weekend days.
      holidays: Defines the holidays that are added to the weekends defined by
      `weekend_mask`. An instance of `dates.DateTensor` or an object
       convertible to `DateTensor`.
       Default value: None which means no holidays other than those implied by
       the weekends (if any).
      start_year: Integer giving the earliest year this calendar includes. If
        `holidays` is specified, then `start_year` and `end_year` are ignored,
        and the boundaries are derived from `holidays`. If `holidays` is `None`,
        both `start_year` and `end_year` must be specified.
      end_year: Integer giving the latest year this calendar includes. If
        `holidays` is specified, then `start_year` and `end_year` are ignored,
        and the boundaries are derived from `holidays`. If `holidays` is `None`,
        both `start_year` and `end_year` must be specified.
    """
        self._weekend_mask = np.array(weekend_mask
                                      or constants.WeekendMask.NONE)
        if holidays is None:
            self._holidays = None
        else:
            self._holidays = dt.convert_to_date_tensor(holidays)
        start_year, end_year = _resolve_calendar_boundaries(
            self._holidays, start_year, end_year)
        self._ordinal_offset = dt.from_year_month_day(start_year, 1,
                                                      1).ordinal()
        self._calendar_size = (
            dt.from_year_month_day(end_year + 1, 1, 1).ordinal() -
            self._ordinal_offset)

        # Precomputed tables. These are constant 1D Tensors, mapping each day in the
        # [start_year, end_year] period to some quantity of interest, e.g. next
        # business day. The tables should be indexed with
        # `date.ordinal - self._offset`. All tables are computed lazily.
        # All tables have an extra element at the beginning and the end, see comment
        # in _compute_is_bus_day_table().
        self._table_cache = _TableCache()
 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))
 def __init__(self, weekend_mask=None, holidays=None):
     """Initializer.
 Args:
   weekend_mask: Boolean `Tensor` of 7 elements one for each day of the week
     starting with Monday at index 0. A `True` value indicates the day is
     considered a weekend day and a `False` value implies a week day.
     Default value: None which means no weekends are applied.
   holidays: Defines the holidays that are added to the weekends defined by
     `weekend_mask`. An instance of `dates.DateTensor` or an object
     convertible to `DateTensor`.
     Default value: None which means no holidays other than those implied by
       the weekends (if any).
 """
     if weekend_mask is not None:
         weekend_mask = np.array(weekend_mask, dtype=np.bool)
     if holidays is not None:
         holidays = dt.convert_to_date_tensor(holidays).ordinal()
     self._to_biz_space, self._from_biz_space = hol.business_day_mappers(
         weekend_mask=weekend_mask, holidays=holidays)
    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.'))

        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))
 def is_business_day(self, date_tensor):
     """Returns a tensor of bools for whether given dates are business days."""
     ordinals = dt.convert_to_date_tensor(date_tensor).ordinal()
     return self._to_biz_space(ordinals)[1]