code: def bond_option_price(
      *,
      strikes: types.RealTensor,
      expiries: types.RealTensor,
      maturities: types.RealTensor,
      discount_rate_fn: Callable[..., types.RealTensor],
      mean_reversion: Union[
          types.RealTensor, Callable[..., types.RealTensor]
      ],
      volatility: Union[
          types.RealTensor, Callable[..., types.RealTensor]
      ],
      is_call_options: types.BoolTensor = True,
      use_analytic_pricing: bool = True,
      num_samples: types.IntTensor = 1,
      random_type: random.RandomType = None,
      seed: types.IntTensor = None,
      skip: types.IntTensor = 0,
      time_step: types.RealTensor = None,
      dtype: tf.DType = None,
      name: str = None,
  ) -> types.RealTensor:
      """Calculates European bond option prices using the Hull-White model.
  
      Bond options are fixed income securities which give the holder a right to
      exchange at a future date (the option expiry) a zero coupon bond for a fixed
      price (the strike of the option). The maturity date of the bond is after the
      the expiry of the option. If `P(t,T)` denotes the price at time `t` of a zero
      coupon bond with maturity `T`, then the payoff from the option at option
      expiry, `T0`, is given by:
  
      ```None
      payoff = max(P(T0, T) - X, 0)
      ```
      where `X` is the strike price of the option.
  
      #### Example
  
      ````python
      import numpy as np
      import tensorflow.compat.v2 as tf
      import tf_quant_finance as tff
  
      dtype = tf.float64
  
      discount_rate_fn = lambda x: 0.01 * tf.ones_like(x, dtype=dtype)
      expiries = np.array([1.0])
      maturities = np.array([5.0])
      strikes = np.exp(-0.01 * maturities) / np.exp(-0.01 * expiries)
      price = tff.models.hull_white.bond_option_price(
          strikes=strikes,
          expiries=expiries,
          maturities=maturities,
          dim=1,
          mean_reversion=[0.03],
          volatility=[0.02],
          discount_rate_fn=discount_rate_fn,
          use_analytic_pricing=True,
          dtype=dtype)
      # Expected value: [[0.02817777]]
      ````
  
      Args:
        strikes: A real `Tensor` of any shape and dtype. The strike price of the
          options. The shape of this input determines the number (and shape) of the
          options to be priced and the output.
        expiries: A real `Tensor` of the same dtype and compatible shape as
          `strikes`.  The time to expiry of each bond option.
        maturities: A real `Tensor` of the same dtype and compatible shape as
          `strikes`.  The time to maturity of the underlying zero coupon bonds.
        discount_rate_fn: A Python callable that accepts expiry time as a real
          `Tensor` and returns a `Tensor` of the same shape as the input Computes
          the zero coupon bond yield 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.
        is_call_options: A boolean `Tensor` of a shape compatible with
          `strikes`. Indicates whether the option is a call (if True) or a put
          (if False). If not supplied, call options 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 `Tensor`s.
          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_bond_option_price`.
  
      Returns:
        A `Tensor` of real dtype and shape  `strikes.shape` containing the
        computed option prices.
      """
      name = name or "hw_bond_option_price"
      if dtype is None:
          dtype = tf.convert_to_tensor([0.0]).dtype
      with tf.name_scope(name):
          strikes = tf.convert_to_tensor(
              strikes, dtype=dtype, name="strikes"
          )
          expiries = tf.convert_to_tensor(
              expiries, dtype=dtype, name="expiries"
          )
          maturities = tf.convert_to_tensor(
              maturities, dtype=dtype, name="maturities"
          )
          is_call_options = tf.convert_to_tensor(
              is_call_options, dtype=tf.bool, name="is_call_options"
          )
  
          model = one_factor.HullWhiteModel1F(
              mean_reversion=mean_reversion,
              volatility=volatility,
              initial_discount_rate_fn=discount_rate_fn,
              dtype=dtype,
          )
  
          if use_analytic_pricing:
              return _analytic_valuation(
                  discount_rate_fn,
                  model,
                  strikes,
                  expiries,
                  maturities,
                  is_call_options,
              )
  
          if time_step is None:
              raise ValueError(
                  "`time_step` must be provided for simulation "
                  "based bond option valuation."
              )
  
          def sample_discount_curve_paths_fn(
              times, curve_times, num_samples
          ):
              return model.sample_discount_curve_paths(
                  times=times,
                  curve_times=curve_times,
                  num_samples=num_samples,
                  random_type=random_type,
                  seed=seed,
                  skip=skip,
              )
  
          # Shape batch_shape + [1]
          prices = (
              zero_coupon_bond_option_util.options_price_from_samples(
                  strikes,
                  expiries,
                  maturities,
                  is_call_options,
                  sample_discount_curve_paths_fn,
                  num_samples,
                  time_step,
                  dtype=dtype,
              )
          )
          # Shape batch_shape
          return tf.squeeze(prices, axis=-1)
  
file_path: tf-quant-finance/tf_quant_finance/models/hull_white/zero_coupon_bond_option.py
imports: from typing import Callable, Union
  import numpy
  import tensorflow.compat.v2
  from tf_quant_finance import types
  from tf_quant_finance import utils
  from tf_quant_finance.math import random
  from tf_quant_finance.models import utils
  from tf_quant_finance.models.hjm import zero_coupon_bond_option_util
  from tf_quant_finance.models.hull_white import one_factor
label_desc: Use image node_id 2 for calling a global function with example usage: bond_option_price() and returns: tf, _analytic_valuation, model