mementum / bta-lib

Technical Analysis library in pandas for backtesting algotrading and quantitative analysis
MIT License
451 stars 106 forks source link

Can't run bta-lib inside a thread #9

Open karaolidis opened 3 years ago

karaolidis commented 3 years ago

Hello, I'm trying to use btalib and I'm having some trouble when having it run from inside a thread.

The below code works fine:

import [...]

symbol = 'BTCEUR'

with open('./data/' + symbol + '/' + symbol + '_kline.p', 'rb') as handle:
    kline_df = pickle.load(handle)

sma = btalib.sma(kline_df).df
print(sma)

But when I try to use threads...

import [...]

symbol = 'BTCEUR'

with open('./data/' + symbol + '/' + symbol + '_kline.p', 'rb') as handle:
    kline_df = pickle.load(handle)

def thread():
    sma = btalib.sma(kline_df).df
    print(sma)
    time.sleep(5)

x = threading.Thread(target=thread)
x.start()

... I get the following error:

Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/home/nick/storage/Documents/_Projects/Python/Crypto/btalib_test.py", line 13, in thread
    sma = btalib.sma(kline_df).df
  File "/home/nick/storage/Documents/_Projects/Python/Crypto/venv/lib/python3.9/site-packages/btalib/indicator.py", line 110, in __call__
    self.outputs = self.o = meta.outputs._from_class(cls)
  File "/home/nick/storage/Documents/_Projects/Python/Crypto/venv/lib/python3.9/site-packages/btalib/meta/outputs.py", line 30, in _from_class
    return _CLSOUTPUTS[cls]()  # defvals params in dict format
  File "/home/nick/storage/Documents/_Projects/Python/Crypto/venv/lib/python3.9/site-packages/btalib/meta/lines.py", line 630, in __init__
    metadata.minperiods[self] = [1] * len(self)
AttributeError: '_thread._local' object has no attribute 'minperiods'

Any help would be appreciated!

vijay-r commented 3 years ago

Team, getting same error any solution ?

karaolidis commented 3 years ago

I found a workaround which is less than ideal but will have to do until we get an update from the maintainers.

I created a separate script for the bta-lib calculations that had looked something like this...

import pandas as pd
import pickle
import btalib
import sys

symbol = sys.argv[1]

with open('./data/' + symbol + '/' + symbol + '_kline.p', 'rb') as handle:
    kline_df = pickle.load(handle)

sma = btalib.sma(kline_df).df

with open('./data/' + symbol + '/sma.p', 'wb') as handle:
    pickle.dump(sma, handle)

...and then, from the main script, from inside the thread, I run...

subprocess.Popen(['python', 'bta.py', 'BTCEUR']).wait()

with open('./data/' + symbol + '/sma.p', 'rb') as handle:
    sma = pickle.load(handle)

It's clunky but it will have to do for now.

Beauj34 commented 3 years ago

Has anyone found a better explanation why BTA-Lib doesn't work within threading? Getting the same errors with different indicators

drhighliner commented 3 years ago

Take a look at the pull request section. Someone found a solution for this (thread) issue which works quite nicely.