我正试图通过定义函数(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)

我不知道它是来自函数定义(第一部分)还是来自参数定义(第二个脚本),以及如何解决.

推荐答案

错误是因为B.shape[1]M,而V[1:-1, n-1].shape[0]M-1,两者不匹配,因此我猜测错误是由于函数定义造成的.

正在改变

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)

A = np.diag(-alpha[2:M], -1) + np.diag(1-beta[1:M]) + np.diag(-gamma[1:M-1], 1)
B = np.diag(alpha[2:M], -1) + np.diag(1+beta[1:M]) + np.diag(gamma[1:M-1], 1)

(深受this个非常类似的实现的启发)go 掉了错误消息并运行

cn_price = crank_nicolson(S0, K, r, sigma, T, Smin, Smax, M, N)
bs_price = bs_call(S0, K, r, sigma, T)
print(cn_price, bs_price)

(带有其他未更改的代码)打印

10.3201002605872 10.450583572185565

Note that I am not familiar with the Crank-Nicolson method and can therefore only hope that the proximity of those values indicates a fix (i.e. correct adjustment) indeed, as opposed 至 a mere ridding of the error message.

Python相关问答推荐

比较两个二元组列表,NP.isin

Pandas实际上如何对基于自定义的索引(integer和非integer)执行索引

如何使用pandasDataFrames和scipy高度优化相关性计算

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

按列分区,按另一列排序

为什么符号没有按顺序添加?

Vectorize多个头寸的止盈/止盈回溯测试pythonpandas

按顺序合并2个词典列表

如何获取TFIDF Transformer中的值?

当从Docker的--env-file参数读取Python中的环境变量时,每个\n都会添加一个\'.如何没有额外的?

在极性中创建条件累积和

Scrapy和Great Expectations(great_expectations)—不合作

如何使用OpenGL使球体遵循Python中的八样路径?

剪切间隔以添加特定日期

如何获取Python synsets列表的第一个内容?

Python类型提示:对于一个可以迭代的变量,我应该使用什么?

多个矩阵的张量积

比较两个有条件的数据帧并删除所有不合格的数据帧

用由数据帧的相应元素形成的列表的函数来替换列的行中的值

正在try 让Python读取特定的CSV文件