def __init__(self, settlement_date, maturity_date, coupon_spec, start_date=None, first_coupon_date=None, penultimate_coupon_date=None, holiday_calendar=None, dtype=None, name=None): """Initialize a batch of fixed coupon bonds. Args: settlement_date: A rank 1 `DateTensor` specifying the settlement date of the bonds. maturity_date: A rank 1 `DateTensor` specifying the maturity dates of the bonds. The shape of the input should be the same as that of `settlement_date`. coupon_spec: A list of `FixedCouponSpecs` specifying the coupon payments. The length of the list should be the same as the number of bonds being created. start_date: An optional `DateTensor` specifying the dates when the interest starts to accrue for the coupons. The input can be used to specify a forward start date for the coupons. The shape of the input correspond to the numbercof instruments being created. Default value: None in which case the coupons start to accrue from the `settlement_date`. first_coupon_date: An optional rank 1 `DateTensor` specifying the dates when first coupon will be paid for bonds with irregular first coupon. penultimate_coupon_date: An optional rank 1 `DateTensor` specifying the dates when the penultimate coupon (or last regular coupon) will be paid for bonds with irregular last coupon. holiday_calendar: An instance of `dates.HolidayCalendar` to specify weekends and holidays. Default value: None in which case a holiday calendar would be created with Saturday and Sunday being the holidays. dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops either supplied to the bond object or created by the bond 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 'bond'. """ self._name = name or 'bond' if holiday_calendar is None: holiday_calendar = dates.create_holiday_calendar( weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY) with tf.name_scope(self._name): self._dtype = dtype self._settlement_date = dates.convert_to_date_tensor( settlement_date) self._maturity_date = dates.convert_to_date_tensor(maturity_date) self._holiday_calendar = holiday_calendar self._setup(coupon_spec, start_date, first_coupon_date, penultimate_coupon_date)
def __init__(self, start_date, maturity_date, pay_leg, receive_leg, holiday_calendar=None, dtype=None, name=None): """Initialize a batch of IRS contracts. Args: start_date: A rank 1 `DateTensor` specifying the dates for the inception (start of the accrual) of the swap contracts. The shape of the input correspond to the number of instruments being created. maturity_date: A rank 1 `DateTensor` specifying the maturity dates for each contract. The shape of the input should be the same as that of `start_date`. pay_leg: A scalar or a list of either `FixedCouponSpecs` or `FloatCouponSpecs` specifying the coupon payments for the payment leg of the swap. If specified as a list then the length of the list should be the same as the number of instruments being created. If specified as a scalar, then the elements of the namedtuple must be of the same shape as (or compatible to) the shape of `start_date`. receive_leg: A scalar or a list of either `FixedCouponSpecs` or `FloatCouponSpecs` specifying the coupon payments for the receiving leg of the swap. If specified as a list then the length of the list should be the same as the number of instruments being created. If specified as a scalar, then the elements of the namedtuple must be of the same shape as (or compatible with) the shape of `start_date`. holiday_calendar: An instance of `dates.HolidayCalendar` to specify weekends and holidays. Default value: None in which case a holiday calendar would be created with Saturday and Sunday being the holidays. dtype: `tf.Dtype`. If supplied the dtype for the real variables or ops either supplied to the IRS object or created by the IRS 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 'interest_rate_swap'. """ self._name = name or 'interest_rate_swap' if holiday_calendar is None: holiday_calendar = dates.create_holiday_calendar( weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY) with tf.name_scope(self._name): self._dtype = dtype self._start_date = dates.convert_to_date_tensor(start_date) self._maturity_date = dates.convert_to_date_tensor(maturity_date) self._holiday_calendar = holiday_calendar self._floating_leg = None self._fixed_leg = None self._pay_leg = self._setup_leg(pay_leg) self._receive_leg = self._setup_leg(receive_leg) self._is_payer = isinstance(self._pay_leg, cs.FixedCashflowStream)
def __init__(self, contract_start_date, contract_end_date, daycount_convention=None, averaging_type=None, contract_unit=1., holiday_calendar=None, dtype=None, name=None): """Initialize the Overnight index futures object. Args: contract_start_date: A Rank 1 `DateTensor` specifying the start dates of the reference period (or delivery period) of each futures contract. The published overnight index during the reference period determines the final settlement price of the futures contract. contract_end_date: A Rank 1 `DateTensor` specifying the ending dates of the reference period (or delivery period) of each futures contract. daycount_convention: An optional scalar `DayCountConvention` corresponding to the day count convention for the underlying rate for each contract. Default value: None in which case each the day count convention equal to DayCountConvention.ACTUAL_360 is used. averaging_type: An optional `AverageType` corresponding to how the final settlement rate is computed from daily rates. Default value: None, in which case `AverageType.COMPOUNDING` is used. contract_unit: An optional scalar or Rank 1 `Tensor` of real dtype specifying the notional amount for the contract. If the notional is entered as a scalar, it is assumed that all of the contracts have a notional equal to the input value. Default value: 1.0 holiday_calendar: An instance of `dates.HolidayCalenday` to specify weekends and holidays. Default value: None in which case a holiday calendar would be created with Saturday and Sunday being the holidays. 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'. """ self._name = name or 'overnight_rate_futures' with tf.compat.v2.name_scope(self._name): self._contract_unit = tf.convert_to_tensor(contract_unit, dtype=dtype) self._dtype = dtype if dtype else self._contract_unit.dtype self._start_date = dates.convert_to_date_tensor( contract_start_date) self._end_date = dates.convert_to_date_tensor(contract_end_date) self._batch_size = self._start_date.shape[0] if daycount_convention is None: daycount_convention = rc.DayCountConvention.ACTUAL_360 if averaging_type is None: averaging_type = rc.AverageType.COMPOUNDING if holiday_calendar is None: holiday_calendar = dates.create_holiday_calendar( weekend_mask=dates.WeekendMask.SATURDAY_SUNDAY) self._daycount_convention = daycount_convention self._averaging_type = averaging_type self._holiday_calendar = holiday_calendar self._rate_tenor = dates.day() self._setup()
def __init__(self, short_position: types.BoolTensor, currency: types.CurrencyProtoType, fixing_date: types.DateTensor, fixed_rate: types.FloatTensor, notional_amount: types.FloatTensor, daycount_convention: types.DayCountConventionsProtoType, business_day_convention: types.BusinessDayConventionProtoType, calendar: types.BankHolidaysProtoType, rate_term: period_pb2.Period, rate_index: types.RateIndexProtoType, settlement_days: Optional[types.IntTensor] = 0, fra_config: ForwardRateAgreementConfig = None, batch_names: Optional[types.StringTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes the batch of FRA contracts. Args: short_position: Whether the contract holder lends or borrows the money. Default value: `True` which means that the contract holder lends the money at the fixed rate. currency: The denominated currency. fixing_date: A `DateTensor` specifying the dates on which forward rate will be fixed. fixed_rate: A `Tensor` of real dtype specifying the fixed rate payment agreed at the initiation of the individual contracts. The shape should be broadcastable with `fixed_rate`. notional_amount: A `Tensor` of real dtype broadcastable with fixed_rate 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. daycount_convention: A `DayCountConvention` to determine how cashflows are accrued for each contract. Daycount is assumed to be the same for all contracts in a given batch. business_day_convention: A business count convention. calendar: A calendar to specify the weekend mask and bank holidays. rate_term: A tenor of the rate (usually Libor) that determines the floating cashflow. rate_index: A type of the floating leg. Either an instance of `RateIndexType` or a list of `RateIndexType`. If list, assumes that the batch shape is of rank 1 and the batch size is equal to the list length. settlement_days: An integer `Tensor` of the shape broadcastable with the shape of `fixing_date`. fra_config: Optional `ForwardRateAgreementConfig`. batch_names: A string `Tensor` of instrument names. Should be of shape `batch_shape + [2]` specying name and instrument type. This is useful when the `from_protos` method is used and the user needs to identify which instruments got batched together. dtype: `tf.Dtype` of the input and output real `Tensor`s. Default value: `None` which maps to `float64`. name: Python str. The name to give to the ops created by this class. Default value: `None` which maps to 'forward_rate_agreement'. """ self._name = name or "forward_rate_agreement" with tf.name_scope(self._name): if batch_names is not None: self._names = tf.convert_to_tensor(batch_names, name="batch_names") else: self._names = None self._dtype = dtype or tf.float64 ones = tf.constant(1, dtype=self._dtype) self._short_position = tf.where(short_position, ones, -ones, name="short_position") self._notional_amount = tf.convert_to_tensor( notional_amount, dtype=self._dtype, name="notional_amount") self._fixed_rate = tf.convert_to_tensor(fixed_rate, dtype=self._dtype, name="fixed_rate") settlement_days = tf.convert_to_tensor(settlement_days) # Business day roll convention and the end of month flag roll_convention, eom = market_data_utils.get_business_day_convention( business_day_convention) # TODO(b/160446193): Calendar is ignored at the moment calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) self._fixing_date = dateslib.convert_to_date_tensor(fixing_date) self._accrual_start_date = calendar.add_business_days( self._fixing_date, settlement_days, roll_convention=roll_convention) self._day_count_fn = market_data_utils.get_daycount_fn( daycount_convention) period = market_data_utils.get_period(rate_term) self._accrual_end_date = calendar.add_period_and_roll( self._accrual_start_date, period, roll_convention=roll_convention) if eom: self._accrual_end_date = self._accrual_end_date.to_end_of_month( ) self._daycount_fractions = self._day_count_fn( start_date=self._accrual_start_date, end_date=self._accrual_end_date, dtype=self._dtype) self._settlement_days = settlement_days self._roll_convention = roll_convention # Get discount and reference curves if isinstance(rate_index, (list, tuple)): rate_index = rate_index[0] index_type = market_data_utils.get_index(rate_index, period=rate_term) reference_curve_type = curve_types.CurveType(currency=currency, index_type=index_type) if fra_config is not None: try: self._discount_curve_type = fra_config.discounting_index except KeyError: self._discount_curve_type = curve_types.CurveType( currency=currency, index_type=curve_types.Index.OIS) else: self._discount_curve_type = curve_types.CurveType( currency=currency, index_type=curve_types.Index.OIS) self._reference_curve_type = reference_curve_type self._batch_shape = self._daycount_fractions.shape.as_list()[:-1]
def __init__(self, coupon_spec: coupon_specs.FixedCouponSpecs, discount_curve_type: _CurveType, start_date: types.DateTensor = None, end_date: types.DateTensor = None, discount_curve_mask: types.IntTensor = None, first_coupon_date: Optional[types.DateTensor] = None, penultimate_coupon_date: Optional[types.DateTensor] = None, schedule_fn: Optional[Callable[..., Any]] = None, schedule: Optional[types.DateTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes a batch of fixed cashflow streams. Args: coupon_spec: An instance of `FixedCouponSpecs` specifying the details of the coupon payment for the cashflow stream. discount_curve_type: An instance of `CurveType` or a list of those. If supplied as a list and `discount_curve_mask` is not supplied, the size of the list should be the same as the number of priced instruments. start_date: A `DateTensor` of `batch_shape` specifying the starting dates of the accrual of the first coupon of the cashflow stream. The shape of the input correspond to the number of streams being created. Either this of `schedule` should be supplied Default value: `None` end_date: A `DateTensor` of `batch_shape`specifying the end dates for accrual of the last coupon in each cashflow stream. The shape of the input should be the same as that of `start_date`. Either this of `schedule` should be supplied Default value: `None` discount_curve_mask: An optional integer `Tensor` of values ranging from `0` to `len(discount_curve_type)` and of shape `batch_shape`. Identifies a mapping between `discount_curve_type` list and the underlying instruments. Default value: `None`. first_coupon_date: An optional `DateTensor` specifying the payment dates of the first coupon of the cashflow stream. Use this input for cashflows with irregular first coupon. Should be of the same shape as `start_date`. Default value: None which implies regular first coupon. penultimate_coupon_date: An optional `DateTensor` specifying the payment dates of the penultimate (next to last) coupon of the cashflow stream. Use this input for cashflows with irregular last coupon. Should be of the same shape as `end_date`. Default value: None which implies regular last coupon. schedule_fn: A callable that accepts `start_date`, `end_date`, `coupon_frequency`, `settlement_days`, `first_coupon_date`, and `penultimate_coupon_date` as `Tensor`s and returns coupon payment days. Default value: `None`. schedule: A `DateTensor` of coupon payment dates. Default value: `None`. dtype: `tf.Dtype` of the input and output real `Tensor`s. 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 'fixed_cashflow_stream'. """ self._name = name or "fixed_cashflow_stream" with tf.name_scope(self._name): curve_list = to_list(discount_curve_type) [ self._discount_curve_type, self._mask ] = process_curve_types(curve_list, discount_curve_mask) if schedule is None: if (start_date is None) or (end_date is None): raise ValueError("If `schedule` is not supplied both " "`start_date` and `end_date` should be supplied") if schedule is None: if isinstance(start_date, tf.Tensor): self._start_date = dateslib.dates_from_tensor( start_date) else: self._start_date = dateslib.convert_to_date_tensor( start_date) if isinstance(start_date, tf.Tensor): self._end_date = dateslib.dates_from_tensor( end_date) else: self._end_date = dateslib.convert_to_date_tensor( end_date) self._first_coupon_date = first_coupon_date self._penultimate_coupon_date = penultimate_coupon_date if self._first_coupon_date is not None: if isinstance(start_date, tf.Tensor): self._first_coupon_date = dateslib.dates_from_tensor( first_coupon_date) else: self._first_coupon_date = dateslib.convert_to_date_tensor( first_coupon_date) if self._penultimate_coupon_date is not None: if isinstance(start_date, tf.Tensor): self._penultimate_coupon_date = dateslib.dates_from_tensor( penultimate_coupon_date) else: self._penultimate_coupon_date = dateslib.convert_to_date_tensor( penultimate_coupon_date) # Update coupon frequency coupon_frequency = _get_attr(coupon_spec, "coupon_frequency") if isinstance(coupon_frequency, period_pb2.Period): coupon_frequency = market_data_utils.get_period( _get_attr(coupon_spec, "coupon_frequency")) if isinstance(coupon_frequency, (list, tuple)): coupon_frequency = market_data_utils.period_from_list( *_get_attr(coupon_spec, "coupon_frequency")) if isinstance(coupon_frequency, dict): coupon_frequency = market_data_utils.period_from_dict( _get_attr(coupon_spec, "coupon_frequency")) businessday_rule = coupon_spec.businessday_rule # Business day roll convention and the end of month flag roll_convention, eom = market_data_utils.get_business_day_convention( businessday_rule) notional = tf.convert_to_tensor( _get_attr(coupon_spec, "notional_amount"), dtype=dtype, name="notional") self._dtype = dtype or notional.dtype fixed_rate = tf.convert_to_tensor(_get_attr(coupon_spec, "fixed_rate"), dtype=self._dtype, name="fixed_rate") # TODO(b/160446193): Calendar is ignored and weekends only is used calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) daycount_fn = market_data_utils.get_daycount_fn( _get_attr(coupon_spec, "daycount_convention"), self._dtype) self._settlement_days = tf.convert_to_tensor( _get_attr(coupon_spec, "settlement_days"), dtype=tf.int32, name="settlement_days") if schedule is not None: if isinstance(start_date, tf.Tensor): coupon_dates = dateslib.dates_from_tensor(schedule) else: coupon_dates = dateslib.convert_to_date_tensor(schedule) elif schedule_fn is None: coupon_dates = _generate_schedule( start_date=self._start_date, end_date=self._end_date, coupon_frequency=coupon_frequency, roll_convention=roll_convention, calendar=calendar, settlement_days=self._settlement_days, end_of_month=eom, first_coupon_date=self._first_coupon_date, penultimate_coupon_date=self._penultimate_coupon_date) else: if first_coupon_date is not None: first_coupon_date = self._first_coupon_date.to_tensor() if penultimate_coupon_date is not None: penultimate_coupon_date = self._penultimate_coupon_date.to_tensor() coupon_dates = schedule_fn( start_date=self._start_date.to_tensor(), end_date=self._end_date.to_tensor(), coupon_frequency=coupon_frequency.quantity(), settlement_days=self._settlement_days, first_coupon_date=first_coupon_date, penultimate_coupon_date=penultimate_coupon_date) # Convert to DateTensor if the result comes from a tf.function coupon_dates = dateslib.convert_to_date_tensor(coupon_dates) self._batch_shape = tf.shape(coupon_dates.ordinal())[:-1] payment_dates = coupon_dates[..., 1:] daycount_fractions = daycount_fn( start_date=coupon_dates[..., :-1], end_date=coupon_dates[..., 1:]) coupon_rate = tf.expand_dims(fixed_rate, axis=-1) self._num_cashflows = tf.shape(payment_dates.ordinal())[-1] self._payment_dates = payment_dates self._notional = notional self._daycount_fractions = daycount_fractions self._coupon_rate = coupon_rate self._calendar = coupon_rate self._fixed_rate = tf.convert_to_tensor(fixed_rate, dtype=self._dtype) self._daycount_fn = daycount_fn
def __init__(self, coupon_spec: coupon_specs.FloatCouponSpecs, discount_curve_type: _CurveType, start_date: types.DateTensor = None, end_date: types.DateTensor = None, discount_curve_mask: types.IntTensor = None, rate_index_curves: curve_types_lib.RateIndexCurve = None, reference_mask: types.IntTensor = None, first_coupon_date: Optional[types.DateTensor] = None, penultimate_coupon_date: Optional[types.DateTensor] = None, schedule_fn: Optional[Callable[..., Any]] = None, schedule: Optional[types.DateTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes a batch of floating cashflow streams. Args: coupon_spec: An instance of `FloatCouponSpecs` specifying the details of the coupon payment for the cashflow stream. discount_curve_type: An instance of `CurveType` or a list of those. If supplied as a list and `discount_curve_mask` is not supplied, the size of the list should be the same as the number of priced instruments. Defines discount curves for the instruments. start_date: A `DateTensor` of `batch_shape` specifying the starting dates of the accrual of the first coupon of the cashflow stream. The shape of the input correspond to the number of streams being created. Either this of `schedule` should be supplied. When passed as an integet `Tensor`, should be of shape `batch_shape + [3]` and contain `[year, month, day]` for each date. Default value: `None` end_date: A `DateTensor` of `batch_shape`specifying the end dates for accrual of the last coupon in each cashflow stream. The shape of the input should be the same as that of `start_date`. Either this of `schedule` should be supplied. When passed as an integet `Tensor`, should be of shape `batch_shape + [3]` and contain `[year, month, day]` for each date. Default value: `None` discount_curve_mask: An optional integer `Tensor` of values ranging from `0` to `len(discount_curve_type) - 1` and of shape `batch_shape`. Identifies a mapping between `discount_curve_type` list and the underlying instruments. Default value: `None`. rate_index_curves: An instance of `RateIndexCurve` or a list of those. If supplied as a list and `reference_mask` is not supplid, the size of the list should be the same as the number of priced instruments. Defines the index curves for each instrument. If not supplied, `coupon_spec.floating_rate_type` is used to identify the curves. Default value: `None`. reference_mask: An optional integer `Tensor` of values ranging from `0` to `len(rate_index_curves) - 1` and of shape `batch_shape`. Identifies a mapping between `rate_index_curves` list and the underlying instruments. Default value: `None`. first_coupon_date: An optional `DateTensor` specifying the payment dates of the first coupon of the cashflow stream. Use this input for cashflows with irregular first coupon. Should be of the same shape as `start_date`. When passed as an integet `Tensor`, should be of shape `batch_shape + [3]` and contain `[year, month, day]` for each date. Default value: None which implies regular first coupon. penultimate_coupon_date: An optional `DateTensor` specifying the payment dates of the penultimate (next to last) coupon of the cashflow stream. Use this input for cashflows with irregular last coupon. Should be of the same shape as `end_date`. When passed as an integet `Tensor`, should be of shape `batch_shape + [3]` and contain `[year, month, day]` for each date. Default value: None which implies regular last coupon. schedule_fn: A callable that accepts `start_date`, `end_date`, `coupon_frequency`, `settlement_days`, `first_coupon_date`, and `penultimate_coupon_date` as `Tensor`s and returns coupon payment days. Default value: `None`. schedule: A `DateTensor` of coupon payment dates including the start and end dates of the cashflows. Default value: `None`. dtype: `tf.Dtype` of the input and output real `Tensor`s. 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 'floating_cashflow_stream'. """ self._name = name or "floating_cashflow_stream" with tf.name_scope(self._name): curve_list = to_list(discount_curve_type) [self._discount_curve_type, self._mask] = process_curve_types(curve_list, discount_curve_mask) self._first_coupon_date = None self._penultimate_coupon_date = None if schedule is None: if (start_date is None) or (end_date is None): raise ValueError( "If `schedule` is not supplied both " "`start_date` and `end_date` should be supplied") if schedule is None: if isinstance(start_date, tf.Tensor): self._start_date = dateslib.dates_from_tensor(start_date) else: self._start_date = dateslib.convert_to_date_tensor( start_date) if isinstance(start_date, tf.Tensor): self._end_date = dateslib.dates_from_tensor(end_date) else: self._end_date = dateslib.convert_to_date_tensor(end_date) self._first_coupon_date = first_coupon_date self._penultimate_coupon_date = penultimate_coupon_date if self._first_coupon_date is not None: if isinstance(start_date, tf.Tensor): self._first_coupon_date = dateslib.dates_from_tensor( first_coupon_date) else: self._first_coupon_date = dateslib.convert_to_date_tensor( first_coupon_date) if self._penultimate_coupon_date is not None: if isinstance(start_date, tf.Tensor): self._penultimate_coupon_date = dateslib.dates_from_tensor( penultimate_coupon_date) else: self._penultimate_coupon_date = dateslib.convert_to_date_tensor( penultimate_coupon_date) # Ignored and weekends only is used calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) # Convert coupon and reset frequencies to PeriodTensor coupon_frequency = _get_attr(coupon_spec, "coupon_frequency") # Update coupon frequency if isinstance(coupon_frequency, period_pb2.Period): coupon_frequency = market_data_utils.get_period( _get_attr(coupon_spec, "coupon_frequency")) if isinstance(coupon_frequency, (list, tuple)): coupon_frequency = market_data_utils.period_from_list( *_get_attr(coupon_spec, "coupon_frequency")) if isinstance(coupon_frequency, dict): coupon_frequency = market_data_utils.period_from_dict( _get_attr(coupon_spec, "coupon_frequency")) # Update reset frequency reset_frequency = _get_attr(coupon_spec, "reset_frequency") if isinstance(reset_frequency, period_pb2.Period): reset_frequency = market_data_utils.get_period( _get_attr(coupon_spec, "reset_frequency")) if isinstance(reset_frequency, (list, tuple)): reset_frequency = market_data_utils.period_from_list( *_get_attr(coupon_spec, "reset_frequency")) if isinstance(reset_frequency, dict): reset_frequency = market_data_utils.period_from_dict( _get_attr(coupon_spec, "reset_frequency")) self._reset_frequency = reset_frequency businessday_rule = _get_attr(coupon_spec, "businessday_rule") roll_convention, eom = market_data_utils.get_business_day_convention( businessday_rule) notional = tf.convert_to_tensor(_get_attr(coupon_spec, "notional_amount"), dtype=dtype, name="notional") self._dtype = dtype or notional.dtype daycount_convention = _get_attr(coupon_spec, "daycount_convention") daycount_fn = market_data_utils.get_daycount_fn( _get_attr(coupon_spec, "daycount_convention"), self._dtype) self._daycount_convention = daycount_convention self._settlement_days = tf.convert_to_tensor( _get_attr(coupon_spec, "settlement_days"), dtype=tf.int32, name="settlement_days") spread = tf.convert_to_tensor(_get_attr(coupon_spec, "spread"), dtype=self._dtype, name="spread") if schedule is not None: if isinstance(start_date, tf.Tensor): coupon_dates = dateslib.dates_from_tensor(schedule) else: coupon_dates = dateslib.convert_to_date_tensor(schedule) # Extract starting date for the cashflow self._start_date = coupon_dates[..., 0] elif schedule_fn is None: coupon_dates = _generate_schedule( start_date=self._start_date, end_date=self._end_date, coupon_frequency=coupon_frequency, roll_convention=roll_convention, calendar=calendar, settlement_days=self._settlement_days, end_of_month=eom, first_coupon_date=self._first_coupon_date, penultimate_coupon_date=self._penultimate_coupon_date) # Extract starting date for the cashflow self._start_date = coupon_dates[..., 0] else: if first_coupon_date is not None: first_coupon_date = self._first_coupon_date.to_tensor() if penultimate_coupon_date is not None: penultimate_coupon_date = self._penultimate_coupon_date.to_tensor( ) coupon_dates = schedule_fn( start_date=self._start_date.to_tensor(), end_date=self._end_date.to_tensor(), coupon_frequency=coupon_frequency.quantity(), settlement_days=self._settlement_days, first_coupon_date=first_coupon_date, penultimate_coupon_date=penultimate_coupon_date) # Convert to DateTensor if the result comes from a tf.function coupon_dates = dateslib.convert_to_date_tensor(coupon_dates) # Extract batch shape self._batch_shape = tf.shape(coupon_dates.ordinal())[:-1] accrual_start_dates = coupon_dates[..., :-1] coupon_start_dates = coupon_dates[..., :-1] coupon_end_dates = coupon_dates[..., 1:] accrual_end_dates = accrual_start_dates + reset_frequency.expand_dims( axis=-1) # Adjust for irregular coupons accrual_end_dates = dateslib.DateTensor.concat([ coupon_end_dates[..., :1], accrual_end_dates[..., 1:-1], coupon_end_dates[..., -1:] ], axis=-1) daycount_fractions = daycount_fn(start_date=coupon_start_dates, end_date=coupon_end_dates) self._num_cashflows = tf.shape(daycount_fractions)[-1] self._coupon_start_dates = coupon_start_dates self._coupon_end_dates = coupon_end_dates self._accrual_start_date = accrual_start_dates self._accrual_end_date = accrual_end_dates self._notional = notional self._daycount_fractions = daycount_fractions self._spread = spread self._currency = _get_attr(coupon_spec, "currency") self._daycount_fn = daycount_fn # Construct the reference curve object # Extract all rate_curves self._floating_rate_type = to_list( _get_attr(coupon_spec, "floating_rate_type")) self._currency = to_list(self._currency) if rate_index_curves is None: rate_index_curves = [] for currency, floating_rate_type in zip( self._currency, self._floating_rate_type): rate_index_curves.append( curve_types_lib.RateIndexCurve( currency=currency, index=floating_rate_type)) [self._reference_curve_type, self._reference_mask ] = process_curve_types(rate_index_curves, reference_mask)
def __init__(self, short_position: types.BoolTensor, currency: types.CurrencyProtoType, expiry_date: types.DateTensor, equity: List[str], contract_amount: types.FloatTensor, strike: types.FloatTensor, is_call_option: List[bool], business_day_convention: types.BusinessDayConventionProtoType, calendar: types.BankHolidaysProtoType, settlement_days: Optional[types.IntTensor] = 0, american_option_config: AmericanOptionConfig = None, batch_names: Optional[types.StringTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes the batch of American Equity Options. Args: short_position: Whether the price is computed for the contract holder. Default value: `True` which means that the price is for the contract holder. currency: The denominated currency. expiry_date: A `DateTensor` specifying the dates on which the options expire. equity: A string name of the underlyings. contract_amount: A `Tensor` of real dtype and shape compatible with with `short_position`. strike: `Tensor` of real dtype and shape compatible with with `short_position`. Option strikes. is_call_option: A bool `Tensor` of shape compatible with with `short_position`. Indicates which options are of call type. business_day_convention: A business count convention. calendar: A calendar to specify the weekend mask and bank holidays. settlement_days: An integer `Tensor` of the shape broadcastable with the shape of `fixing_date`. american_option_config: Optional `AmericanOptionConfig`. batch_names: A string `Tensor` of instrument names. Should be of shape `batch_shape + [2]` specying name and instrument type. This is useful when the `from_protos` method is used and the user needs to identify which instruments got batched together. dtype: `tf.Dtype` of the input and output real `Tensor`s. Default value: `None` which maps to `float64`. name: Python str. The name to give to the ops created by this class. Default value: `None` which maps to 'AmericanOption'. """ self._name = name or "AmericanOption" with tf.name_scope(self._name): if batch_names is not None: self._names = tf.convert_to_tensor(batch_names, name="batch_names") else: self._names = None self._dtype = dtype or tf.float64 ones = tf.constant(1, dtype=self._dtype) self._short_position = tf.where(short_position, ones, -ones, name="short_position") self._contract_amount = tf.convert_to_tensor( contract_amount, dtype=self._dtype, name="contract_amount") self._strike = tf.convert_to_tensor(strike, dtype=self._dtype, name="strike") self._is_call_option = tf.convert_to_tensor(is_call_option, dtype=tf.bool, name="strike") settlement_days = tf.convert_to_tensor(settlement_days) # Business day roll convention and the end of month flag roll_convention, eom = market_data_utils.get_business_day_convention( business_day_convention) # TODO(b/160446193): Calendar is ignored at the moment calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) self._expiry_date = dateslib.convert_to_date_tensor(expiry_date) self._settlement_days = settlement_days self._roll_convention = roll_convention # Get discount and reference curves self._currency = cashflow_streams.to_list(currency) self._equity = cashflow_streams.to_list(equity) if len(self._currency) != len(self._equity): if len(self._currency) > 1 and len(self._equity) > 1: raise ValueError( "Number of currencies and equities should be the same " "but it is {0} and {1}".format(len(self._currency), len(self._equity))) self._discount_curve_type = [] self._model = "BS-LSM" # default pricing model is LSM under Black-Scholes self._num_exercise_times = 100 self._num_samples = 96000 self._seed = [42, 42] if american_option_config is not None: self._model = american_option_config.model self._seed = american_option_config.seed self._num_calibration_samples = None for currency in self._currency: if american_option_config is not None: [ self._num_samples, self._num_exercise_times, self._num_calibration_samples ] = [ american_option_config.num_samples, american_option_config.num_exercise_times, american_option_config.num_calibration_samples ] try: discount_curve_type = american_option_config.discounting_curve[ currency] except (KeyError, TypeError): discount_curve_type = curve_types.RiskFreeCurve( currency=currency) self._discount_curve_type.append(discount_curve_type) else: # Default discounting is the risk free curve risk_free = curve_types.RiskFreeCurve(currency=currency) self._discount_curve_type.append(risk_free) # Get masks for discount curves and vol surfaces [self._discount_curve_type, self._discount_curve_mask] = cashflow_streams.process_curve_types( self._discount_curve_type) [ self._equity, self._equity_mask, ] = equity_utils.process_equities(self._equity) # Get batch shape self._batch_shape = tf.shape(strike)
def __init__(self, short_position: types.BoolTensor, currency: types.CurrencyProtoType, fixing_date: types.DateTensor, fixed_rate: types.FloatTensor, notional_amount: types.FloatTensor, daycount_convention: types.DayCountConventionsProtoType, business_day_convention: types.BusinessDayConventionProtoType, calendar: types.BankHolidaysProtoType, rate_term: period_pb2.Period, rate_index: rate_indices.RateIndex, settlement_days: Optional[types.IntTensor] = 0, discount_curve_type: curve_types_lib.CurveType = None, discount_curve_mask: types.IntTensor = None, rate_index_curves: curve_types_lib.RateIndexCurve = None, reference_mask: types.IntTensor = None, config: Union[ForwardRateAgreementConfig, Dict[str, Any]] = None, batch_names: Optional[types.StringTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes the batch of FRA contracts. Args: short_position: Whether the contract holder lends or borrows the money. Default value: `True` which means that the contract holder lends the money at the fixed rate. currency: The denominated currency. fixing_date: A `DateTensor` specifying the dates on which forward rate will be fixed. fixed_rate: A `Tensor` of real dtype specifying the fixed rate payment agreed at the initiation of the individual contracts. The shape should be broadcastable with `fixed_rate`. notional_amount: A `Tensor` of real dtype broadcastable with fixed_rate 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. daycount_convention: A `DayCountConvention` to determine how cashflows are accrued for each contract. Daycount is assumed to be the same for all contracts in a given batch. business_day_convention: A business count convention. calendar: A calendar to specify the weekend mask and bank holidays. rate_term: A tenor of the rate (usually Libor) that determines the floating cashflow. rate_index: A type of the floating leg. An instance of `core.rate_indices.RateIndex`. settlement_days: An integer `Tensor` of the shape broadcastable with the shape of `fixing_date`. discount_curve_type: An optional instance of `CurveType` or a list of those. If supplied as a list and `discount_curve_mask` is not supplied, the size of the list should be the same as the number of priced instruments. Defines discount curves for the instruments. Default value: `None`, meaning that discount curves are inferred from `currency` and `config`. discount_curve_mask: An optional integer `Tensor` of values ranging from `0` to `len(discount_curve_type) - 1` and of shape `batch_shape`. Identifies a mapping between `discount_curve_type` list and the underlying instruments. Default value: `None`. rate_index_curves: An instance of `RateIndexCurve` or a list of those. If supplied as a list and `reference_mask` is not supplid, the size of the list should be the same as the number of priced instruments. Defines the index curves for each instrument. If not supplied, `coupon_spec.floating_rate_type` is used to identify the curves. Default value: `None`. reference_mask: An optional integer `Tensor` of values ranging from `0` to `len(rate_index_curves) - 1` and of shape `batch_shape`. Identifies a mapping between `rate_index_curves` list and the underlying instruments. Default value: `None`. config: Optional `ForwardRateAgreementConfig` or a dictionary. If dictionary, then the keys should be the same as the field names of `ForwardRateAgreementConfig`. batch_names: A string `Tensor` of instrument names. Should be of shape `batch_shape + [2]` specying name and instrument type. This is useful when the `from_protos` method is used and the user needs to identify which instruments got batched together. dtype: `tf.Dtype` of the input and output real `Tensor`s. Default value: `None` which maps to `float64`. name: Python str. The name to give to the ops created by this class. Default value: `None` which maps to 'forward_rate_agreement'. """ self._name = name or "forward_rate_agreement" with tf.name_scope(self._name): if batch_names is not None: self._names = tf.convert_to_tensor(batch_names, name="batch_names") else: self._names = None self._dtype = dtype or tf.float64 ones = tf.constant(1, dtype=self._dtype) self._short_position = tf.where(short_position, ones, -ones, name="short_position") self._notional_amount = tf.convert_to_tensor( notional_amount, dtype=self._dtype, name="notional_amount") self._fixed_rate = tf.convert_to_tensor(fixed_rate, dtype=self._dtype, name="fixed_rate") settlement_days = tf.convert_to_tensor(settlement_days) # Business day roll convention and the end of month flag roll_convention, eom = market_data_utils.get_business_day_convention( business_day_convention) # TODO(b/160446193): Calendar is ignored at the moment calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) if isinstance(fixing_date, types.IntTensor): self._fixing_date = dateslib.dates_from_tensor(fixing_date) else: self._fixing_date = dateslib.convert_to_date_tensor( fixing_date) self._accrual_start_date = calendar.add_business_days( self._fixing_date, settlement_days, roll_convention=roll_convention) self._day_count_fn = market_data_utils.get_daycount_fn( daycount_convention) period = rate_term if isinstance(rate_term, period_pb2.Period): period = market_data_utils.get_period(rate_term) if isinstance(rate_term, dict): period = market_data_utils.period_from_dict(rate_term) self._accrual_end_date = calendar.add_period_and_roll( self._accrual_start_date, period, roll_convention=roll_convention) if eom: self._accrual_end_date = self._accrual_end_date.to_end_of_month( ) self._daycount_fractions = self._day_count_fn( start_date=self._accrual_start_date, end_date=self._accrual_end_date, dtype=self._dtype) self._settlement_days = settlement_days self._roll_convention = roll_convention # Get discount and reference curves self._currency = cashflow_streams.to_list(currency) self._rate_index = cashflow_streams.to_list(rate_index) # Get a mask for the reference curves if rate_index_curves is None: rate_index_curves = [] if len(self._currency) != len(self._rate_index): raise ValueError( "When rate_index_curves` is not supplied, number of currencies " "and rate indices should be the same `but it is {0} and " "{1}".format(len(self._currency), len(self._rate_index))) for currency, rate_index in zip(self._currency, self._rate_index): rate_index_curves.append( curve_types_lib.RateIndexCurve(currency=currency, index=rate_index)) [self._reference_curve_type, self._reference_mask ] = cashflow_streams.process_curve_types(rate_index_curves, reference_mask) # Get a mask for the discount curves self._config = _process_config(config) if discount_curve_type is None: curve_list = [] for currency in self._currency: if currency in self._config.discounting_curve: discount_curve_type = self._config.discounting_curve[ currency] else: # Default discounting is the risk free curve discount_curve_type = curve_types_lib.RiskFreeCurve( currency=currency) curve_list.append(discount_curve_type) else: curve_list = cashflow_streams.to_list(discount_curve_type) # Get masks for discount and reference curves [self._discount_curve_type, self._mask ] = cashflow_streams.process_curve_types(curve_list, discount_curve_mask) # Get batch shape self._batch_shape = self._daycount_fractions.shape.as_list()[:-1]
def __init__(self, start_date: types.DateTensor, end_date: types.DateTensor, coupon_spec: coupon_specs.FixedCouponSpecs, discount_curve_type: _CurveType, first_coupon_date: Optional[types.DateTensor] = None, penultimate_coupon_date: Optional[types.DateTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes a batch of fixed cashflow streams. Args: start_date: A `DateTensor` of `batch_shape` specifying the starting dates of the accrual of the first coupon of the cashflow stream. The shape of the input correspond to the number of streams being created. end_date: A `DateTensor` of `batch_shape`specifying the end dates for accrual of the last coupon in each cashflow stream. The shape of the input should be the same as that of `start_date`. coupon_spec: An instance of `FixedCouponSpecs` specifying the details of the coupon payment for the cashflow stream. discount_curve_type: An instance of `CurveType`. first_coupon_date: An optional `DateTensor` specifying the payment dates of the first coupon of the cashflow stream. Use this input for cashflows with irregular first coupon. Should be of the same shape as `start_date`. Default value: None which implies regular first coupon. penultimate_coupon_date: An optional `DateTensor` specifying the payment dates of the penultimate (next to last) coupon of the cashflow stream. Use this input for cashflows with irregular last coupon. Should be of the same shape as `end_date`. Default value: None which implies regular last coupon. dtype: `tf.Dtype` of the input and output real `Tensor`s. 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 'fixed_cashflow_stream'. """ self._name = name or "fixed_cashflow_stream" with tf.name_scope(self._name): curve_list = to_list(discount_curve_type) [self._discount_curve_type, self._mask] = process_curve_types(curve_list) self._start_date = dateslib.convert_to_date_tensor(start_date) self._end_date = dateslib.convert_to_date_tensor(end_date) self._first_coupon_date = first_coupon_date self._penultimate_coupon_date = penultimate_coupon_date if self._first_coupon_date is not None: self._first_coupon_date = dateslib.convert_to_date_tensor( first_coupon_date) if self._penultimate_coupon_date is not None: self._penultimate_coupon_date = dateslib.convert_to_date_tensor( penultimate_coupon_date) coupon_frequency = coupon_spec.coupon_frequency if isinstance(coupon_frequency, (period_pb2.Period, list, tuple)): coupon_frequency = market_data_utils.get_period( coupon_spec.coupon_frequency) businessday_rule = coupon_spec.businessday_rule # Business day roll convention and the end of month flag roll_convention, eom = market_data_utils.get_business_day_convention( businessday_rule) notional = tf.convert_to_tensor(coupon_spec.notional_amount, dtype=dtype, name="notional") self._dtype = dtype or notional.dtype fixed_rate = tf.convert_to_tensor(coupon_spec.fixed_rate, dtype=self._dtype, name="fixed_rate") # TODO(b/160446193): Calendar is ignored and weekends only is used calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) daycount_fn = market_data_utils.get_daycount_fn( coupon_spec.daycount_convention) self._settlement_days = tf.convert_to_tensor( coupon_spec.settlement_days, dtype=tf.int32, name="settlement_days") coupon_dates = _generate_schedule( start_date=self._start_date, end_date=self._end_date, coupon_frequency=coupon_frequency, roll_convention=roll_convention, calendar=calendar, settlement_days=self._settlement_days, end_of_month=eom, first_coupon_date=self._first_coupon_date, penultimate_coupon_date=self._penultimate_coupon_date) self._batch_shape = coupon_dates.shape.as_list()[:-1] payment_dates = coupon_dates[..., 1:] daycount_fractions = daycount_fn(start_date=coupon_dates[..., :-1], end_date=coupon_dates[..., 1:], dtype=self._dtype) coupon_rate = tf.expand_dims(fixed_rate, axis=-1) self._num_cashflows = payment_dates.shape.as_list()[-1] self._payment_dates = payment_dates self._notional = notional self._daycount_fractions = daycount_fractions self._coupon_rate = coupon_rate self._calendar = coupon_rate self._fixed_rate = tf.convert_to_tensor(fixed_rate, dtype=self._dtype) self._daycount_fn = daycount_fn
def __init__(self, start_date: types.DateTensor, end_date: types.DateTensor, coupon_spec: coupon_specs.FloatCouponSpecs, discount_curve_type: _CurveType, first_coupon_date: Optional[types.DateTensor] = None, penultimate_coupon_date: Optional[types.DateTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes a batch of floating cashflow streams. Args: start_date: A `DateTensor` of `batch_shape` specifying the starting dates of the accrual of the first coupon of the cashflow stream. The shape of the input correspond to the number of streams being created. end_date: A `DateTensor` of `batch_shape`specifying the end dates for accrual of the last coupon in each cashflow stream. The shape of the input should be the same as that of `start_date`. coupon_spec: An instance of `FloatCouponSpecs` specifying the details of the coupon payment for the cashflow stream. discount_curve_type: An instance of `CurveType`. first_coupon_date: An optional `DateTensor` specifying the payment dates of the first coupon of the cashflow stream. Use this input for cashflows with irregular first coupon. Should be of the same shape as `start_date`. Default value: None which implies regular first coupon. penultimate_coupon_date: An optional `DateTensor` specifying the payment dates of the penultimate (next to last) coupon of the cashflow stream. Use this input for cashflows with irregular last coupon. Should be of the same shape as `end_date`. Default value: None which implies regular last coupon. dtype: `tf.Dtype` of the input and output real `Tensor`s. 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 'floating_cashflow_stream'. """ self._name = name or "floating_cashflow_stream" with tf.name_scope(self._name): curve_list = to_list(discount_curve_type) [self._discount_curve_type, self._mask] = process_curve_types(curve_list) self._first_coupon_date = None self._penultimate_coupon_date = None self._start_date = dateslib.convert_to_date_tensor(start_date) self._end_date = dateslib.convert_to_date_tensor(end_date) if self._first_coupon_date is not None: self._first_coupon_date = dateslib.convert_to_date_tensor( first_coupon_date) if self._penultimate_coupon_date is not None: self._penultimate_coupon_date = dateslib.convert_to_date_tensor( penultimate_coupon_date) # Ignored and weekends only is used calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) # Convert coupon and reset frequencies to PeriodTensor coupon_frequency = coupon_spec.coupon_frequency if isinstance(coupon_frequency, (period_pb2.Period, list, tuple)): coupon_frequency = market_data_utils.get_period( coupon_spec.coupon_frequency) reset_frequency = coupon_spec.reset_frequency if isinstance(reset_frequency, (period_pb2.Period, list, tuple)): reset_frequency = market_data_utils.get_period( coupon_spec.reset_frequency) self._reset_frequency = reset_frequency businessday_rule = coupon_spec.businessday_rule roll_convention, eom = market_data_utils.get_business_day_convention( businessday_rule) notional = tf.convert_to_tensor(coupon_spec.notional_amount, dtype=dtype, name="notional") self._dtype = dtype or notional.dtype daycount_convention = coupon_spec.daycount_convention daycount_fn = market_data_utils.get_daycount_fn( coupon_spec.daycount_convention) self._daycount_convention = daycount_convention self._settlement_days = tf.convert_to_tensor( coupon_spec.settlement_days, dtype=tf.int32, name="settlement_days") spread = tf.convert_to_tensor(coupon_spec.spread, dtype=self._dtype, name="spread") coupon_dates = _generate_schedule( start_date=self._start_date, end_date=self._end_date, coupon_frequency=coupon_frequency, roll_convention=roll_convention, calendar=calendar, settlement_days=self._settlement_days, end_of_month=eom, first_coupon_date=self._first_coupon_date, penultimate_coupon_date=self._penultimate_coupon_date) # Extract batch shape self._batch_shape = coupon_dates.shape.as_list()[:-1] accrual_start_dates = coupon_dates[..., :-1] coupon_start_dates = coupon_dates[..., :-1] coupon_end_dates = coupon_dates[..., 1:] accrual_end_dates = accrual_start_dates + reset_frequency.expand_dims( axis=-1) # Adjust for irregular coupons accrual_end_dates = dateslib.DateTensor.concat([ coupon_end_dates[..., :1], accrual_end_dates[..., 1:-1], coupon_end_dates[..., -1:] ], axis=-1) daycount_fractions = daycount_fn(start_date=coupon_start_dates, end_date=coupon_end_dates, dtype=self._dtype) self._num_cashflows = daycount_fractions.shape.as_list()[-1] self._coupon_start_dates = coupon_start_dates self._coupon_end_dates = coupon_end_dates self._accrual_start_date = accrual_start_dates self._accrual_end_date = accrual_end_dates self._notional = notional self._daycount_fractions = daycount_fractions self._spread = spread self._currency = coupon_spec.currency self._daycount_fn = daycount_fn # Construct the reference curve object # Extract all rate_curves self._floating_rate_type = to_list(coupon_spec.floating_rate_type) self._currency = to_list(self._currency) rate_index_curves = [] for currency, floating_rate_type in zip(self._currency, self._floating_rate_type): rate_index_curves.append( curve_types_lib.RateIndexCurve(currency=currency, index=floating_rate_type)) [self._reference_curve_type, self._reference_mask] = process_curve_types(rate_index_curves)
def __init__(self, short_position: types.BoolTensor, currency: Union[types.CurrencyProtoType, List[types.CurrencyProtoType]], expiry_date: types.DateTensor, equity: List[str], contract_amount: types.FloatTensor, strike: types.FloatTensor, is_call_option: List[bool], business_day_convention: types.BusinessDayConventionProtoType, calendar: types.BankHolidaysProtoType, settlement_days: Optional[types.IntTensor] = 0, discount_curve_type: curve_types_lib.CurveType = None, discount_curve_mask: types.IntTensor = None, equity_mask: types.IntTensor = None, config: Union[AmericanOptionConfig, Dict[str, Any]] = None, batch_names: Optional[types.StringTensor] = None, dtype: Optional[types.Dtype] = None, name: Optional[str] = None): """Initializes the batch of American Equity Options. Args: short_position: Whether the price is computed for the contract holder. Default value: `True` which means that the price is for the contract holder. currency: The denominated currency. expiry_date: A `DateTensor` specifying the dates on which the options expire. equity: A string name of the underlyings. contract_amount: A `Tensor` of real dtype and shape compatible with with `short_position`. strike: `Tensor` of real dtype and shape compatible with with `short_position`. Option strikes. is_call_option: A bool `Tensor` of shape compatible with with `short_position`. Indicates which options are of call type. business_day_convention: A business count convention. calendar: A calendar to specify the weekend mask and bank holidays. settlement_days: An integer `Tensor` of the shape broadcastable with the shape of `fixing_date`. discount_curve_type: An optional instance of `CurveType` or a list of those. If supplied as a list and `discount_curve_mask` is not supplied, the size of the list should be the same as the number of priced instruments. Defines discount curves for the instruments. Default value: `None`, meaning that discount curves are inferred from `currency` and `config`. discount_curve_mask: An optional integer `Tensor` of values ranging from `0` to `len(discount_curve_type) - 1` and of shape `batch_shape`. Identifies a mapping between `discount_curve_type` list and the underlying instruments. Default value: `None`. equity_mask: An optional integer `Tensor` of values ranging from `0` to `len(equity) - 1` and of shape `batch_shape`. Identifies a mapping between `equity` list and the underlying instruments. Default value: `None`. config: Optional `AmericanOptionConfig` or a dictionary. If dictionary, then the keys should be the same as the field names of `AmericanOptionConfig`. batch_names: A string `Tensor` of instrument names. Should be of shape `batch_shape + [2]` specying name and instrument type. This is useful when the `from_protos` method is used and the user needs to identify which instruments got batched together. dtype: `tf.Dtype` of the input and output real `Tensor`s. Default value: `None` which maps to `float64`. name: Python str. The name to give to the ops created by this class. Default value: `None` which maps to 'AmericanOption'. """ self._name = name or "AmericanOption" with tf.name_scope(self._name): if batch_names is not None: self._names = tf.convert_to_tensor(batch_names, name="batch_names") else: self._names = None self._dtype = dtype or tf.float64 ones = tf.constant(1, dtype=self._dtype) self._short_position = tf.where( short_position, ones, -ones, name="short_position") self._contract_amount = tf.convert_to_tensor( contract_amount, dtype=self._dtype, name="contract_amount") self._strike = tf.convert_to_tensor(strike, dtype=self._dtype, name="strike") self._is_call_option = tf.convert_to_tensor( is_call_option, dtype=tf.bool, name="strike") settlement_days = tf.convert_to_tensor(settlement_days) # Business day roll convention and the end of month flag roll_convention, eom = market_data_utils.get_business_day_convention( business_day_convention) # TODO(b/160446193): Calendar is ignored at the moment calendar = dateslib.create_holiday_calendar( weekend_mask=dateslib.WeekendMask.SATURDAY_SUNDAY) if isinstance(expiry_date, types.IntTensor): self._expiry_date = dateslib.dates_from_tensor(expiry_date) else: self._expiry_date = dateslib.convert_to_date_tensor(expiry_date) self._settlement_days = settlement_days self._roll_convention = roll_convention # Get discount and reference curves self._currency = cashflow_streams.to_list(currency) self._equity = cashflow_streams.to_list(equity) if len(self._currency) != len(self._equity): if len(self._currency) > 1 and len(self._equity) > 1: raise ValueError( "Number of currencies and equities should be the same " "but it is {0} and {1}".format(len(self._currency), len(self._equity))) config = _process_config(config) [ self._model, self._num_samples, self._seed, self._num_exercise_times, self._num_calibration_samples ] = _get_config_values(config) if discount_curve_type is None: discount_curve_type = [] for currency in self._currency: if currency in config.discounting_curve: curve_type = config.discounting_curve[currency] else: # Default discounting curve curve_type = curve_types_lib.RiskFreeCurve( currency=currency) discount_curve_type.append(curve_type) # Get masks for discount curves and vol surfaces [ self._discount_curve_type, self._discount_curve_mask ] = cashflow_streams.process_curve_types(discount_curve_type, discount_curve_mask) [ self._equity, self._equity_mask, ] = equity_utils.process_equities(self._equity, equity_mask) # Get batch shape self._batch_shape = tf.shape(strike)