Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call functions based on their names as a strings in a list

Terms: 
talib: Technical Analysis Library (stock market indicators, charts etc)
CDL: Candle or Candlestick

Short version: I want to run my_lib.some_function() based on the string 'some_function'

On quantopian.com I want to call all of the 60 talib functions that start with CDL, like talib.CDL2CROWS(), in a loop for brevity. First pull the function names as strings, then run the functions by the name matching the string.

Those CDL functions all take the same inputs, lists of open, high, low and closing prices for a time period and the test here just uses a list of length 1 to simplify.

import talib, re
import numpy as np

# Make a list of talib's function names that start with 'CDL'
cdls = re.findall('(CDL\w*)', ' '.join(dir(talib)))
# cdls[:3], the first three like ['CDL2CROWS', 'CDL3BLACKCROWS', 'CDL3INSIDE']

for cdl in cdls:
    codeobj = compile(cdl + '(np.array([3]),np.array([4]),np.array([5]),np.array([6]))', 'talib', 'exec')
    exec(codeobj)
    break
# Output:  NameError: name 'CDL2CROWS' is not defined

Try number two:

import talib, re
import numpy as np

cdls = re.findall('(CDL\w*)', ' '.join(dir(talib)))

for cdl in cdls:
    codeobj = compile('talib.' + cdl + '(np.array([3]),np.array([4]),np.array([5]),np.array([6]))', '', 'exec')
    exec(codeobj)
    break
# Output:  AssertionError: open is not double

I didn't find that error online.

Related, where I asked the question over there: https://www.quantopian.com/posts/talib-indicators (111 views, no replies yet)

For anyone curious about candlesticks: http://thepatternsite.com/TwoCrows.html


Update

This works, after help in chat from Anzel, possibly floats in the lists were key.

import talib, re
import numpy as np
cdls = re.findall('(CDL\w*)', ' '.join(dir(talib)))
# O, H, L, C = Open, High, Low, Close
O = [ 167.07, 170.8, 178.9, 184.48, 179.1401, 183.56, 186.7, 187.52, 189.0, 193.96 ]
H = [ 167.45, 180.47, 185.83, 185.48, 184.96, 186.3, 189.68, 191.28, 194.5, 194.23 ]
L = [ 164.2, 169.08, 178.56, 177.11, 177.65, 180.5, 185.611, 186.43, 188.0, 188.37 ]
C = [ 166.26, 177.8701, 183.4, 181.039, 182.43, 185.3, 188.61, 190.86, 193.39, 192.99 ]
for cdl in cdls: # the string that becomes the function name
    toExec = getattr(talib, cdl)
    out    = toExec(np.array(O), np.array(H), np.array(L), np.array(C))
    print str(out) + ' ' + cdl

Choices on how to add arguments to your string-turned-function:

toExec = getattr(talib, cdl)(args)
toExec()

or

toExec = getattr(talib, cdl)
toExec(args)
like image 650
gseattle Avatar asked Jan 10 '23 14:01

gseattle


1 Answers

A simpler way would be using the abstract lib

import talib

# All the CDL functions are under the Pattern Recognition group
for cdl in talib.get_function_groups()['Pattern Recognition']:
    # get the function object
    cdl_func = talib.abstract.Function(cdl)

    # you can use the info property to get the name of the pattern
    print('Checking', cdl_func.info['display_name'], 'pattern')

    # run the function as usual
    cdl_func(np.array(O), np.array(H), np.array(L), np.array(C))
like image 126
Renato Avatar answered Feb 01 '23 15:02

Renato