def price(self, valuation_date, market, model=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: Reserved for future use. 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. """ del model name = name or (self._name + '_price') with tf.name_scope(name): discount_curve = market.discount_curve reference_curve = market.reference_curve libor_rate = rc.get_rate_index(market, self._start_date, rc.RateIndexType.LIBOR, dtype=self._dtype) libor_rate = tf.repeat( tf.convert_to_tensor(libor_rate, dtype=self._dtype), self._num_cashflows) discount_factors = discount_curve.get_discount_factor( self._payment_dates) forward_rates = reference_curve.get_forward_rate( self._accrual_start_date, self._accrual_end_date, self._daycount_fractions) forward_rates = tf.where(self._daycount_fractions > 0., forward_rates, tf.zeros_like(forward_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. forward_rates = tf.where( self._coupon_end_dates < valuation_date, tf.constant(0., dtype=self._dtype), tf.where(self._coupon_start_dates < valuation_date, libor_rate, forward_rates)) coupon_rate = self._coupon_multiplier * (forward_rates + self._coupon_basis) cashflow_pvs = self._notional * (self._daycount_fractions * coupon_rate * discount_factors) return tf.math.reduce_sum(tf.reshape( cashflow_pvs, (self._batch_size, self._num_cashflows)), axis=1)
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 _get_forward_rate(self, valuation_date, market): """Returns the relevant forward rates from the market data.""" forward_rates = market.reference_curve.get_forward_rate( self._accrual_start_dates, self._accrual_end_dates, self._daycount_fractions) forward_rates = tf.where(self._daycount_fractions > 0.0, forward_rates, tf.zeros_like(forward_rates)) libor_rate = rc.get_rate_index( market, self._start_date, rc.RateIndexType.LIBOR, dtype=self._dtype) libor_rate = tf.repeat( tf.convert_to_tensor(libor_rate, dtype=self._dtype), self._num_caplets) forward_rates = tf.where( self._accrual_end_dates < valuation_date, tf.constant(0., dtype=self._dtype), tf.where(self._accrual_start_dates < valuation_date, libor_rate, forward_rates)) return forward_rates