TA-Lib / ta-lib-python

Python wrapper for TA-Lib (http://ta-lib.org/).
http://ta-lib.github.io/ta-lib-python
Other
9.46k stars 1.74k forks source link

abstract.Function.info inconsistency #523

Open TheMightiestCarrot opened 2 years ago

TheMightiestCarrot commented 2 years ago

Hello,

i have found some inconsistencies in abstract function definitions. Inputs are mainly refered like this: OrderedDict([('prices', ['high', 'low', 'close'])]) But sometimes like this: OrderedDict([('price0', 'high'), ('price1', 'low')])

If this is when functions input is any ndarray: OrderedDict([('price', 'close')]) then why OBV is like this: OrderedDict([('price', 'close'), ('prices', ['volume'])])

TheMightiestCarrot commented 2 years ago

also all parameters that start with 'nbdev' are defined as integers but the actual function expects float indicators: BBANDS, STDDEV, VAR

mrjbq7 commented 2 years ago

Where do we define nbdev as integers?

I only see them as double nbdev in the _func.pxi and _stream.pxi files.

TheMightiestCarrot commented 2 years ago

In abstract function info

for name, value in abstract.Function("BBANDS").info['parameters'].items():
    print(name ,":",type(value))

timeperiod : <class 'int'>
nbdevup : <class 'int'>
nbdevdn : <class 'int'>
matype : <class 'int'>

for example T3 vfactor is float as its supposed to be

for name, value in abstract.Function("T3").info['parameters'].items():
    print(name ,":",type(value))

timeperiod : <class 'int'>
vfactor : <class 'float'>
mrjbq7 commented 2 years ago

Oh interesting, I'm not sure.

For sure the C function takes floats:

TA_RetCode TA_BBANDS( int    startIdx,
                      int    endIdx,
                      const double inReal[],
                      int           optInTimePeriod, /* From 2 to 100000 */
                      double        optInNbDevUp, /* From TA_REAL_MIN to TA_REAL_MAX */
                      double        optInNbDevDn, /* From TA_REAL_MIN to TA_REAL_MAX */
                      TA_MAType     optInMAType,
                      int          *outBegIdx,
                      int          *outNBElement,
                      double        outRealUpperBand[],
                      double        outRealMiddleBand[],
                      double        outRealLowerBand[] );
mrjbq7 commented 2 years ago

Okay, resolved it -- these values are default values, but not the expected type.

For some reason, default values are made into integers if they "look like integers":

https://github.com/mrjbq7/ta-lib/blob/master/talib/_abstract.pxi#L662

You can see the expected type by inspecting the info TA_OptInputParameterType, which is defined here:

typedef enum
{
   TA_OptInput_RealRange,
   TA_OptInput_RealList,
   TA_OptInput_IntegerRange,
   TA_OptInput_IntegerList
} TA_OptInputParameterType;

So for BBANDS, these are type 0 or TA_OptInput_RealRange, which is correct:

>>> abstract.Function("BBANDS")._Function__opt_inputs
OrderedDict([('timeperiod',
              {'default_value': 5,
               'display_name': 'Time Period',
               'help': 'Number of period',
               'name': 'timeperiod',
               'type': 2,
               'value': None}),
             ('nbdevup',
              {'default_value': 2,
               'display_name': 'Deviations up',
               'help': 'Deviation multiplier for upper band',
               'name': 'nbdevup',
               'type': 0,
               'value': None}),
             ('nbdevdn',
              {'default_value': 2,
               'display_name': 'Deviations down',
               'help': 'Deviation multiplier for lower band',
               'name': 'nbdevdn',
               'type': 0,
               'value': None}),
             ('matype',
              {'default_value': 0,
               'display_name': 'MA Type',
               'help': 'Type of Moving Average',
               'name': 'matype',
               'type': 3,
               'value': None})])

This, I think, sort of resolves your question -- although there may be a valid discussion on why we are int() on a double value...

Could you explain the original question about input price names?