4

我正在尝试编写函数,为 BS 模型计算金融希腊语
我从这样的事情开始:

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-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,) 

我用谷歌搜索了一下,看起来 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(我尝试过但失败了......),做一些数据类型技巧,以其他方式计算(如何?)或其他任何方式。

4

1 回答 1

1

据我所知,您可以在一维情况下使用它,在 a 中的每个值处评估您的函数np.linspace。现在你正试图让它在 2D 中工作并且仍在使用np.linspace.

Numpy 想要在元素方面工作。因此,当您给它两个linspace不同大小的 s 时,它不知道如何将元素从一个映射到另一个linspace元素。但是,如果您考虑一下您想要什么,您应该意识到您希望在所有对组合中评估您的函数,(s, t)其中s in St in tau,并且所有这些对都是二维网格上的点。因此,您要使用的工具是np.meshgrid.

以图形方式,您编写它的方式是尝试仅在#s 处评估您的表达式。

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

这就是 numpy 抱怨的原因——它是说我不确定 in 中tau的哪个值对应于S. 我想做的是将一个值tau与 all of匹配S或将它们配对,但这只会发生len(tau)==len(S)在你看到的情况下。您真正想要的是在该网格上的所有点上评估您的表达式,这就是np.meshgrid您可以做的。

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

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)
    ...

这不再引发错误。

于 2015-10-12T20:52:35.283 回答