0

I'm making a crypto scanner which has to scan 100+ different cryptocoins at the same time. Now I'm having a really hard time simplifying this code because if I don't I'm gonna end up with more than 100 functions for something really easy. I'll post down here what I'm trying to refactor.

def main():
    twm = ThreadedWebsocketManager(api_key=api_key,api_secret=api_secret)
    twm.start()
    dic = {'close': [], 'low': [], 'high': []}
    dic2 = {'close': [], 'low': [], 'high': []}

    def handle_socket_message(msg):
        candle = msg['k']
        close_price = candle['c']
        highest_price = candle['h']
        lowest_price = candle['l']
        status = candle['x']
        if status:
            dic['close'].append(close_price)
            dic['low'].append(lowest_price)
            dic['high'].append(highest_price)
            df = pd.DataFrame(dic)
            print(df)

    def handle_socket_message2(msg):
        candle = msg['k']
        close_price = candle['c']
        highest_price = candle['h']
        lowest_price = candle['l']
        status = candle['x']
        if status:
            dic2['close'].append(close_price)
            dic2['low'].append(lowest_price)
            dic2['high'].append(highest_price)
            df = pd.DataFrame(dic2)
            print(df)



    twm.start_kline_socket(callback=handle_socket_message, symbol='ETHUSDT')
    twm.start_kline_socket(callback=handle_socket_message2, symbol='BTCUSDT')
    twm.join()

As you can see I getting live data from BTCUSDT and ETHUSDT. Now I append the close,low and high prices to a dictionary and then I make a DataFrame out of those dictionaries. I tried to do this with 1 dictionary and 1 handle_socket_message function. But then it merges the values of both cryptocoins into 1 dataframe which is not what I want. Does anyone know how I can refactor this piece of code? I was thinking about something with a loop but I can't figure it out myself. If you have any questions, ask away! Thanks in advance!

Jellyfish
  • 67
  • 9
  • How about creating a dictionary with each symbol as the key and a dictionary as a value? The latter can have `close`, `low` and `high` as its keys. I am saying this because the code of each callback seems identical. – gthanop Nov 06 '21 at 17:32
  • @gthanop Oooh yeah this seems a really easy solution! I'm gonna try this tomorrow, thanks! – Jellyfish Nov 06 '21 at 17:43

1 Answers1

0

I don't know exactly what you are trying to do, but the following code might get you started (basically use a dict of dicts):

twm = ThreadedWebsocketManager(api_key=api_key,api_secret=api_secret)
twm.start()

symbols = ['ETHUSDT', 'BTCUSDT']

symbolToMessageKeys = {
    'close': 'c',
    'high': 'h',
    'low': 'l'
}

dictPerSymbol = dict()
for sym in symbols:
    d = dict()
    dictPerSymbol[sym] = d
    for key in symbolToMessageKeys.keys():
        d[key] = list()

print(dictPerSymbol)

def handle_socket_message(msg):
    candle = msg['k']
    if candle['x']:
        d = dictPerSymbol[msg['s']]
        for (symbolKey, msgKey) in symbolToMessageKeys.items():
            d[symbolKey].append(candle[msgKey])
        df = pd.DataFrame(d)
        print(df)

for sym in symbols:
    twm.start_kline_socket(callback=handle_socket_message, symbol=sym)

twm.join()

Luckily, appending to lists seems thread safe. Warning: if it is not, then we have a major race condition in the code of this answer. I should also note that I haven't used neither ThreadedWebsocketManagers nor DataFrames (so the latter may as well introduce thread safety issues if it is meant to write in the provided dictionary).

gthanop
  • 3,035
  • 2
  • 10
  • 27