LUCIT-Systems-and-Development / unicorn-fy

A Python SDK by LUCIT to convert received raw data from crypto exchange API endpoints into well-formed python dictionaries.
https://unicorn-fy.docs.lucit.tech
MIT License
54 stars 20 forks source link

Unicorn Websocket crashes because of key 'data' error when the event type is balanceUpdate #20

Closed davivc closed 3 years ago

davivc commented 3 years ago

Check this or we will delete your issue. (fill in the checkbox with an X like so: [x])

Select one:

Environment

Operating System? (include version)

Exact Python Version?

Python 3.8.7

Pip Version?

pip 21.0.1

Description of your issue

unicorn-binance-websocket-api crashes when I use the output=UnicornFy on my user stream and I make a manual trade on my Binance account. My guess is that the key 'balanceUpdate' does not exist in UnicornFy.

This error occurs both in margin (cross and isolated) and spot account stream data.

I've created the isolated margin stream with the output=UnicornFy

ubwa_com_im.create_stream(
                "arr",
                "!userData",
                symbols="BTCUSDT",
                output="UnicornFy",
                api_key=binance_api_key,
                api_secret=binance_api_secret,
                stream_label="im BTCUSDT"
)

This is part of the DEBUG output after I've sent 1USDT to my BTCUSDT Isolated-Margin (this error also happens in the spot account when I trade manually.

unicorn_stream                | 2021-03-16 20:21:58,309 - DEBUG |client - received solicited pong: 60806399
unicorn_stream                | 2021-03-16 20:22:10,470 - DEBUG |client - event = data_received(<72 bytes>)
unicorn_stream                | 2021-03-16 20:22:10,470 - DEBUG |client - event = data_received(<97 bytes>)
unicorn_stream                | 2021-03-16 20:22:10,481 - DEBUG |client < Frame(fin=True, opcode=1, data=b'{"e":"balanceUpdate","E":1615926131286,"a":"USDT","d":"1.00000000","T":1615926131285}', rsv1=False, rsv2=False, rsv3=False)
unicorn_stream                | 2021-03-16 20:22:10,491 - DEBUG |client < Frame(fin=True, opcode=1, data=b'{"e":"outboundAccountPosition","E":1615926131286,"u":1615926131285,"B":[{"a":"USDT","f":"1.00000000","l":"0.00000000"}]}', rsv1=False, rsv2=False, rsv3=False)
unicorn_stream                | 2021-03-16 20:22:10,622 - DEBUG |UnicornFy->binance_websocket({"e":"balanceUpdate","E":1615926131286,"a":"USDT","d":"1.00000000","T":1615926131285})
unicorn_stream                | 2021-03-16 20:22:10,627 - ERROR |BinanceWebSocketApiSocket.start_socket(d4b1ac8c-f4c3-4f4a-b6a7-e67bb04ad856, ['arr'], ['!userData']) - Exception General Exception - error_msg: 'data'
unicorn_stream                | 2021-03-16 20:22:10,632 - CRITICAL |BinanceWebSocketApiManager.stream_is_crashing(d4b1ac8c-f4c3-4f4a-b6a7-e67bb04ad856)
unicorn_stream                | 2021-03-16 20:22:10,638 - DEBUG |client - state = CLOSING
unicorn_stream                | 2021-03-16 20:22:10,643 - DEBUG |client > Frame(fin=True, opcode=8, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
unicorn_stream                | 2021-03-16 20:22:10,721 - INFO |BinanceWebSocketApiManager.kill_stream(d4b1ac8c-f4c3-4f4a-b6a7-e67bb04ad856)
unicorn_stream                | 2021-03-16 20:22:10,726 - INFO |BinanceWebSocketApiManager._restart_stream(d4b1ac8c-f4c3-4f4a-b6a7-e67bb04ad856, ['arr'], ['!userData'])
unicorn_stream                | 2021-03-16 20:22:10,737 - DEBUG |Using selector: EpollSelector

I think this is the part of the UnicornFy code that misses the balanceUpdate key and throws the error down in the code:

        try:
            if stream_data['e'] == 'outboundAccountInfo':
                stream_data = {'data': stream_data}
            elif stream_data['e'] == 'executionReport':
                stream_data = {'data': stream_data}
            elif stream_data['e'] == 'outboundAccountPosition':
                stream_data = {'data': stream_data}
            elif stream_data['e'] == 'listStatus':
                stream_data = {'data': stream_data}
        except KeyError:
            pass

Since the 'balanceUpdate' is not on this if-else chain the stream_data follows as it is, the code down below can't find the key 'data' and raises the error killing the WebSocket.

I did a local test tinkering with this and worked, however, I did by processing the JSON after the buffer output and not using the output param in create_stream. I'll fork the code, fix this and will do a pull request.

oliver-zehentleitner commented 3 years ago

I am very tired and cant get the big picture in my head today...

Maybe this is related to the changes binance announced some time ago: https://github.com/oliver-zehentleitner/unicorn-fy/issues/17

I very appreciate that you fix this and contribute it via a PR, i will create a new package then asap.

Best regards!

oliver-zehentleitner commented 3 years ago

Its released: https://github.com/oliver-zehentleitner/unicorn-fy/releases/tag/0.9.0 https://pypi.org/project/unicorn-fy/0.9.0/

Thanks for your support! Best regards, Oliver