Reputation: 2822
ORIGINAL ERROR FOUND -> from CyBlack.CyBlack import CyBlack
then pass *numpy_value
as inputs. A new issue has arisen so creating a new post for that.
Cython program with numpy arrays does not allow vectorized inputs (only accepts length 1 arrays), how to fix?
I am new to Cython and tried converting the Black (Black Scholes without a stock dividend) over from Python to Cython. After getting it to compile, it doesn't let me actually use the function. I'm sure someone with more experience can look at this easily and figure out why. The error I get after compiling and importing the function from CyBlack import CyBlack
and calling CyBlack(BlackPnL, Black_S, Black_Texpiry, Black_strike, Black_volatility, Black_IR, Black_callput)
is TypeError: 'module' object is not callable
: So here's the code:
from numpy cimport ndarray
cimport numpy as np
cimport cython
cdef extern from "math.h":
double exp(double)
double sqrt(double)
double pow(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)
cdef 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.float64_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
Thanks for any help here! I can post python fake data if you need something to test off of - although just calling it with any data will expose the error... Something points me to the variables not being exposed to Python from the C code.
Adding my setup.py
here so others can build this typing: python setup.py build_ext --inplace
built with VS2015 for Python 3.5 64bit Windows.
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize("CyBlack.pyx"), include_dirs =["C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//include", "C://Program Files (x86)//Windows Kits//10//Include//10.0.1.0240.0//ucrt", "C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//lib//amd64", "C://Anaconda3//Lib//site-packages//numpy//core//include", "C://Program Files (x86)//Microsoft Visual Studio 14.0//VC//lib//amd64"])
Upvotes: 1
Views: 1272
Reputation: 8689
I managed to get (something like it) working in the following way:
C:/dev/tmp/CyBlack/
__init__.py
setup.py
CyBlack.pyx
Where CyBlack.pyx
is just like yours, except with CyBlack
function being cpdef
'd. setup.py
contains:
from distutils.core import setup
import numpy
from Cython.Build import cythonize
extra_compile_args = ['/EHsc', '/openmp', '/favor:INTEL64']
setup(
ext_modules=cythonize("CyBlack.pyx"),
include_dirs=['.', numpy.get_include()],
extra_compile_args=extra_compile_args
)
Running then:
C:\dev\tmp\CyBlack> python .\setup.py build_ext --compiler=msvc --inplace
Will produce C:/dev/tmp/CyBlack/CyBlack.pyd
, and I then managed to run the code from Python:
>>> from sys import path
>>> path.insert(0, "C:/dev/tmp")
>>> from CyBlack.CyBlack import CyBlack
>>> CyBlack(*[np.array([1.0]) for _ in xrange(7)]) # I'm too lazy to put proper values here...
array([ 0.14087021])
This was done with Python 2.7, and overall setup might be slightly different, but hopefully, that might help you getting a minimum working example and trace back how to make yours run correctly.
Upvotes: 2
Reputation: 714
Instead of
from CyBlack import CyBlack
Why don't you just do
import CyBlack
?
Upvotes: -2