Refactor trading logic and client initialization; remove unused clob_client_and_order module
This commit is contained in:
@@ -2,6 +2,7 @@ LOG_FOLDER = "logs/"
|
|||||||
GAMMA_API_URL = "https://gamma-api.polymarket.com"
|
GAMMA_API_URL = "https://gamma-api.polymarket.com"
|
||||||
POLYMARKET_HOST = "https://clob.polymarket.com"
|
POLYMARKET_HOST = "https://clob.polymarket.com"
|
||||||
POLYMARKET_WS_MARKET_URL = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
|
POLYMARKET_WS_MARKET_URL = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
|
||||||
|
POLYMARKET_WS_USER_URL = "wss://ws-subscriptions-clob.polymarket.com/ws/user"
|
||||||
CHAIN_ID = 137
|
CHAIN_ID = 137
|
||||||
REQUEST_TIMEOUT = 5
|
REQUEST_TIMEOUT = 5
|
||||||
PROFIT_MARGIN = 0.02
|
PROFIT_MARGIN = 0.02
|
||||||
@@ -9,3 +10,4 @@ TRADING_BPS_THRESHOLD = 50
|
|||||||
MARKET_SESSION_SECONDS = 900
|
MARKET_SESSION_SECONDS = 900
|
||||||
TIMEZONE = "US/Eastern"
|
TIMEZONE = "US/Eastern"
|
||||||
MAX_TRADES = 1
|
MAX_TRADES = 1
|
||||||
|
PLACE_OPPOSITE_ORDER = True # Hedge orders
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
|
import os
|
||||||
import gc
|
import gc
|
||||||
import asyncio
|
import asyncio
|
||||||
import requests
|
import requests
|
||||||
from utils.logger import setup_logging
|
from utils.logger import setup_logging
|
||||||
from utils.tokens import fetch_tokens
|
from utils.tokens import fetch_tokens
|
||||||
from utils.clob_client_and_order import init_clob_client
|
|
||||||
from utils.orderbook import OrderBook, SIGNALES
|
from utils.orderbook import OrderBook, SIGNALES
|
||||||
from utils.market_time import is_in_trading_window, get_period_elapsed_seconds
|
from utils.clob_client import init_global_client
|
||||||
from utils.clob_client_and_order import (
|
from utils.market_time import is_in_trading_window
|
||||||
|
from utils.clob_orders import (
|
||||||
place_anchor_and_hedge,
|
place_anchor_and_hedge,
|
||||||
cache_tocken_trading_infos,
|
cache_tocken_trading_infos,
|
||||||
)
|
)
|
||||||
@@ -26,16 +27,17 @@ requests.options = session.options
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
|
||||||
trades = 0
|
trades = 0
|
||||||
|
|
||||||
logger = setup_logging()
|
logger = setup_logging()
|
||||||
set_cpu_affinity()
|
set_cpu_affinity()
|
||||||
logger.info("Polymarket HFT Market Maker started")
|
logger.info("Polymarket HFT Market Maker started")
|
||||||
|
init_global_client()
|
||||||
up_token, down_token, market_slug = await fetch_tokens()
|
up_token, down_token, market_slug = await fetch_tokens()
|
||||||
client = init_clob_client()
|
|
||||||
book = OrderBook(up_token, down_token, market_slug)
|
book = OrderBook(up_token, down_token, market_slug)
|
||||||
await asyncio.create_task(cache_tocken_trading_infos(client, book))
|
await asyncio.create_task(cache_tocken_trading_infos(book))
|
||||||
book.start()
|
book.start()
|
||||||
|
|
||||||
await asyncio.sleep(5) # Allow some time for initial order book data
|
await asyncio.sleep(5) # Allow some time for initial order book data
|
||||||
@@ -62,7 +64,7 @@ async def main():
|
|||||||
trades = 0
|
trades = 0
|
||||||
up_token, down_token, market_slug = await fetch_tokens()
|
up_token, down_token, market_slug = await fetch_tokens()
|
||||||
book = OrderBook(up_token, down_token, market_slug)
|
book = OrderBook(up_token, down_token, market_slug)
|
||||||
asyncio.create_task(cache_tocken_trading_infos(client, book))
|
asyncio.create_task(cache_tocken_trading_infos(book))
|
||||||
book.start()
|
book.start()
|
||||||
|
|
||||||
market_data = book.get_current_market_data()
|
market_data = book.get_current_market_data()
|
||||||
@@ -83,7 +85,6 @@ async def main():
|
|||||||
|
|
||||||
if trading_side == SIGNALES.UP:
|
if trading_side == SIGNALES.UP:
|
||||||
await place_anchor_and_hedge(
|
await place_anchor_and_hedge(
|
||||||
client,
|
|
||||||
up_token,
|
up_token,
|
||||||
down_token,
|
down_token,
|
||||||
"UP",
|
"UP",
|
||||||
@@ -97,7 +98,6 @@ async def main():
|
|||||||
|
|
||||||
elif trading_side == SIGNALES.DOWN:
|
elif trading_side == SIGNALES.DOWN:
|
||||||
await place_anchor_and_hedge(
|
await place_anchor_and_hedge(
|
||||||
client,
|
|
||||||
up_token,
|
up_token,
|
||||||
down_token,
|
down_token,
|
||||||
"DOWN",
|
"DOWN",
|
||||||
@@ -114,12 +114,12 @@ async def main():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
try:
|
if os.name == "nt":
|
||||||
|
asyncio.run(main())
|
||||||
|
else:
|
||||||
import uvloop
|
import uvloop
|
||||||
|
|
||||||
uvloop.run(main())
|
uvloop.run(main())
|
||||||
except ImportError:
|
|
||||||
asyncio.run(main())
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("\nMarket maker stopped by user")
|
print("\nMarket maker stopped by user")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from py_clob_client.client import ClobClient
|
||||||
|
from config import POLYMARKET_HOST, CHAIN_ID
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
PRIVATE_KEY = os.getenv("PRIVATE_KEY")
|
||||||
|
POLYMARKET_PROXY_ADDRESS = os.getenv("POLYMARKET_PROXY_ADDRESS")
|
||||||
|
SIGNATURE_TYPE = os.getenv("SIGNATURE_TYPE")
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
_client = None
|
||||||
|
_client_creds = None
|
||||||
|
|
||||||
|
|
||||||
|
def init_clob_client() -> ClobClient:
|
||||||
|
try:
|
||||||
|
client = ClobClient(
|
||||||
|
POLYMARKET_HOST,
|
||||||
|
key=PRIVATE_KEY,
|
||||||
|
chain_id=CHAIN_ID,
|
||||||
|
signature_type=int(SIGNATURE_TYPE),
|
||||||
|
funder=POLYMARKET_PROXY_ADDRESS,
|
||||||
|
)
|
||||||
|
creds = client.create_or_derive_api_creds()
|
||||||
|
client.set_api_creds(creds)
|
||||||
|
logger.info("ClobClient initialized successfully")
|
||||||
|
return client, creds
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to initialize ClobClient: {e}")
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
|
def init_global_client():
|
||||||
|
global _client, _client_creds
|
||||||
|
_client, _client_creds = init_clob_client()
|
||||||
|
|
||||||
|
|
||||||
|
def is_client_ready():
|
||||||
|
return _client is not None
|
||||||
|
|
||||||
|
|
||||||
|
def get_client():
|
||||||
|
if _client is None:
|
||||||
|
init_clob_client()
|
||||||
|
return _client
|
||||||
|
|
||||||
|
|
||||||
|
def get_client_creds():
|
||||||
|
if _client_creds is None:
|
||||||
|
init_clob_client()
|
||||||
|
return _client_creds
|
||||||
@@ -1,42 +1,19 @@
|
|||||||
import os
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from dotenv import load_dotenv
|
|
||||||
from py_clob_client.client import ClobClient
|
from py_clob_client.client import ClobClient
|
||||||
from py_clob_client.clob_types import OrderArgs
|
from py_clob_client.clob_types import OrderArgs
|
||||||
from py_clob_client.order_builder.constants import BUY
|
from py_clob_client.order_builder.constants import BUY
|
||||||
from config import POLYMARKET_HOST, CHAIN_ID, PROFIT_MARGIN
|
from config import PROFIT_MARGIN, PLACE_OPPOSITE_ORDER
|
||||||
|
from utils.clob_client import get_client
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
PRIVATE_KEY = os.getenv("PRIVATE_KEY")
|
|
||||||
POLYMARKET_PROXY_ADDRESS = os.getenv("POLYMARKET_PROXY_ADDRESS")
|
|
||||||
SIGNATURE_TYPE = os.getenv("SIGNATURE_TYPE")
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def init_clob_client() -> ClobClient:
|
|
||||||
try:
|
|
||||||
client = ClobClient(
|
|
||||||
POLYMARKET_HOST,
|
|
||||||
key=PRIVATE_KEY,
|
|
||||||
chain_id=CHAIN_ID,
|
|
||||||
signature_type=int(SIGNATURE_TYPE),
|
|
||||||
funder=POLYMARKET_PROXY_ADDRESS,
|
|
||||||
)
|
|
||||||
client.set_api_creds(client.create_or_derive_api_creds())
|
|
||||||
logger.info("ClobClient initialized successfully")
|
|
||||||
return client
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to initialize ClobClient: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
async def cache_tocken_trading_infos(
|
async def cache_tocken_trading_infos(
|
||||||
client: ClobClient,
|
|
||||||
order_book,
|
order_book,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
client = get_client()
|
||||||
|
|
||||||
up_token_id, down_token_id = order_book.up_token_id, order_book.down_token_id
|
up_token_id, down_token_id = order_book.up_token_id, order_book.down_token_id
|
||||||
client.get_tick_size(up_token_id)
|
client.get_tick_size(up_token_id)
|
||||||
@@ -48,7 +25,7 @@ async def cache_tocken_trading_infos(
|
|||||||
|
|
||||||
|
|
||||||
async def place_anchor_and_hedge(
|
async def place_anchor_and_hedge(
|
||||||
client, up_token_id, down_token_id, anchor_side, price, size=5
|
up_token_id, down_token_id, anchor_side, price, size=5
|
||||||
):
|
):
|
||||||
if anchor_side == "UP":
|
if anchor_side == "UP":
|
||||||
anchor_token_id = up_token_id
|
anchor_token_id = up_token_id
|
||||||
@@ -57,15 +34,19 @@ async def place_anchor_and_hedge(
|
|||||||
anchor_token_id = down_token_id
|
anchor_token_id = down_token_id
|
||||||
hedge_token_id = up_token_id
|
hedge_token_id = up_token_id
|
||||||
|
|
||||||
asyncio.create_task(place_limit_order(client, anchor_token_id, price, size))
|
asyncio.create_task(place_limit_order(anchor_token_id, price, size))
|
||||||
asyncio.create_task(
|
if PLACE_OPPOSITE_ORDER:
|
||||||
place_limit_order(client, hedge_token_id, 1 - price - PROFIT_MARGIN, size)
|
asyncio.create_task(
|
||||||
)
|
place_limit_order(hedge_token_id, 1 - price - PROFIT_MARGIN, size)
|
||||||
|
)
|
||||||
|
|
||||||
logger.info(f"Order prices: {price} and {1 - price - PROFIT_MARGIN}")
|
logger.info(f"Order prices: {price} and {1 - price - PROFIT_MARGIN}")
|
||||||
|
else:
|
||||||
|
logger.info(f"Order price: {price}")
|
||||||
|
|
||||||
|
|
||||||
async def place_limit_order(client: ClobClient, token_id: str, price: float, size: int):
|
async def place_limit_order(token_id: str, price: float, size: int):
|
||||||
|
client = get_client()
|
||||||
start_time = asyncio.get_event_loop().time()
|
start_time = asyncio.get_event_loop().time()
|
||||||
try:
|
try:
|
||||||
response = client.create_and_post_order(
|
response = client.create_and_post_order(
|
||||||
@@ -83,3 +64,4 @@ async def place_limit_order(client: ClobClient, token_id: str, price: float, siz
|
|||||||
logger.info(
|
logger.info(
|
||||||
f"Order placed! ID: {response['orderID']} in {end_time - start_time:.2f} sec"
|
f"Order placed! ID: {response['orderID']} in {end_time - start_time:.2f} sec"
|
||||||
)
|
)
|
||||||
|
return response["orderID"]
|
||||||
+2
-1
@@ -8,6 +8,7 @@ import threading
|
|||||||
import websocket
|
import websocket
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from config import POLYMARKET_WS_MARKET_URL, TRADING_BPS_THRESHOLD
|
from config import POLYMARKET_WS_MARKET_URL, TRADING_BPS_THRESHOLD
|
||||||
|
from utils.clob_client import get_client
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ class OrderBook:
|
|||||||
self.down_token_id = down_token_id
|
self.down_token_id = down_token_id
|
||||||
self.slug = slug
|
self.slug = slug
|
||||||
self.ws_url = POLYMARKET_WS_MARKET_URL
|
self.ws_url = POLYMARKET_WS_MARKET_URL
|
||||||
self.client = None
|
self.client = get_client()
|
||||||
|
|
||||||
self.orderbook = {
|
self.orderbook = {
|
||||||
"best_bid": 0.0,
|
"best_bid": 0.0,
|
||||||
|
|||||||
Reference in New Issue
Block a user