1

I think it would be easiest to explain what I mean by showing code first:

def indicator(
        self, symbol: str = None, timeframe: str = None,
        indicator: str = None, period: int = 0, instances: int = 0,
        *args, **kwargs):
    data = self.ohlcv(symbol, timeframe, instances + period)

    for arg in args:
        if arg == 'open':
            arg = data['open'].to_numpy()
        elif arg == 'high':
            arg = data['high'].to_numpy()
        elif arg == 'low':
            arg = data['low'].to_numpy()
        elif arg == 'close':
            arg = data['close'].to_numpy()
        elif arg == 'volume':
            arg = data['volume'].to_numpy()
        else:
            pass

    values = getattr(ta.func, indicator)(args, kwargs)
    return values

Here I am re-assigning args that are strings (i.e. open) to an array of open values from a dataframe. Is there an easier way,or more pythonic/terse way of doing this than using a bunch of if and elif statements? I feel i could do something like setattr for each column in the dataframe but I would not know how to pass them to the second ta.func function.

Thank you!

GSatterwhite
  • 301
  • 1
  • 3
  • 12
  • `args` is a tuple, and therefore immutable. You can build a *new* tuple using its contents, but you cannot change the tuple itself. – chepner Nov 24 '19 at 19:36

1 Answers1

3

Just use the arg variable to access the dataframe directly:

for arg in args:
    arg = data[arg].to_numpy()

However this won't have the intended behaviour that I think you want. When you're iterating a list, reassigning a value has to be done by directly referencing the list via args[i] = rather than arg =. See link.

Also, when passing in *args to a function, args will be a tuple, not a list. So you'll need to:

  1. Convert args to a list.
  2. Reassign values in args with args[i] = instead of arg =, which can be done easily using the enumerate() function in python:
args = list(args)
for i, arg in enumerate(args):
    try:
        args[i] = data[arg].to_numpy()
    except:
        continue

It's wrapped around a try/catch statement to ensure if arg is not a valid location in the dataframe, it'll just ignore it.

Jay Mody
  • 3,727
  • 1
  • 11
  • 27
  • 1
    Thank you so much man this is great. So when I pass in the newly-assigned args in `values = getattr(ta.func, indicator)(args, kwargs)` it will not matter that args is now a list and not a tuple? – GSatterwhite Nov 24 '19 at 19:37
  • @GSatterwhite not sure, but you can always convert it back to a tuple with `tuple(args)`, I'd be curious to find out however. – Jay Mody Nov 24 '19 at 19:39