1

我正在使用 Montecarlo 方法为通用看涨期权计算这些衍生品。我对这种组合导数感兴趣(关于 S 和 Sigma)。使用算法微分执行此操作,我得到一个可以在页面末尾看到的错误。什么是可能的解决方案?只是为了解释有关代码的内容,我将在下面的代码中附上用于计算“X”的公式:

在此处输入图像描述

from jax import jit, grad, vmap
import jax.numpy as jnp
from jax import random
Underlying_asset = jnp.linspace(1.1,1.4,100)
volatilities = jnp.linspace(0.5,0.6,100)
def second_derivative_mc(S,vol):
    N = 100
    j,T,q,r,k = 10000,1.,0,0,1.
    S0 = jnp.array([S]).T #(Nx1) vector underlying asset
    C = jnp.identity(N)*vol    #matrix of volatilities with 0 outside diagonal 
    e = jnp.array([jnp.full(j,1.)])#(1xj) vector of "1"
    Rand = np.random.RandomState()
    Rand.seed(10)
    U= Rand.normal(0,1,(N,j)) #Random number for Brownian Motion
    sigma2 = jnp.array([vol**2]).T #Vector of variance Nx1

    first = jnp.dot(sigma2,e) #First part equation
    second = jnp.dot(C,U)     #Second part equation

    X = -0.5*first+jnp.sqrt(T)*second

    St = jnp.exp(X)*S0

    P = jnp.maximum(St-k,0)
    payoff = jnp.average(P, axis=-1)*jnp.exp(-q*T)
    return payoff 


greek = vmap(grad(grad(second_derivative_mc, argnums=1), argnums=0)(Underlying_asset,volatilities)

这是错误消息:

> UnfilteredStackTrace                      Traceback (most recent call
> last) <ipython-input-78-0cc1da97ae0c> in <module>()
>      25 
> ---> 26 greek = vmap(grad(grad(second_derivative_mc, argnums=1), argnums=0))(Underlying_asset,volatilities)
> 
> 18 frames UnfilteredStackTrace: TypeError: Gradient only defined for
> scalar-output functions. Output had shape: (100,).

下面的堆栈跟踪不包括 JAX 内部帧。前面是发生的原始异常,未经修改。


上述异常是以下异常的直接原因:

> TypeError                                 Traceback (most recent call
> last) /usr/local/lib/python3.7/dist-packages/jax/_src/api.py in
> _check_scalar(x)
>     894     if isinstance(aval, ShapedArray):
>     895       if aval.shape != ():
> --> 896         raise TypeError(msg(f"had shape: {aval.shape}"))
>     897     else:
>     898       raise TypeError(msg(f"had abstract value {aval}"))

> TypeError: Gradient only defined for scalar-output functions. Output had shape: (100,).
4

1 回答 1

1

如错误消息所示,只能为返回标量的函数计算梯度。您的函数返回一个向量:

print(len(second_derivative_mc(1.1, 0.5)))
# 100

对于向量值函数,您可以计算雅可比(类似于多维梯度)。这是你的想法吗?

from jax import jacobian
greek = vmap(jacobian(jacobian(second_derivative_mc, argnums=1), argnums=0))(Underlying_asset,volatilities)

此外,这不是您询问的内容,但即使您解决了问题中的问题,上述功能也可能无法按您的预期工作。NumpyRandomState对象是有状态的,因此通常无法与 , , 等需要无副作用代码的 jax 转换一起正常工作gradjitvmap参阅JAX 中的有状态计算)。您可以尝试jax.random改用;有关更多信息,请参阅JAX:随机数

于 2021-08-25T13:35:09.430 回答