tf_quant_finance.models.hjm.swaption_price

Last updated: 2023-03-16.

tf_quant_finance.models.hjm.swaption_price#

View source

Calculates the price of European swaptions using the HJM model.

tf_quant_finance.models.hjm.swaption_price(
    *, expiries, fixed_leg_payment_times, fixed_leg_daycount_fractions,
    fixed_leg_coupon, reference_rate_fn, num_hjm_factors, mean_reversion,
    volatility, times=None, time_step=None, num_time_steps=None, curve_times=None,
    corr_matrix=None, notional=None, is_payer_swaption=None,
    valuation_method=tf_quant_finance.models.ValuationMethod.MONTE_CARLO,
    num_samples=1, random_type=None, seed=None, skip=0,
    time_step_finite_difference=None, num_time_steps_finite_difference=None,
    num_grid_points_finite_difference=101, dtype=None, name=None
)

A European Swaption is a contract that gives the holder an option to enter a swap contract at a future date at a prespecified fixed rate. A swaption that grants the holder the right to pay fixed rate and receive floating rate is called a payer swaption while the swaption that grants the holder the right to receive fixed and pay floating payments is called the receiver swaption. Typically the start date (or the inception date) of the swap coincides with the expiry of the swaption. Mid-curve swaptions are currently not supported (b/160061740).

This implementation uses the HJM model to numerically value European swaptions. For more information on the formulation of the HJM model, see quasi_gaussian_hjm.py.

Example#

import numpy as np
import tensorflow as tf
import tf_quant_finance as tff

dtype = tf.float64

# Price 1y x 1y swaption with quarterly payments using Monte Carlo
# simulations.
expiries = np.array([1.0])
fixed_leg_payment_times = np.array([1.25, 1.5, 1.75, 2.0])
fixed_leg_daycount_fractions = 0.25 * np.ones_like(fixed_leg_payment_times)
fixed_leg_coupon = 0.011 * np.ones_like(fixed_leg_payment_times)
zero_rate_fn = lambda x: 0.01 * tf.ones_like(x, dtype=dtype)
mean_reversion = [0.03]
volatility = [0.02]

price = tff.models.hjm.swaption_price(
    expiries=expiries,
    fixed_leg_payment_times=fixed_leg_payment_times,
    fixed_leg_daycount_fractions=fixed_leg_daycount_fractions,
    fixed_leg_coupon=fixed_leg_coupon,
    reference_rate_fn=zero_rate_fn,
    notional=100.,
    num_hjm_factors=1,
    mean_reversion=mean_reversion,
    volatility=volatility,
    valuation_method=tff.model.ValuationMethod.MONTE_CARLO,
    num_samples=500000,
    time_step=0.1,
    random_type=tff.math.random.RandomType.STATELESS_ANTITHETIC,
    seed=[1, 2])
# Expected value: [[0.716]]

References:#

[1]: D. Brigo, F. Mercurio. Interest Rate Models-Theory and Practice. Second Edition. 2007. Section 6.7, page 237.

Args:#

  • expiries: A real Tensor of any shape and dtype. The time to expiration of the swaptions. The shape of this input along with the batch shape of the HJM model determines the number (and shape) of swaptions to be priced and the shape of the output. If the batch shape of HJM models is model_batch_shape, then the leading dimensions of expiries must be broadcastable to model_batch_shape. For example, if the rank of model_batch_shape is n and the rank of expiries.shape is m, then m>=n and the leading n dimensions of expiries.shape must be broadcastable to model_batch_shape.

  • fixed_leg_payment_times: A real Tensor of the same dtype as expiries. The payment times for each payment in the fixed leg. The shape of this input should be expiries.shape + [n] where n denotes the number of fixed payments in each leg. The fixed_leg_payment_times should be greater-than or equal-to the corresponding expiries.

  • fixed_leg_daycount_fractions: A real Tensor of the same dtype and compatible shape as fixed_leg_payment_times. The daycount fractions for each payment in the fixed leg.

  • fixed_leg_coupon: A real Tensor of the same dtype and compatible shape as fixed_leg_payment_times. The fixed rate for each payment in the fixed leg.

  • reference_rate_fn: A Python callable that accepts expiry time as a real Tensor and returns a Tensor of shape model_batch_shape + input_shape. Returns the continuously compounded zero rate at the present time for the input expiry time.

  • num_hjm_factors: A Python scalar which corresponds to the number of factors in the batch of HJM models to be used for pricing.

  • mean_reversion: A real positive Tensor of shape model_batch_shape + [num_hjm_factors]. Corresponds to the mean reversion rate of each factor in the batch.

  • volatility: A real positive Tensor of the same dtype and shape as mean_reversion or a callable with the following properties: (a) The callable should accept a scalar Tensor t and a Tensor r(t) of shape batch_shape + [num_samples] and returns a Tensor of shape compatible with batch_shape + [num_samples, dim]. The variable t stands for time and r(t) is the short rate at time t. The function returns instantaneous volatility sigma(t) = sigma(t, r(t)). When volatility is specified as a real Tensor, each factor is assumed to have a constant instantaneous volatility and the model is effectively a Gaussian HJM model. Corresponds to the instantaneous volatility of each factor.

  • times: An optional rank 1 Tensor of increasing positive real values. The times at which Monte Carlo simulations are performed. Relevant when swaption valuation is done using Monte Calro simulations. Default value: None in which case simulation times are computed based on either time_step or num_time_steps inputs.

  • time_step: Optional scalar real Tensor. Maximal distance between time grid points in Euler scheme. Relevant when Euler scheme is used for simulation. This input or num_time_steps are required when valuation method is Monte Carlo. Default Value: None.

  • num_time_steps: An optional scalar integer Tensor - a total number of time steps during Monte Carlo simulations. The maximal distance betwen points in grid is bounded by times[-1] / (num_time_steps - times.shape[0]). Either this or time_step should be supplied when the valuation method is Monte Carlo. Default value: None.

  • curve_times: An optional rank 1 Tensor of positive and increasing real values. The maturities at which spot discount curve is computed during simulations. Default value: None in which case curve_times is computed based on swaption expiries and fixed_leg_payments_times inputs.

  • corr_matrix: A Tensor of shape [num_hjm_factors, num_hjm_factors] and the same dtype as mean_reversion. Specifies the correlation between HJM factors. Default value: None in which case the factors are assumed to be uncorrelated.

  • notional: An optional Tensor of same dtype and compatible shape as strikesspecifying the notional amount for the underlying swaps. Default value: None in which case the notional is set to 1.

  • is_payer_swaption: A boolean Tensor of a shape compatible with expiries. Indicates whether the swaption is a payer (if True) or a receiver (if False) swaption. If not supplied, payer swaptions are assumed.

  • valuation_method: An enum of type ValuationMethod specifying the method to be used for swaption valuation. Currently the valuation is supported using MONTE_CARLO and FINITE_DIFFERENCE methods. Valuation using finite difference is only supported for Gaussian HJM models, i.e. for models with constant mean-reversion rate and time-dependent volatility. Default value: ValuationMethod.MONTE_CARLO, in which case swaption valuation is done using Monte Carlo simulations.

  • num_samples: Positive scalar int32 Tensor. The number of simulation paths during Monte-Carlo valuation. This input is ignored during analytic valuation. Default value: The default value is 1.

  • random_type: Enum value of RandomType. The type of (quasi)-random number generator to use to generate the simulation paths. This input is relevant only for Monte-Carlo valuation and ignored during analytic valuation. Default value: None which maps to the standard pseudo-random numbers.

  • seed: Seed for the random number generator. The seed is only relevant if random_type is one of [STATELESS, PSEUDO, HALTON_RANDOMIZED, PSEUDO_ANTITHETIC, STATELESS_ANTITHETIC]. For PSEUDO, PSEUDO_ANTITHETIC and HALTON_RANDOMIZED the seed should be an Python integer. For STATELESS and STATELESS_ANTITHETIC must be supplied as an integer Tensor of shape [2]. This input is relevant only for Monte-Carlo valuation and ignored during analytic valuation. Default value: None which means no seed is set.

  • skip: int32 0-d Tensor. The number of initial points of the Sobol or Halton sequence to skip. Used only when random_type is ‘SOBOL’, ‘HALTON’, or ‘HALTON_RANDOMIZED’, otherwise ignored. Default value: 0.

  • time_step_finite_difference: Optional scalar real Tensor. Spacing between time grid points in finite difference discretization. This input is only relevant for valuation using finite difference. Default value: None. If num_time_steps_finite_difference is also unspecified then a time_step corresponding to 100 discretization steps is used.

  • num_time_steps_finite_difference: Optional scalar real Tensor. Number of time grid points in finite difference discretization. This input is only relevant for valuation using finite difference. Default value: None. If time_step_finite_difference is also unspecified, then 100 time steps are used.

  • num_grid_points_finite_difference: Optional scalar real Tensor. Number of spatial grid points per dimension. Currently, we construct an uniform grid for spatial discretization. This input is only relevant for valuation using finite difference. Default value: 101.

  • dtype: The default dtype to use when converting values to Tensors. Default value: None which means that default dtypes inferred by TensorFlow are used.

  • name: Python string. The name to give to the ops created by this function. Default value: None which maps to the default name hjm_swaption_price.

Returns:#

A Tensor of real dtype and shape derived from model_batch_shape and expiries.shape containing the computed swaption prices. The shape of the output is as follows:

  • If the model_batch_shape is [], then the shape of the output is expiries.shape

  • Otherwise, the shape of the output is model_batch_shape + expiries.shape[model_batch_shape.rank:] For swaptions that have reset in the past (expiries<0), the function sets the corresponding option prices to 0.0.