使用 Numpy 数组,出现错误
Working with Numpy arrays, getting an Error
我正在尝试编写函数,为 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(S - 股票价格,在 x 轴上)。换句话说,我必须为 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,)
我用谷歌搜索了一下,看起来 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'
请帮我找到解决这个问题的方法。我不知道我是否应该尝试循环遍历 S(我尝试过但失败了......),做一些数据类型技巧,以其他方式计算(如何?)或其他任何方式。
据我所知,您在一维情况下使用了此方法,在 np.linspace
中的每个值处评估了您的函数。现在您正试图让它在 2D 中工作并且仍在使用 np.linspace
。
Numpy 想要处理元素方面的事情。因此,当您给它两个不同大小的 linspace
时,它不知道如何将元素从一个 linspace
映射到另一个 linspace
中的元素。但是如果你考虑一下你想要什么,你应该意识到你想要在所有对组合 (s, t)
中评估你的函数,其中 s in S
和 t in tau
,并且所有这些对都是 2D 上的点网格。所以您要使用的工具是 np.meshgrid
.
从图形上看,按照您编写它的方式,您试图仅在 #s 处计算表达式。
#...................
#...................
#...................
#...................
#...................
####################
这就是 numpy 抱怨的原因——它说我不确定 tau
中的哪个值与 S
中的哪个值相对应。我想做的是将 tau
的一个值与所有 S
匹配,或者将它们配对,但如您所见,这只会发生在 len(tau)==len(S)
上。你真正想要的是在该网格上的所有点上评估你的表达式,这就是 np.meshgrid
会让你做的。
Numpy 的 meshgrid 一开始可能很难理解如何使用。如果你给它两个向量(例如你的 linspaces
),它将 return 两个二维数组,指定这两个向量跨越的每个网格点的坐标。我想您可能想做类似的事情:
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)
...
这不再引发错误。
我正在尝试编写函数,为 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(S - 股票价格,在 x 轴上)。换句话说,我必须为 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,)
我用谷歌搜索了一下,看起来 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'
请帮我找到解决这个问题的方法。我不知道我是否应该尝试循环遍历 S(我尝试过但失败了......),做一些数据类型技巧,以其他方式计算(如何?)或其他任何方式。
据我所知,您在一维情况下使用了此方法,在 np.linspace
中的每个值处评估了您的函数。现在您正试图让它在 2D 中工作并且仍在使用 np.linspace
。
Numpy 想要处理元素方面的事情。因此,当您给它两个不同大小的 linspace
时,它不知道如何将元素从一个 linspace
映射到另一个 linspace
中的元素。但是如果你考虑一下你想要什么,你应该意识到你想要在所有对组合 (s, t)
中评估你的函数,其中 s in S
和 t in tau
,并且所有这些对都是 2D 上的点网格。所以您要使用的工具是 np.meshgrid
.
从图形上看,按照您编写它的方式,您试图仅在 #s 处计算表达式。
#...................
#...................
#...................
#...................
#...................
####################
这就是 numpy 抱怨的原因——它说我不确定 tau
中的哪个值与 S
中的哪个值相对应。我想做的是将 tau
的一个值与所有 S
匹配,或者将它们配对,但如您所见,这只会发生在 len(tau)==len(S)
上。你真正想要的是在该网格上的所有点上评估你的表达式,这就是 np.meshgrid
会让你做的。
Numpy 的 meshgrid 一开始可能很难理解如何使用。如果你给它两个向量(例如你的 linspaces
),它将 return 两个二维数组,指定这两个向量跨越的每个网格点的坐标。我想您可能想做类似的事情:
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)
...
这不再引发错误。