我正在尝试编写为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)
...
对于这两个版本,我在params和run(a-variable)之后初始化:
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'
请帮我找到解决方法。我不知道我是否应该尝试循环S(我尝试过但失败了......),做一些数据类型技巧,以其他方式计算(如何?)或其他任何东西。
答案 0 :(得分:1)
根据我的理解,您可以使用1D案例,在np.linspace
中评估每个值的函数。现在,您正试图让它在2D中工作,并且仍在使用np.linspace
。
Numpy想要在元素方面做事。因此,当你给它两个不同大小的linspace
时,它不知道如何将元素从一个linspace
映射到另一个(s, t)
中的元素。但是如果你想想你想要什么,你应该意识到你想要评估s in S
t in tau
和#...................
#...................
#...................
#...................
#...................
####################
所有对组合的函数,所有这些对都是2D上的点网格。因此,您要使用的工具是np.meshgrid
。
以图形方式,你编写它的方式,你只是试图在#s评估你的表达。
tau
这就是numpy抱怨的原因 - 它说我不确定S
中的哪个值与tau
的值相对应。我想要做的是将S
的一个值与len(tau)==len(S)
的所有值匹配,或将它们配对,但只有np.meshgrid
才能看到。你真正想要的是在网格上的所有点评估你的表达,这就是linspaces
允许你做的事情。
Numpy的meshgrid起初可能很难理解如何使用。如果你给它喂两个向量(例如你的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)
...
),它将返回两个2D数组,指定这两个向量所跨越的每个网格点的坐标。我想你可能会喜欢这样的事情:
N = 300; % length of the the array
in = [1:1:N]; % index array
delta = 0.5;
M = 70;
R = N/M;
t(1:M-1) = 1./(in(1:M-1)*M);
t(M) = log(R/delta)/M;
t(M+1:N) = 0;
不再引发错误。