tf_quant_finance.models.hull_white.cap_floor_price

Last updated: 2023-03-16.

tf_quant_finance.models.hull_white.cap_floor_price#

View source

Calculates the prices of interest rate Caps/Floors using Hull-White model.

tf_quant_finance.models.hull_white.cap_floor_price(
    *, strikes, expiries, maturities, daycount_fractions, reference_rate_fn,
    mean_reversion, volatility, notional=1.0, is_cap=True,
    use_analytic_pricing=True, num_samples=1, random_type=None, seed=None, skip=0,
    time_step=None, dtype=None, name=None
)

An interest Cap (or Floor) is a portfolio of call (or put) options where the underlying for the individual options are successive forward rates. The individual options comprising a Cap are called Caplets and the corresponding options comprising a Floor are called Floorlets. For example, a caplet on forward rate F(T_i, T_{i+1}) has the following payoff at time T_{i_1}:


 caplet payoff = tau_i * max[F(T_i, T_{i+1}) - X, 0]

where where X is the strake rate and tau_i is the daycount fraction. The caplet payoff (at T_{i+1}) can be expressed as the following at T_i:


caplet_payoff = (1.0 + tau_i * X) *
                max[1.0 / (1 + tau_i * X) - P(T_i, T_{t+1}), 0]

where P(T_i, T_{i+1}) is the price at T_i of a zero coupon bond with maturity `T_{i+1}. Thus, a caplet can be priced as a put option on zero coupon bond [1].

References#

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

Example#

The example shows how value a batch containing spot starting 1-year and 2-year Caps and with quarterly frequency.

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

dtype = tf.float64

reference_rate_fn = lambda x: 0.01 * tf.ones_like(x, dtype=dtype)
expiries = np.array([[0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0],
                     [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75]])
maturities = np.array([[0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0],
                     [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]])
strikes = 0.01 * np.ones_like(expiries)
daycount_fractions = np.array([[0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0],
                     [0.0, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25]])
price = tff.models.hull_white.cap_floor_price(
    strikes=strikes,
    expiries=expiries,
    maturities=maturities,
    daycount_fractions=daycount_fractions,
    notional=1.0e6,
    mean_reversion=[0.03],
    volatility=[0.02],
    reference_rate_fn=reference_rate_fn,
    use_analytic_pricing=True,
    dtype=dtype)
# Expected value: [[0.4072088281493774], [1.3031872853339002]]

Args:#

  • strikes: A real Tensor of any shape and dtype. The strike rate of the caplets or floorlets. The shape of this input determines the number (and shape) of the options to be priced and the shape of the output. For an N-dimensional input Tensor, the first N-1 dimensions correspond to the batch dimension, i.e., the distinct caps and floors and the last dimension correspond to the caplets or floorlets contained with an instrument.

  • expiries: A real Tensor of the same dtype and compatible shape as strikes. The reset time of each caplet (or floorlet).

  • maturities: A real Tensor of the same dtype and compatible shape as strikes. The maturity time of each caplet (or floorlet) and also the time at which payment is made.

  • daycount_fractions: A real Tensor of the same dtype and compatible shape as strikes. The daycount fractions associated with the underlying forward rates.

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

  • mean_reversion: A real positive scalar Tensor or a Python callable. The callable can be one of the following: (a) A left-continuous piecewise constant object (e.g., tff.math.piecewise.PiecewiseConstantFunc) that has a property is_piecewise_constant set to True. In this case the object should have a method jump_locations(self) that returns a Tensor of shape [num_jumps]. The return value of mean_reversion(t) should return a Tensor of shape t.shape, t is a rank 1 Tensor of the same dtype as the output. See example in the class docstring. (b) A callable that accepts scalars (stands for time t) and returns a scalar Tensor of the same dtype as strikes. Corresponds to the mean reversion rate.

  • volatility: A real positive Tensor of the same dtype as mean_reversion or a callable with the same specs as above. Corresponds to the long run price variance.

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

  • is_cap: A boolean Tensor of a shape compatible with strikes. Indicates whether the option is a Cap (if True) or a Floor (if False). If not supplied, Caps are assumed.

  • use_analytic_pricing: A Python boolean specifying if analytic valuation should be performed. Analytic valuation is only supported for constant mean_reversion and piecewise constant volatility. If the input is False, then valuation using Monte-Carlo simulations is performed.

  • 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: Scalar real Tensor. Maximal distance between time grid points in Euler scheme. Relevant when Euler scheme is used for simulation. This input is ignored during analytic valuation. Default value: None.

  • 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 class. Default value: None which maps to the default name hw_cap_floor_price.

Returns:#

A Tensor of real dtype and shape strikes.shape[:-1] containing the computed option prices. For caplets that have reset in the past (expiries<0), the function sets the corresponding caplet prices to 0.0.