已修复:请参阅下面的更新代码。
这是我的第一次Cython尝试并且有一个有效的构建,但它不允许numpy数组(向量)作为输入,这是我的真正目的。它是Black模型(Black Scholes,欧洲期权定价没有股息)。它只接受长度为1的数组作为输入(如果我尝试用长度为2的数组计算它是错误的:TypeError: CyBlack() takes exactly 7 positional arguments (14 given)
,如果我传递长度为10的数组,(70 given)
等等。我不确定为什么我在Cython代码中定义了numpy数组。作为参考,你可以使用下面的代码编译它然后使用它:from CyBlack.CyBlack import CyBlack
然后调用CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput)
所以这里的代码(保存为CyBlack.pyx
文件进行编译):< / p>
from numpy cimport ndarray
cimport numpy as np
cimport cython
cdef extern from "math.h":
double exp(double)
double sqrt(double)
double log(double)
double erf(double)
cdef double std_norm_cdf(double x):
return 0.5*(1+erf(x/sqrt(2.0)))
@cython.boundscheck(False)
cpdef CyBlack(ndarray[np.float64_t, ndim=1] BlackPnL, ndarray[np.float64_t, ndim=1] Black_S, ndarray[np.float64_t, ndim=1] Black_Texpiry, ndarray[np.float64_t, ndim=1] Black_strike, ndarray [np.float64_t, ndim=1] Black_volatility, ndarray[np.float64_t, ndim=1] Black_IR, ndarray[np.int64_t, ndim=1] Black_callput):
cdef Py_ssize_t i
cdef Py_ssize_t N = BlackPnL.shape[0]
cdef double d1, d2
for i in range(N):
d1 = ((log(Black_S[i] / Black_strike[i]) + Black_Texpiry[i] * Black_volatility[i] **2 / 2)) / (Black_volatility[i] * sqrt(Black_Texpiry[i]))
d2 = d1 - Black_volatility[i] * sqrt(Black_Texpiry[i])
BlackPnL[i] = exp(-Black_IR[i] * Black_Texpiry[i]) * (Black_callput[i] * Black_S[i] * std_norm_cdf(Black_callput[i] * d1) - Black_callput[i] * Black_strike[i] * std_norm_cdf(Black_callput[i] * d2))
return BlackPnL
以下是setup.py
,因此其他人可以构建此类型:python setup.py build_ext --inplace
使用VS2015为Python 3.5 64位Windows构建。
from distutils.core import setup
from Cython.Build import cythonize
import numpy
extra_compile_args = ['/EHsc', '/openmp', '/favor:INTEL64']
setup(
ext_modules=cythonize("CyBlack.pyx"),
include_dirs=['.', numpy.get_include()],
extra_compile_args=extra_compile_args)
上面的代码在使用变量类型的修复程序后编译并运行(Black_callput实际上是int64
),你必须按原样传递numpy数组(没有星号)并且它可以正常工作。
答案 0 :(得分:3)
这里有两个问题:
TypeError: CyBlack() takes exactly 7 positional arguments (14 given)
这是因为您使用*
(“splat”)运算符解压缩输入数组。你需要将它们作为7个单独的参数传递给它们。
ValueError: Buffer dtype mismatch, expected 'float64_t' but got 'long long'
:
此错误告诉您其中一个输入数组的C类型为long long
(64位整数),而不是输入类型声明中指定的float64_t
。您需要将所有输入数组转换为np.float64
。