ta-lib-python
ta-lib-python copied to clipboard
Calling functions from within Numba
Is this doable? I tried using get_cython_function_address
as stated in Numba docs but it fails because module 'talib._ta_lib' has no attribute __pyx_capi__
.
It might be possible, there is an issue it looks like with keyword arguments:
talib/_stream.pxi:5222:22: Function with optional arguments may not be declared public or api
We might need to make these changes:
- make all the
_func.pxi
indicator functionscpdef api
. - change how we wrap them for pandas support, so you can access the C functions
- fix the issue with the optional arguments, so you can build the
.so
in a way thatnumba
can lookup
I didn't have time to work through this right now, but if you'd like to help, that would be cool.
I’m more experienced with Numba than with Cython to be honest, but I can try to apply those changes locally to see if this is doable.
I’m the creator behind vectorbt and would love to integrate your library more tightly to run indicators on two-dimensional data without slow Pythonic loops, but also to use talib functions within Numba without falling back to object mode; for example, to build completely new indicators without losing any performance.
@polakowo is there maybe any progress implementing talib with numba in vectorbt? Thank you
@smjure I didn’t have time to experiment with this, unfortunately, partly because the performance is already satisfactory, but I’m still interested in this.
@polakowo any chance for you to look into this ? I've tried and unfortunately simple change "cdef" not "cdef api" didn't work.
some of ta-lib indicators are not implemented in vectorbt and can be so useful if talib finally can work with 2D arrays.
@academe-01 did you try cpdef api
?
And did you disable the pandas wrapper function in talib/__init__.py
? Or import them directly from talib._ta_lib
?
@mrjbq7 I did, however I'm ending up with Segmentation fault
_func.pxi:
cdef public api np.ndarray ADX_api(np.ndarray high, np.ndarray low, np.ndarray close, int timeperiod):
return ADX(high, low, close, timeperiod)
test.py:
from numba import njit
import numpy as np
import ctypes
from ctypes import *
from numba.extending import get_cython_function_address
@njit(cache=None)
def adx_nb(h, l, c, t):
return adx(h, l, c, t)
addr = get_cython_function_address("talib._ta_lib", "ADX_api")
adx = ctypes.CFUNCTYPE(c_double,
c_double,
c_double, c_double, ctypes.c_int64)(addr)
h = np.arange(1, 1000.)
l = np.arange(1, 1000.)
c = np.arange(1, 1000.)
adx(h.ctypes.data, l.ctypes.data, c.ctypes.data, 7)
#adx_nb(h.ctypes.data, l.ctypes.data, c.ctypes.data, 7)
not sure what am I doing wrong I tried to use pointers as well, same result, seg fault