Files
poly-maker/poly_data/data_processing.py
T

161 lines
6.7 KiB
Python
Raw Normal View History

2025-03-31 12:16:51 -04:00
import json
from sortedcontainers import SortedDict
import poly_data.global_state as global_state
import poly_data.CONSTANTS as CONSTANTS
from trading import perform_trade
import time
import asyncio
from poly_data.data_utils import set_position, set_order, update_positions
def process_book_data(asset, json_data):
global_state.all_data[asset] = {
'asset_id': json_data['asset_id'], # token_id for the Yes token
2025-03-31 12:16:51 -04:00
'bids': SortedDict(),
'asks': SortedDict()
}
global_state.all_data[asset]['bids'].update({float(entry['price']): float(entry['size']) for entry in json_data['bids']})
global_state.all_data[asset]['asks'].update({float(entry['price']): float(entry['size']) for entry in json_data['asks']})
def process_price_change(asset, side, price_level, new_size, asset_id=None):
# Skip updates for the No token to prevent duplicated updates
# Only process if asset_id matches the stored asset_id for this market
if asset_id and asset in global_state.all_data and asset_id != global_state.all_data[asset]['asset_id']:
return
2025-03-31 12:16:51 -04:00
if side == 'bids':
book = global_state.all_data[asset]['bids']
else:
book = global_state.all_data[asset]['asks']
if new_size == 0:
if price_level in book:
del book[price_level]
else:
book[price_level] = new_size
2025-04-17 17:39:58 -07:00
def process_data(json_datas, trade=True):
# Ensure input is always a list
if isinstance(json_datas, dict):
json_datas = [json_datas]
2025-04-17 17:39:58 -07:00
for json_data in json_datas:
event_type = json_data['event_type']
asset = json_data['market']
if event_type == 'book':
process_book_data(asset, json_data)
if trade:
asyncio.create_task(perform_trade(asset))
elif event_type == 'price_change':
for data in json_data['price_changes']:
2025-04-17 17:39:58 -07:00
side = 'bids' if data['side'] == 'BUY' else 'asks'
price_level = float(data['price'])
new_size = float(data['size'])
# Pass asset_id if available in the data
asset_id = data.get('asset_id', None)
process_price_change(asset, side, price_level, new_size, asset_id)
2025-04-17 17:39:58 -07:00
if trade:
asyncio.create_task(perform_trade(asset))
2025-03-31 12:16:51 -04:00
2025-04-17 17:39:58 -07:00
# pretty_print(f'Received book update for {asset}:', global_state.all_data[asset])
2025-03-31 12:16:51 -04:00
def add_to_performing(col, id):
if col not in global_state.performing:
global_state.performing[col] = set()
if col not in global_state.performing_timestamps:
global_state.performing_timestamps[col] = {}
# Add the trade ID and track its timestamp
global_state.performing[col].add(id)
global_state.performing_timestamps[col][id] = time.time()
def remove_from_performing(col, id):
if col in global_state.performing:
global_state.performing[col].discard(id)
if col in global_state.performing_timestamps:
global_state.performing_timestamps[col].pop(id, None)
2025-04-17 17:39:58 -07:00
def process_user_data(rows):
2025-03-31 12:16:51 -04:00
2025-04-17 17:39:58 -07:00
for row in rows:
market = row['market']
2025-03-31 12:16:51 -04:00
2025-04-17 17:39:58 -07:00
side = row['side'].lower()
token = row['asset_id']
if token in global_state.REVERSE_TOKENS:
col = token + "_" + side
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]))
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)])
2025-03-31 12:16:51 -04:00
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))
2025-04-17 17:39:58 -07:00
elif row['status'] == 'MINED':
remove_from_performing(col, row['id'])
2025-03-31 12:16:51 -04:00
2025-04-17 17:39:58 -07:00
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'])
2025-03-31 12:16:51 -04:00
asyncio.create_task(perform_trade(market))
else:
print(f"User date received for {market} but its not in")