ta-lib-python icon indicating copy to clipboard operation
ta-lib-python copied to clipboard

Calling functions from within Numba

Open polakowo opened this issue 3 years ago • 7 comments

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__.

polakowo avatar Jul 27 '20 21:07 polakowo

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:

  1. make all the _func.pxi indicator functions cpdef api.
  2. change how we wrap them for pandas support, so you can access the C functions
  3. fix the issue with the optional arguments, so you can build the .so in a way that numba can lookup

I didn't have time to work through this right now, but if you'd like to help, that would be cool.

mrjbq7 avatar Aug 04 '20 04:08 mrjbq7

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 avatar Aug 06 '20 10:08 polakowo

@polakowo is there maybe any progress implementing talib with numba in vectorbt? Thank you

smjure avatar Jul 26 '21 07:07 smjure

@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 avatar Aug 02 '21 10:08 polakowo

@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 avatar Nov 16 '22 00:11 academe-01

@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 avatar Nov 16 '22 00:11 mrjbq7

@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

academe-01 avatar Nov 16 '22 01:11 academe-01