market cap fixes

This commit is contained in:
2025-10-25 19:58:52 +02:00
parent 5805601218
commit fe5cc8e1d1
5 changed files with 184 additions and 44 deletions

View File

@ -1,11 +1,33 @@
import logging
import json
import time
import os
import traceback
from hyperliquid.info import Info
from hyperliquid.utils import constants
from logging_utils import setup_logging
# --- Configuration for standalone error logging ---
LOGS_DIR = "_logs"
ERROR_LOG_FILE = os.path.join(LOGS_DIR, "live_market_errors.log")
def log_error(error_message: str, include_traceback: bool = True):
"""A simple, robust file logger for any errors."""
try:
if not os.path.exists(LOGS_DIR):
os.makedirs(LOGS_DIR)
with open(ERROR_LOG_FILE, 'a') as f:
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
f.write(f"--- ERROR at {timestamp} UTC ---\n")
f.write(error_message + "\n")
if include_traceback:
f.write(traceback.format_exc() + "\n")
f.write("="*50 + "\n")
except Exception:
print(f"CRITICAL: Failed to write to error log file: {error_message}", file=sys.stderr)
def on_message(message, shared_prices_dict):
"""
Callback function to process incoming 'allMids' messages and update the
@ -14,36 +36,71 @@ def on_message(message, shared_prices_dict):
try:
if message.get("channel") == "allMids":
new_prices = message.get("data", {}).get("mids", {})
# Update the shared dictionary with the new price data
shared_prices_dict.update(new_prices)
except Exception as e:
# It's important to log errors inside the process
logging.error(f"Error in WebSocket on_message: {e}")
log_error(f"Error in WebSocket on_message: {e}")
def start_live_feed(shared_prices_dict, log_level='off'):
"""
Main function for the WebSocket process. It takes a shared dictionary
and continuously feeds it with live market data.
Includes a watchdog to auto-reconnect on failure.
"""
setup_logging(log_level, 'LiveMarketFeed')
# The Info object manages the WebSocket connection.
info = Info(constants.MAINNET_API_URL, skip_ws=False)
# We need to wrap the callback in a lambda to pass our shared dictionary
info = None
callback = lambda msg: on_message(msg, shared_prices_dict)
# Subscribe to the allMids channel
subscription = {"type": "allMids"}
info.subscribe(subscription, callback)
logging.info("Subscribed to 'allMids' for live mark prices.")
def connect_and_subscribe():
"""Establishes a new WebSocket connection and subscribes to allMids."""
try:
logging.info("Connecting to Hyperliquid WebSocket...")
# Ensure skip_ws=False to create the ws_manager
new_info = Info(constants.MAINNET_API_URL, skip_ws=False)
subscription = {"type": "allMids"}
new_info.subscribe(subscription, callback)
logging.info("WebSocket connected and subscribed to 'allMids'.")
return new_info
except Exception as e:
log_error(f"Failed to connect to WebSocket: {e}")
return None
info = connect_and_subscribe()
logging.info("Starting live price feed process. Press Ctrl+C in main app to stop.")
try:
# The background thread in the SDK handles messages. This loop just keeps the process alive.
while True:
time.sleep(1)
# --- Watchdog Logic ---
time.sleep(15) # Check the connection every 15 seconds
if info is None or not info.ws_manager.is_running():
# --- FIX: Log this critical failure to the persistent error log ---
error_msg = "WebSocket connection lost or not running. Attempting to reconnect..."
logging.warning(error_msg)
log_error(error_msg, include_traceback=False) # Log it to the file
if info:
try:
info.ws_manager.stop() # Clean up old manager
except Exception as e:
log_error(f"Error stopping old ws_manager: {e}")
info = connect_and_subscribe()
if info is None:
logging.error("Reconnect failed, will retry in 15s.")
else:
logging.info("Successfully reconnected to WebSocket.")
else:
logging.debug("Watchdog check: WebSocket connection is active.")
except KeyboardInterrupt:
logging.info("Stopping WebSocket listener...")
info.ws_manager.stop()
except Exception as e:
log_error(f"Live Market Feed process crashed: {e}")
finally:
if info and info.ws_manager:
info.ws_manager.stop()
logging.info("Listener stopped.")