Add inventory management with configurable limits and updater thread
This commit is contained in:
@@ -10,6 +10,7 @@ TRADING_BPS_THRESHOLD = 50
|
|||||||
MAX_TRADING_BPS_THRESHOLD = 100
|
MAX_TRADING_BPS_THRESHOLD = 100
|
||||||
MARKET_SESSION_SECONDS = 900
|
MARKET_SESSION_SECONDS = 900
|
||||||
TIMEZONE = "US/Eastern"
|
TIMEZONE = "US/Eastern"
|
||||||
MAX_TRADES = 1
|
MAX_TRADES = 30
|
||||||
|
MAX_INVENTORY = 1
|
||||||
MIN_DELAY_BETWEEN_TRADES_SECONDS = 1
|
MIN_DELAY_BETWEEN_TRADES_SECONDS = 1
|
||||||
PLACE_OPPOSITE_ORDER = True # Hedge orders
|
PLACE_OPPOSITE_ORDER = True # Hedge orders
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from config import (
|
|||||||
MAX_TRADES,
|
MAX_TRADES,
|
||||||
MAX_TRADING_BPS_THRESHOLD,
|
MAX_TRADING_BPS_THRESHOLD,
|
||||||
MIN_DELAY_BETWEEN_TRADES_SECONDS,
|
MIN_DELAY_BETWEEN_TRADES_SECONDS,
|
||||||
|
MAX_INVENTORY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ def main():
|
|||||||
down_bid_price = 1 - up_ask_price
|
down_bid_price = 1 - up_ask_price
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"Initial Prices - UP: {up_bid_price:.2f}/{up_ask_price:.2f} | DOWN: {down_bid_price:.2f}/{down_ask_price:.2f}",
|
f"Initial Prices - UP: {up_bid_price:.2f}/{up_ask_price:.2f} | DOWN: {down_bid_price:.2f}/{down_ask_price:.2f} | Inventory: {book.inventory} / {MAX_INVENTORY}",
|
||||||
flush=True,
|
flush=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ def main():
|
|||||||
down_ask_price = 1 - up_bid_price
|
down_ask_price = 1 - up_bid_price
|
||||||
down_bid_price = 1 - up_ask_price
|
down_bid_price = 1 - up_ask_price
|
||||||
|
|
||||||
if (get_trades_count() < MAX_TRADES) and (get_period_elapsed_seconds() < 500):
|
if (get_trades_count() < MAX_TRADES) and (get_period_elapsed_seconds() < 500) and (book.inventory < MAX_INVENTORY):
|
||||||
trading_side = book.last_signal
|
trading_side = book.last_signal
|
||||||
|
|
||||||
if trading_side == SIGNALES.UP:
|
if trading_side == SIGNALES.UP:
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import requests
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def get_inventory(slug=None):
|
||||||
|
|
||||||
|
url = f"https://data-api.polymarket.com/positions?sizeThreshold=1&user={os.getenv('POLYMARKET_PROXY_ADDRESS')}&mergeable=false"
|
||||||
|
|
||||||
|
response = requests.get(url).json()
|
||||||
|
size = 0
|
||||||
|
for pos in response:
|
||||||
|
if pos and pos.get("slug") == slug:
|
||||||
|
size += pos.get("size")
|
||||||
|
print(pos)
|
||||||
|
return round(size / 5)
|
||||||
+27
-2
@@ -10,6 +10,7 @@ from config import POLYMARKET_WS_MARKET_URL, TRADING_BPS_THRESHOLD
|
|||||||
from py_clob_client import OrderArgs
|
from py_clob_client import OrderArgs
|
||||||
from py_clob_client.order_builder.constants import BUY
|
from py_clob_client.order_builder.constants import BUY
|
||||||
from utils.clob_client import get_client
|
from utils.clob_client import get_client
|
||||||
|
from utils.inventory import get_inventory
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -46,6 +47,9 @@ class OrderBook:
|
|||||||
self.monitoring_running = False
|
self.monitoring_running = False
|
||||||
|
|
||||||
self.last_signal = SIGNALES.NEUTRAL
|
self.last_signal = SIGNALES.NEUTRAL
|
||||||
|
self.inventory = 0
|
||||||
|
self.inventory_thread = None
|
||||||
|
self.inventory_running = False
|
||||||
self.create_signed_orders_cache()
|
self.create_signed_orders_cache()
|
||||||
|
|
||||||
def _on_message(self, ws, message):
|
def _on_message(self, ws, message):
|
||||||
@@ -104,6 +108,7 @@ class OrderBook:
|
|||||||
|
|
||||||
self.running = True
|
self.running = True
|
||||||
self.monitoring_running = True
|
self.monitoring_running = True
|
||||||
|
self.inventory_running = True
|
||||||
|
|
||||||
self.thread = threading.Thread(target=self._connect, daemon=True)
|
self.thread = threading.Thread(target=self._connect, daemon=True)
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
@@ -113,16 +118,36 @@ class OrderBook:
|
|||||||
)
|
)
|
||||||
self.monitoring_thread.start()
|
self.monitoring_thread.start()
|
||||||
|
|
||||||
logger.info("WebSocket price stream and trading monitor started")
|
self.inventory_thread = threading.Thread(
|
||||||
|
target=self._inventory_updater, daemon=True
|
||||||
|
)
|
||||||
|
self.inventory_thread.start()
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"WebSocket price stream, trading monitor, and inventory updater started"
|
||||||
|
)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.running = False
|
self.running = False
|
||||||
self.monitoring_running = False
|
self.monitoring_running = False
|
||||||
|
self.inventory_running = False
|
||||||
|
|
||||||
if self.ws:
|
if self.ws:
|
||||||
self.ws.close()
|
self.ws.close()
|
||||||
|
|
||||||
logger.info("🛑 WebSocket price stream and trading monitor stopped")
|
logger.info(
|
||||||
|
"🛑 WebSocket price stream, trading monitor, and inventory updater stopped"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _inventory_updater(self):
|
||||||
|
logger.info("Started inventory updater thread")
|
||||||
|
while self.inventory_running:
|
||||||
|
try:
|
||||||
|
self.inventory = get_inventory(self.slug)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error updating inventory: {e}")
|
||||||
|
time.sleep(2)
|
||||||
|
logger.info("Stopped inventory updater thread")
|
||||||
|
|
||||||
def is_connected(self):
|
def is_connected(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
|
|||||||
Reference in New Issue
Block a user