0

The dictionary has 3 keys . The keys are price,size,side . The data comes from websocket. How can I detect same price same side but changed size ? if price and side is same I want size changes. how can I do that ?

from BybitWebsocket import BybitWebsocket
from time import sleep
if __name__ == "__main__":
    ws = BybitWebsocket(wsURL="wss://stream.bybit.com/realtime",
                         api_key="", api_secret=""
                        )

    ws.subscribe_orderBookL2("XRPUSD")

    while(1):
        orders = ws.get_data("orderBookL2_25.XRPUSD")
        if orders != []:
            orders2 = orders["update"]

            data = {'price':[],'size':[],'side':[]}

            for i,val in enumerate(orders2):
                data["price"].append(val["price"])
                data["size"].append(val["size"])
                data["side"].append(val["side"])


            print(data)



        sleep(0.1)



{'price': ['0.7779'], 'size': [31804], 'side': ['Buy']}
{'price': ['0.7779', '0.7782'], 'size': [31766, 33014], 'side': ['Buy', 'Sell']}
{'price': ['0.7773', '0.7770'], 'size': [27029, 83875], 'side': ['Buy', 'Buy']}
{'price': ['0.7779', '0.7778'], 'size': [71, 148372], 'side': ['Sell', 'Sell']}
{'price': ['0.7777', '0.7770'], 'size': [1515, 85432], 'side': ['Buy', 'Buy']}
{'price': ['0.7778', '0.7765', '0.7782'], 'size': [141913, 1290, 5842], 'side': ['Sell', 'Buy', 'Sell']}
{'price': ['0.7777'], 'size': [24794], 'side': ['Buy']}

for that outcome price 0.7779 size changed 31804 to 33014 , price 0.7777 size changed 1515 to 24794 and so on.
  • since the values are all lists, how do you detect that the value changed? – JonSG Mar 01 '22 at 15:14
  • I tried to export data to excel,csv,pandas but no luck. If I use strings other than list than price,size,side updating by last data from websocket . How can I make store all data so maybe with another function will do for comparing ? – Ali Sarikaya Mar 01 '22 at 15:16

1 Answers1

0

I not 100% sure I understand your question, but if so this may help. I hope the sample data I used is sufficient. I use comments in-line to explain:

# from BybitWebsocket import BybitWebsocket
from time import sleep


def sample_gen():
    """Generator return one list item for each order with updates."""
    samples = [
        {"update": [{"price": "1", "side": "Buy", "size": 10}]},
        {"update": [{"price": "1", "side": "Buy", "size": 11}]},
        {
            "update": [
                {"price": "1", "side": "Buy", "size": 12},
                {"price": "1", "side": "Buy", "size": 13},
                {"price": "2", "side": "Sell", "size": 21},
            ]
        },
        [],
        {
            "update": [
                {"price": "1", "side": "Buy", "size": 14},
                {"price": "2", "side": "Sell", "size": 22},
            ]
        },
        [],
        {"update": [{"price": "1", "side": "Sell", "size": 11}]},
        {"update": [{"price": "1", "side": "Buy", "size": 15}]},
    ]
    for sample in samples:
        yield sample


if __name__ == "__main__":
    # Commenting out the websockets bit.
    # ws = BybitWebsocket(
    #     wsURL="wss://stream.bybit.com/realtime", api_key="", api_secret=""
    # )
    # ws.subscribe_orderBookL2("XRPUSD")

    # Since tuples are hashable and you are operating based on size per
    # combination of price and side, I suggest using price and side as
    # a tuple key for a slightly different data structure.
    price_side = {}  # Initialized here for scope.
    g = sample_gen()  # Creating the generator for the sample data.
    while True:  # While True I see more commonly that `While 1`, but they are the same.
        # Get one item from the sample data, and for each at the `update`
        # key or an empty list.
        order = next(g)
        # order = ws.get_data("orderBookL2_25.XRPUSD")
        if order:
            for update in order.get("update", []):
                price, side, size = (
                    update.get("price"),
                    update.get("side"),
                    update.get("size"),
                )
                # Using setdefault lets us start an empty list or append.
                # This way for each price, side combination we can keep a
                # running list of all size updates.
                price_side.setdefault((price, side), []).append(size)
                if len(price_side[(price, side)]) < 2:  # Case where list has only 1.
                    print(f"{price} {side}: new price/side with size {size}")
                    continue  # Continue to next update.
                if price_side[(price, side)][-1] != price_side[(price, side)][-2]:
                    print(f"{price} {side}: price/side updated with size {size}")
        sleep(0.1)

This yields:

1 Buy: new price/side with size 10
1 Buy: price/side updated with size 11
1 Buy: price/side updated with size 12
1 Buy: price/side updated with size 13
2 Sell: new price/side with size 21
1 Buy: price/side updated with size 14
2 Sell: price/side updated with size 22
1 Sell: new price/side with size 11
1 Buy: price/side updated with size 15
Traceback (most recent call last):
  File "/Users/h4s/projects/github.com/theherk/tmp-py/ws/./main.py", line 50, in <module>
    for order in next(g).get("update", []):
StopIteration

The StopIteration here is just getting to the end of the generator.


With your code in place of sample data, this would be:

from BybitWebsocket import BybitWebsocket
from time import sleep


if __name__ == "__main__":
    ws = BybitWebsocket(
        wsURL="wss://stream.bybit.com/realtime", api_key="", api_secret=""
    )
    ws.subscribe_orderBookL2("XRPUSD")

    price_side = {}
    while True:
        order = ws.get_data("orderBookL2_25.XRPUSD")
        if order:
            for update in order.get("update", []):
                price, side, size = (
                    update.get("price"),
                    update.get("side"),
                    update.get("size"),
                )
                price_side.setdefault((price, side), []).append(size)
                if len(price_side[(price, side)]) < 2:
                    print(f"{price} {side}: new price/side with size {size}")
                    continue
                if price_side[(price, side)][-1] != price_side[(price, side)][-2]:
                    print(f"{price} {side}: price/side updated with size {size}")
        sleep(0.1)
theherk
  • 6,954
  • 3
  • 27
  • 52
  • @AliSarikaya I don't know what happened to your comment, but see my updated version. It should handle empty lists in `get_data` in both the sample and the live code. – theherk Mar 01 '22 at 17:36
  • After getting an error I fixed so deleted it thanks anyway. But does this code returning "change" of size or current size ? (I mean for example first size was 1200 updated size 21200 do I get 20000 or 21200 ) I'm confused a little bit. For example if I want to see change over 50k how to add this to your code ?@theherk – Ali Sarikaya Mar 01 '22 at 17:41
  • `price_side[(price, side)][-2]` is the last appended `size` before the update, or second to last in the list. `price_side[(price, side)][-1]` is the most recently added `size`. So in my code I'm just saying "I got an update to this price / side combination of this `size`. If you wanted to know how much the change was, you would just subtract one from the other. – theherk Mar 01 '22 at 17:46