我试图通过定义函数(Black-Scholes和Crank-Nicolson)并比较它们来模拟期权定价方案。带边界条件的Crank-Nicolson格式的实现如下(我包括了复制的完整代码):
import numpy as np
from scipy.stats import norm
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
def bs_call(S, K, r, sigma, T):
d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
d2 = d1 - sigma*np.sqrt(T)
return S*norm.cdf(d1) - K*np.exp(-r*T)*norm.cdf(d2)
def crank_nicolson(S0, K, r, sigma, T, Smin, Smax, M, N):
# Initialization
dt = T/N
ds = (Smax - Smin)/M
S = np.linspace(Smin, Smax, M+1)
tau = np.linspace(0, T, N+1)
V = np.zeros((M+1, N+1))
# Boundary conditions
V[:, 0] = np.maximum(S-K, 0)
V[0, :] = 0
V[-1, :] = Smax-K*np.exp(-r*tau)
# Tridiagonal matrix for the implicit step
alpha = 0.25*dt*(sigma**2*S**2/ds**2 - r*S/ds)
beta = -dt*0.5*(sigma**2*S**2/ds**2 + r)
gamma = 0.25*dt*(sigma**2*S**2/ds**2 + r*S/ds)
A = np.diag(alpha[2:], -1) + np.diag(1+beta[1:]) + np.diag(gamma[:-2], 1)
B = np.diag(-alpha[2:], -1) + np.diag(1-beta[1:]) + np.diag(-gamma[:-2], 1)
# Time loop
for n in range(1, N+1):
b = np.dot(B, V[1:-1, n-1])
b[0] -= alpha[1]*V[0, n]
b[-1] -= gamma[-2]*V[-1, n]
V[1:-1, n] = np.linalg.solve(A, b)
# Interpolation for S0
i = int(round((S0-Smin)/ds))
if i == M+1:
i = M
elif i == 0:
i = 1
a = (V[i+1, -1]-V[i, -1])/ds
b = (V[i+1, -1]-2*V[i, -1]+V[i-1, -1])/ds**2
return V[i, -1] + a*(S0-S[i]) + 0.5*b*(S0-S[i])**2
字符串
到这里为止一切顺利。然后,我运行一个示例,如下所示(完整代码也包括复制):
# Example usage
S0 = 100
K = 100
r = 0.05
sigma = 0.2
T = 1
Smin = 0
Smax = 200
M = 200
N = 1000
option_price = crank_nicolson(S0, K, r, sigma, T, Smin, Smax, M, N)
型
但是,我在这里得到了一个错误,并显示以下消息:
ValueError: shapes (200,200) and (199,) not aligned: 200 (dim 1) != 199 (dim 0)
型
我不知道它是来自函数定义(第一部分)还是来自参数定义(第二个脚本)以及如何解决。
1条答案
按热度按时间2wnc66cl1#
这个错误是因为
B.shape[1]
是M
,而V[1:-1, n-1].shape[0]
是M-1
,它们不匹配,因此我猜这个错误是由于函数定义造成的。变化
字符串
至
型
(受到this非常相似的实现的“启发”)摆脱了错误消息并运行
型
(with否则代码不变)打印
型
请注意,我不熟悉Crank-Nicolson方法,因此只能希望这些值的接近度指示修复(即正确的调整),而不是仅仅消 debugging 误消息。