使用Numpy数组,得到一个E

2024-09-24 02:22:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试编写函数,用于计算B-S模型的financial greeks
我是这样开始的:

def greeks_vanilla(S, K, r, q, t, T, sigma):
    import numpy as np
    from scipy.stats import norm

    tau = np.linspace(t, T, num = T)
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
    d2 = d1 - sigma*np.sqrt(tau)

    delta_call = np.exp(-q*tau) * norm.cdf(d1)
    delta_put = -np.exp(-q*tau) * norm.cdf(-d1)
    ...

    return {'d1':d1, 'd2': d2, 'delta_call': delta_call, 'delta_put': delta_put, ...}

“…”意味着,有更多的希腊人正在计算,但这在这里并不重要。
它工作得很好,我有合理的价值观,很好的情节等;然而,我的老师告诉我,他想看到这些价值观不仅与时间(x轴上的tau),而且与S(x轴上的S-股价)。换言之,我必须计算tau和S变化的希腊人。你知道吗

我试过以下方法:

def greeks_vanilla(S, K, r, q, t, T, sigma):
    import numpy as np
    from scipy.stats import norm

    S = np.linspace(1, S, num = S)

    tau = np.linspace(t, T, num = T)
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
    d2 = d1 - sigma*np.sqrt(tau)

    delta_call = np.exp(-q*tau) * norm.cdf(d1)
    delta_put = -np.exp(-q*tau) * norm.cdf(-d1)
    ...

对于这两个版本,我初始化了以下参数并运行(a变量):

S = 30.0 #Stock price
K = 50.0 #Strike price
r = 0.05 #Risk-free rate
q = 0.01 #also called delta, annual dividend yield
t = 1.0
T = 100.0
sigma = 0.15
a = greeks_vanilla(S, K, r, q, t, T, sigma)

在第一种情况下,它可以正常工作,但是当我想改变S(第二个函数)时,我得到以下错误:

     File "greeks.py", line 11, in greeks_vanilla
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
ValueError: operands could not be broadcast together with shapes (30,) (100,) 

我在google上搜索了一下,发现Numpy库和它的数据类型(数组)似乎有些东西。我不是很熟练或经验丰富的程序员(仍在学习),所以我无法自己解决问题。
看起来它现在只能在S==100(S=T)时工作,但这不是理想的解决方案。
我试过:

S = list(S)

但它只输出:

File "greeks.py", line 11, in greeks_vanilla
    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*tau ) / (sigma * np.sqrt(tau))
TypeError: unsupported operand type(s) for /: 'list' and 'float'

请帮我找到有效的解决办法。我不知道我是否应该尝试循环(我尝试过,但失败了…),做一些数据类型的技巧,用其他方法计算(怎么做?)或者别的什么。你知道吗


Tags: importlognormputnpsqrtcallsigma
1条回答
网友
1楼 · 发布于 2024-09-24 02:22:45

据我所知,这适用于1D情况,在np.linspace中的每个值上评估函数。现在您正试图让它在2D中工作,并且仍在使用np.linspace。你知道吗

Numpy想在元素方面做一些事情。所以当你给它两个大小不同的linspace时,它不知道如何将一个linspace中的元素映射到另一个linspace中的元素。但是如果你想知道你想要什么,你应该意识到你想要在所有的对组合(s, t)中计算你的函数,其中s in St in tau,所有这些对都是二维网格上的点。因此,您要使用的工具是^{}。你知道吗

从图形上看,你写的方式,你试图评估你的表达只在#s

#...................
#...................
#...................
#...................
#...................
####################

这就是为什么numpy抱怨说我不确定tau中的哪个值对应于S的哪个值。我想做的是要么将tau的一个值与所有S匹配,要么将它们配对,但正如您所看到的,这只发生在len(tau)==len(S)上。您真正想要的是在网格上的所有点上计算表达式,这就是np.meshgrid允许您做的。你知道吗

Numpy的meshgrid一开始就很难理解如何使用。如果你给它输入两个向量(例如你的linspaces),它将返回两个2D数组,指定这两个向量所跨越的每个网格点的坐标。我想你可能会想做这样的事情:

def greeks_vanilla(S, K, r, q, t, T, sigma):
    import numpy as np
    from scipy.stats import norm

    v1 = np.linspace(1, S, num = S)
    v2 = np.linspace(t, T, num = T)

    S, TAU = np.meshgrid(v1, v2)

    d1 = ( np.log(S/K) + (r - q + sigma**2 /2)*TAU ) / (sigma * np.sqrt(TAU))
    d2 = d1 - sigma*np.sqrt(TAU)

    delta_call = np.exp(-q*TAU) * norm.cdf(d1)
    delta_put = -np.exp(-q*TAU) * norm.cdf(-d1)
    ...

不会再引起错误了。你知道吗

相关问题 更多 >