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 = self._generate_schedule(cpn_frequency, coupon_spec[-1].businessday_rule) 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
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)
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
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)
def _setup(self, coupon_spec): """Setup tensors for efficient computations.""" if isinstance(coupon_spec, list): cpn_frequency = dates.periods.PeriodTensor.stack( [x.coupon_frequency for x in coupon_spec], axis=0) businessday_rule = coupon_spec[-1].businessday_rule notional = tf.convert_to_tensor([x.notional for x in coupon_spec], dtype=self._dtype) fixed_rate = tf.convert_to_tensor([x.coupon_rate for x in coupon_spec], dtype=self._dtype) daycount_convention = coupon_spec[-1].daycount_convention else: cpn_frequency = coupon_spec.coupon_frequency businessday_rule = coupon_spec.businessday_rule notional = tf.broadcast_to( tf.convert_to_tensor(coupon_spec.notional, dtype=self._dtype), self._start_date.shape) fixed_rate = tf.broadcast_to( tf.convert_to_tensor(coupon_spec.coupon_rate, dtype=self._dtype), self._start_date.shape) daycount_convention = coupon_spec.daycount_convention cpn_dates, _ = self._generate_schedule(cpn_frequency, businessday_rule) payment_dates = cpn_dates[:, 1:] notional = tf.repeat(notional, payment_dates.shape.as_list()[-1]) daycount_fractions = rc.get_daycount_fraction( cpn_dates[:, :-1], cpn_dates[:, 1:], daycount_convention, dtype=self._dtype) coupon_rate = tf.expand_dims(fixed_rate, axis=-1) coupon_rate = tf.repeat(coupon_rate, payment_dates.shape.as_list()[-1]) contract_index = tf.repeat(tf.range(0, self._batch_size), payment_dates.shape.as_list()[-1]) self._num_cashflows = payment_dates.shape.as_list()[-1] self._payment_dates = payment_dates.reshape([-1]) self._notional = notional self._daycount_fractions = tf.reshape(daycount_fractions, [-1]) self._coupon_rate = coupon_rate self._fixed_rate = tf.convert_to_tensor(fixed_rate, dtype=self._dtype) self._contract_index = contract_index
def __init__(self, settlement_date, fixing_date, fixed_rate, notional=1., daycount_convention=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_convention: An optional `DayCountConvention` to determine how cashflows are accrued for each contract. 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. 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_convention is None: daycount_convention = rc.DayCountConvention.ACTUAL_360 self._fixed_rate = tf.convert_to_tensor(fixed_rate, dtype=self._dtype, name='fixed_rate') self._daycount_convention = daycount_convention self._daycount_fraction = rc.get_daycount_fraction( self._accrual_start_date, self._accrual_end_date, self._daycount_convention, self._dtype)
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)
def _setup(self, coupon_spec): """Setup tensors for efficient computations.""" cpn_frequency = dates.PeriodTensor.stack( [x.coupon_frequency for x in coupon_spec], axis=0) cpn_dates, _ = self._generate_schedule(cpn_frequency, coupon_spec[-1].businessday_rule) cms_start_dates = cpn_dates[:, :-1] cms_term = dates.PeriodTensor.stack([x.tenor for x in coupon_spec], axis=0) cms_end_dates = cpn_dates[:, :-1] + cms_term.expand_dims( axis=-1).broadcast_to(cms_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( coupon_start_dates, coupon_end_dates, 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]) cms_fixed_leg = [x.fixed_leg for x in coupon_spec] cms_float_leg = [x.float_leg for x in coupon_spec] self._num_cashflows = daycount_fractions.shape.as_list()[-1] self._swap = irs.InterestRateSwap( cms_start_dates.reshape([-1]), cms_end_dates.reshape([-1]), list(itertools.chain.from_iterable( itertools.repeat(i, self._num_cashflows) for i in cms_fixed_leg)), list(itertools.chain.from_iterable( itertools.repeat(i, self._num_cashflows) for i in cms_float_leg)), dtype=self._dtype ) 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._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 # convexity related values def term_to_years(t): frac = tf.where(t.period_type() == dates.PeriodType.MONTH, tf.constant(1. / 12., dtype=self._dtype), tf.where( t.period_type() == dates.PeriodType.YEAR, tf.constant(1., dtype=self._dtype), tf.constant(0., dtype=self._dtype))) return frac * tf.cast(t.quantity(), dtype=self._dtype) cms_fixed_leg_frequency = dates.PeriodTensor.stack( [x.fixed_leg.coupon_frequency for x in coupon_spec], axis=0) self._delta = term_to_years(cpn_frequency) self._tau = term_to_years(cms_fixed_leg_frequency) self._cms_periods = term_to_years(cms_term) / self._tau
def _setup(self, coupon_spec): """Setup tensors for efficient computations.""" if isinstance(coupon_spec, list): cpn_frequency = dates.periods.PeriodTensor.stack( [x.coupon_frequency for x in coupon_spec], axis=0) businessday_rule = coupon_spec[-1].businessday_rule ref_term = dates.periods.PeriodTensor.stack( [x.reference_rate_term for x in coupon_spec], axis=0) daycount_convention = coupon_spec[-1].daycount_convention notional = tf.convert_to_tensor([x.notional for x in coupon_spec], dtype=self._dtype) coupon_basis = tf.convert_to_tensor( [x.coupon_basis for x in coupon_spec], dtype=self._dtype) coupon_multiplier = tf.convert_to_tensor( [x.coupon_multiplier for x in coupon_spec], dtype=self._dtype) else: cpn_frequency = coupon_spec.coupon_frequency businessday_rule = coupon_spec.businessday_rule ref_term = coupon_spec.reference_rate_term daycount_convention = coupon_spec.daycount_convention notional = tf.broadcast_to( tf.convert_to_tensor(coupon_spec.notional, dtype=self._dtype), self._start_date.shape) coupon_basis = tf.broadcast_to( tf.convert_to_tensor(coupon_spec.coupon_basis, dtype=self._dtype), self._start_date.shape) coupon_multiplier = tf.broadcast_to( tf.convert_to_tensor(coupon_spec.coupon_multiplier, dtype=self._dtype), self._start_date.shape) cpn_dates = self._generate_schedule(cpn_frequency, businessday_rule) accrual_start_dates = cpn_dates[:, :-1] 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:], daycount_convention, dtype=self._dtype) notional = tf.repeat(notional, payment_dates.shape.as_list()[-1]) coupon_basis = tf.repeat(coupon_basis, payment_dates.shape.as_list()[-1]) coupon_multiplier = tf.repeat(coupon_multiplier, payment_dates.shape.as_list()[-1]) contract_index = tf.repeat(tf.range(0, self._batch_size), 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