WhalleyWilmott

class pfhedge.nn.WhalleyWilmott(derivative, a=1.0)[source]

Creates a module for Whalley-Wilmott’s hedging strategy.

The forward method returns the next hedge ratio.

This is the no-transaction band strategy that is optimal under the premises of asymptotically small transaction cost, European option, and exponential utility. The half-width of the no-transaction band is given by

\[w = \left( \frac{3 c \Gamma^2 S}{2 a} \right)^{1 / 3} \,,\]

where \(c\) is the transaction cost rate, \(\Gamma\) is the gamma of the derivative, \(S\) is the spot price of the underlying instrument, and \(a\) is the risk-aversion coefficient of the exponential utility.

Note

A backward computation for this module generates nan if the \(\Gamma\) of the derivative is too small. This is because the output is proportional to \(\Gamma^{2 / 3}\) of which gradient diverges for \(\Gamma \to 0\). A dtype with higher precision may alleviate this problem.

References

  • Davis, M.H., Panas, V.G. and Zariphopoulou, T., 1993. European option pricing with transaction costs. SIAM Journal on Control and Optimization, 31(2), pp.470-493.

  • Whalley, A.E. and Wilmott, P., An asymptotic analysis of an optimal hedging model for option pricing with transaction costs. Mathematical Finance, 1997, 7, 307–324.

Parameters
Shape:
  • Input: \((N, *, H_{\text{in}})\) where \(*\) means any number of additional dimensions and \(H_{\text{in}}\) is the number of input features. See inputs() for the names of input features.

  • Output: \((N, *, 1)\).

Examples

An example for pfhedge.instruments.EuropeanOption.

>>> import torch
>>> from pfhedge.nn import WhalleyWilmott
>>> from pfhedge.instruments import BrownianStock
>>> from pfhedge.instruments import EuropeanOption
>>> derivative = EuropeanOption(BrownianStock(cost=1e-5))
>>>
>>> m = WhalleyWilmott(derivative)
>>> m.inputs()
['log_moneyness', 'time_to_maturity', 'volatility', 'prev_hedge']
>>> input = torch.tensor([
...     [-0.05, 0.1, 0.2, 0.5],
...     [-0.01, 0.1, 0.2, 0.5],
...     [ 0.00, 0.1, 0.2, 0.5],
...     [ 0.01, 0.1, 0.2, 0.5],
...     [ 0.05, 0.1, 0.2, 0.5]])
>>> m(input)
tensor([[0.2946],
        [0.5000],
        [0.5000],
        [0.5000],
        [0.7284]])

An example for pfhedge.instruments.EuropeanOption without cost.

>>> derivative = EuropeanOption(BrownianStock())
>>> m = WhalleyWilmott(derivative)
>>> m.inputs()
['log_moneyness', 'time_to_maturity', 'volatility', 'prev_hedge']
>>> input = torch.tensor([
...     [-0.05, 0.1, 0.2, 0.5],
...     [-0.01, 0.1, 0.2, 0.5],
...     [ 0.00, 0.1, 0.2, 0.5],
...     [ 0.01, 0.1, 0.2, 0.5],
...     [ 0.05, 0.1, 0.2, 0.5]])
>>> m(input)
tensor([[0.2239],
        [0.4497],
        [0.5126],
        [0.5752],
        [0.7945]])
inputs()[source]

Returns the names of input features.

Returns

list[str]

width(input)[source]

Returns half-width of the no-transaction band.

Parameters

input (torch.Tensor) – The input tensor.

Shape:
  • Input: \((N, *, H_{\text{in}} - 1)\) where \(*\) means any number of additional dimensions and \(H_{\text{in}}\) is the number of input features. See inputs() for the names of input features.

  • Output: \((N, *, 1)\)

Returns

torch.Tensor