From a1140c076f61d270b46509360b6d5735aabe4d17 Mon Sep 17 00:00:00 2001 From: warproxxx Date: Thu, 17 Apr 2025 17:39:58 -0700 Subject: [PATCH] Handle the polymarket changes --- README.md | 2 + main.py | 3 + poly_data/data_processing.py | 155 ++++++++++++++++++---------------- poly_merger/package-lock.json | 6 +- poly_utils/google_utils.py | 5 ++ 5 files changed, 93 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index b90dfdd..cbfc3af 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ cp .env.example .env - `PK`: Your private key for Polymarket - `BROWSER_ADDRESS`: Your wallet address +Make sure your wallet has done at least one trade thru the UI so that the permissions are proper. + 6. **Set up Google Sheets integration**: - Create a Google Service Account and download credentials to the main directory - Copy the [sample Google Sheet](https://docs.google.com/spreadsheets/d/1Kt6yGY7CZpB75cLJJAdWo7LSp9Oz7pjqfuVWwgtn7Ns/edit?gid=1884499063#gid=1884499063) diff --git a/main.py b/main.py index 290d0a9..0d72d37 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,9 @@ from poly_data.data_utils import update_markets, update_positions, update_orders from poly_data.websocket_handlers import connect_market_websocket, connect_user_websocket import poly_data.global_state as global_state from poly_data.data_processing import remove_from_performing +from dotenv import load_dotenv + +load_dotenv() def update_once(): """ diff --git a/poly_data/data_processing.py b/poly_data/data_processing.py index 567ce1e..888ca63 100644 --- a/poly_data/data_processing.py +++ b/poly_data/data_processing.py @@ -29,27 +29,30 @@ def process_price_change(asset, side, price_level, new_size): else: book[price_level] = new_size -def process_data(json_data, trade=True): - event_type = json_data['event_type'] - asset = json_data['market'] +def process_data(json_datas, trade=True): - if event_type == 'book': - process_book_data(asset, json_data) + for json_data in json_datas: + event_type = json_data['event_type'] + asset = json_data['market'] - if trade: - asyncio.create_task(perform_trade(asset)) - - elif event_type == 'price_change': - side = 'bids' if json_data['side'] == 'BUY' else 'asks' - price_level = float(json_data['price']) - new_size = float(json_data['size']) - process_price_change(asset, side, price_level, new_size) + if event_type == 'book': + process_book_data(asset, json_data) - if trade: - asyncio.create_task(perform_trade(asset)) - + if trade: + asyncio.create_task(perform_trade(asset)) + + elif event_type == 'price_change': + for data in json_data['changes']: + side = 'bids' if data['side'] == 'BUY' else 'asks' + price_level = float(data['price']) + new_size = float(data['size']) + process_price_change(asset, side, price_level, new_size) - # pretty_print(f'Received book update for {asset}:', global_state.all_data[asset]) + if trade: + asyncio.create_task(perform_trade(asset)) + + + # pretty_print(f'Received book update for {asset}:', global_state.all_data[asset]) def add_to_performing(col, id): if col not in global_state.performing: @@ -69,76 +72,78 @@ def remove_from_performing(col, id): if col in global_state.performing_timestamps: global_state.performing_timestamps[col].pop(id, None) -def process_user_data(row): - market = row['market'] +def process_user_data(rows): - side = row['side'].lower() - token = row['asset_id'] - - if token in global_state.REVERSE_TOKENS: - col = token + "_" + side + for row in rows: + market = row['market'] - if row['event_type'] == 'trade': - size = 0 - price = 0 - maker_outcome = "" - taker_outcome = row['outcome'] - - is_user_maker = False - for maker_order in row['maker_orders']: - if maker_order['maker_address'].lower() == global_state.client.browser_wallet.lower(): - print("User is maker") - size = float(maker_order['matched_amount']) - price = float(maker_order['price']) - - is_user_maker = True - maker_outcome = maker_order['outcome'] #this is curious - - if maker_outcome == taker_outcome: - side = 'buy' if side == 'sell' else 'sell' #need to reverse as we reverse token too - else: - token = global_state.REVERSE_TOKENS[token] + side = row['side'].lower() + token = row['asset_id'] - if not is_user_maker: - size = float(row['size']) - price = float(row['price']) - print("User is taker") + if token in global_state.REVERSE_TOKENS: + col = token + "_" + side - print("TRADE EVENT FOR: ", row['market'], "ID: ", row['id'], "STATUS: ", row['status'], " SIDE: ", row['side'], " MAKER OUTCOME: ", maker_outcome, " TAKER OUTCOME: ", taker_outcome, " PROCESSED SIDE: ", side, " SIZE: ", size) + if row['event_type'] == 'trade': + size = 0 + price = 0 + maker_outcome = "" + taker_outcome = row['outcome'] + + is_user_maker = False + for maker_order in row['maker_orders']: + if maker_order['maker_address'].lower() == global_state.client.browser_wallet.lower(): + print("User is maker") + size = float(maker_order['matched_amount']) + price = float(maker_order['price']) + + is_user_maker = True + maker_outcome = maker_order['outcome'] #this is curious + + if maker_outcome == taker_outcome: + side = 'buy' if side == 'sell' else 'sell' #need to reverse as we reverse token too + else: + token = global_state.REVERSE_TOKENS[token] + + if not is_user_maker: + size = float(row['size']) + price = float(row['price']) + print("User is taker") + + print("TRADE EVENT FOR: ", row['market'], "ID: ", row['id'], "STATUS: ", row['status'], " SIDE: ", row['side'], " MAKER OUTCOME: ", maker_outcome, " TAKER OUTCOME: ", taker_outcome, " PROCESSED SIDE: ", side, " SIZE: ", size) - if row['status'] == 'CONFIRMED' or row['status'] == 'FAILED' : - if row['status'] == 'FAILED': - print(f"Trade failed for {token}, decreasing") - asyncio.create_task(asyncio.sleep(2)) - update_positions() - else: - remove_from_performing(col, row['id']) - print("Confirmed. Performing is ", len(global_state.performing[col])) + if row['status'] == 'CONFIRMED' or row['status'] == 'FAILED' : + if row['status'] == 'FAILED': + print(f"Trade failed for {token}, decreasing") + asyncio.create_task(asyncio.sleep(2)) + update_positions() + else: + remove_from_performing(col, row['id']) + print("Confirmed. Performing is ", len(global_state.performing[col])) + print("Last trade update is ", global_state.last_trade_update) + print("Performing is ", global_state.performing) + print("Performing timestamps is ", global_state.performing_timestamps) + + asyncio.create_task(perform_trade(market)) + + elif row['status'] == 'MATCHED': + add_to_performing(col, row['id']) + + print("Matched. Performing is ", len(global_state.performing[col])) + set_position(token, side, size, price) + print("Position after matching is ", global_state.positions[str(token)]) print("Last trade update is ", global_state.last_trade_update) print("Performing is ", global_state.performing) print("Performing timestamps is ", global_state.performing_timestamps) - asyncio.create_task(perform_trade(market)) + elif row['status'] == 'MINED': + remove_from_performing(col, row['id']) - elif row['status'] == 'MATCHED': - add_to_performing(col, row['id']) - - print("Matched. Performing is ", len(global_state.performing[col])) - set_position(token, side, size, price) - print("Position after matching is ", global_state.positions[str(token)]) - print("Last trade update is ", global_state.last_trade_update) - print("Performing is ", global_state.performing) - print("Performing timestamps is ", global_state.performing_timestamps) + elif row['event_type'] == 'order': + print("ORDER EVENT FOR: ", row['market'], " STATUS: ", row['status'], " TYPE: ", row['type'], " SIDE: ", side, " ORIGINAL SIZE: ", row['original_size'], " SIZE MATCHED: ", row['size_matched']) + + set_order(token, side, float(row['original_size']) - float(row['size_matched']), row['price']) asyncio.create_task(perform_trade(market)) - elif row['status'] == 'MINED': - remove_from_performing(col, row['id']) - - elif row['event_type'] == 'order': - print("ORDER EVENT FOR: ", row['market'], " STATUS: ", row['status'], " TYPE: ", row['type'], " SIDE: ", side, " ORIGINAL SIZE: ", row['original_size'], " SIZE MATCHED: ", row['size_matched']) - - set_order(token, side, float(row['original_size']) - float(row['size_matched']), row['price']) - asyncio.create_task(perform_trade(market)) else: print(f"User date received for {market} but its not in") \ No newline at end of file diff --git a/poly_merger/package-lock.json b/poly_merger/package-lock.json index a7d73c4..7770021 100644 --- a/poly_merger/package-lock.json +++ b/poly_merger/package-lock.json @@ -1,13 +1,13 @@ { - "name": "poly_live", + "name": "poly-merger", "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "poly_live", + "name": "poly-merger", "version": "1.0.0", - "license": "ISC", + "license": "MIT", "dependencies": { "dotenv": "^16.4.5", "ethers": "^5.6.3" diff --git a/poly_utils/google_utils.py b/poly_utils/google_utils.py index 7b63f18..4ea1955 100644 --- a/poly_utils/google_utils.py +++ b/poly_utils/google_utils.py @@ -1,7 +1,9 @@ from google.oauth2.service_account import Credentials import gspread import os +from dotenv import load_dotenv +load_dotenv() def get_spreadsheet(): scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"] @@ -12,5 +14,8 @@ def get_spreadsheet(): spreadsheet_url = os.getenv("SPREADSHEET_URL") if not spreadsheet_url: raise ValueError("SPREADSHEET_URL environment variable is not set") + spreadsheet = client.open_by_url(spreadsheet_url) return spreadsheet + +