Browse Source

Update trading configuration and enhance order placement in HyperliquidClient

- Changed the default trading token from BTC to SUI in the environment configuration.
- Added a new margin mode configuration option for Hyperliquid, defaulting to 'ISOLATED'.
- Simplified the limit and market order methods in HyperliquidClient by integrating margin mode into order parameters.
- Improved logging for order placement success and error handling for better clarity.
Carles Sentis 2 days ago
parent
commit
8edcaa6b3a
4 changed files with 30 additions and 65 deletions
  1. 5 2
      config/env.example
  2. 23 62
      src/clients/hyperliquid_client.py
  3. 1 0
      src/config/config.py
  4. 1 1
      trading_bot.py

+ 5 - 2
config/env.example

@@ -17,7 +17,7 @@ HYPERLIQUID_TESTNET=true
 # Trading Bot Configuration
 # ========================================
 # Default token for market/price commands (when no token specified)
-DEFAULT_TRADING_TOKEN=BTC
+DEFAULT_TRADING_TOKEN=SUI
 
 # Risk management settings
 RISK_MANAGEMENT_ENABLED=true
@@ -84,4 +84,7 @@ LOG_MAX_SIZE_MB=10
 LOG_ROTATION_INTERVAL=midnight
 
 # Number of backup log files to keep (older files are automatically deleted)
-LOG_BACKUP_COUNT=5 
+LOG_BACKUP_COUNT=5
+
+# Trading
+HYPERLIQUID_MARGIN_MODE=ISOLATED 

+ 23 - 62
src/clients/hyperliquid_client.py

@@ -290,92 +290,53 @@ class HyperliquidClient:
             return None
     
     def place_limit_order(self, symbol: str, side: str, amount: float, price: float, params: Optional[Dict] = None) -> Tuple[Optional[Dict[str, Any]], Optional[str]]:
-        """
-        Place a limit order with CCXT-style parameters.
-        Returns a tuple: (order_object, error_message_string).
-        Error_message_string is None on success. Order_object is None on failure.
-        
-        Args:
-            symbol: Trading symbol (e.g., 'BTC/USDC:USDC')
-            side: 'buy' or 'sell'
-            amount: Order amount
-            price: Order price
-            params: Additional parameters for CCXT compatibility
-        """
+        """Place a limit order."""
         try:
             if not self.sync_client:
                 logger.error("❌ Client not initialized")
                 return None, "Client not initialized"
-            
-            # CCXT-style order creation
+
             order_params = params or {}
+            # Add margin mode from config
+            if Config.HYPERLIQUID_MARGIN_MODE:
+                order_params['marginMode'] = Config.HYPERLIQUID_MARGIN_MODE.lower()
+
+            logger.info(f"Placing limit order: {side} {amount} {symbol} @ {price} with params {order_params}")
             order = self.sync_client.create_limit_order(symbol, side, amount, price, params=order_params)
             
-            logger.info(f"✅ Successfully placed {side} limit order for {amount} {symbol} at ${price}")
-            logger.debug(f"📄 Order details: {order}")
-            
+            logger.info(f"✅ Limit order placed successfully: {order}")
             return order, None
         except Exception as e:
             error_message = self._extract_error_message(e)
-            logger.error(f"❌ Error placing limit order: {error_message} (Full exception: {e})")
+            logger.error(f"❌ Error placing limit order: {error_message}")
             return None, error_message
-    
-    def place_market_order(self, symbol: str, side: str, amount: float, params: Optional[Dict] = None) -> Tuple[Optional[Dict[str, Any]], Optional[str]]:
-        """
-        Place a market order with CCXT-style parameters.
-        Returns a tuple: (order_object, error_message_string).
-        Error_message_string is None on success. Order_object is None on failure.
 
-        Args:
-            symbol: Trading symbol (e.g., 'BTC/USDC:USDC')
-            side: 'buy' or 'sell'
-            amount: Order amount
-            params: Additional parameters for CCXT compatibility
-        """
+    def place_market_order(self, symbol: str, side: str, amount: float, params: Optional[Dict] = None) -> Tuple[Optional[Dict[str, Any]], Optional[str]]:
+        """Place a market order."""
         try:
             if not self.sync_client:
                 logger.error("❌ Client not initialized")
                 return None, "Client not initialized"
-            
-            # Get current market price for slippage calculation
-            ticker = self.sync_client.fetch_ticker(symbol)
-            if not ticker:
-                logger.error(f"❌ Could not fetch ticker for {symbol}")
-                return None, f"Could not fetch ticker for {symbol}"
-                
-            current_price = ticker.get('last')
-            if not current_price:
-                logger.error(f"❌ Could not get current price for {symbol}")
-                return None, f"Could not get current price for {symbol}"
-            
-            # Apply slippage tolerance (default 0.5% for market orders)
-            slippage_percent = 0.5  # 0.5% slippage
-            if side == 'buy':
-                # For buy orders, increase price to ensure fill
-                slippage_price = current_price * (1 + slippage_percent / 100)
-            else:
-                # For sell orders, decrease price to ensure fill
-                slippage_price = current_price * (1 - slippage_percent / 100)
-            
-            logger.info(f"🔄 Market order: {side} {amount} {symbol} @ current ${current_price:.2f} (slippage price: ${slippage_price:.2f})")
-            
-            # CCXT-style order creation with price for slippage
+
             order_params = params or {}
-            order_params['price'] = slippage_price  # Add price for slippage calculation
-            
-            order = self.sync_client.create_market_order(symbol, side, amount, price=slippage_price, params=order_params)
+            # Add margin mode from config
+            if Config.HYPERLIQUID_MARGIN_MODE:
+                order_params['marginMode'] = Config.HYPERLIQUID_MARGIN_MODE.lower()
+
+            logger.info(f"Placing market order: {side} {amount} {symbol} with params {order_params}")
             
-            logger.info(f"✅ Successfully placed {side} market order for {amount} {symbol}")
-            logger.debug(f"📄 Order details: {order}")
+            # Use create_market_order for market orders
+            order = self.sync_client.create_market_order(symbol, side, amount, params=order_params)
             
+            logger.info(f"✅ Market order placed successfully: {order}")
             return order, None
         except Exception as e:
             error_message = self._extract_error_message(e)
-            logger.error(f"❌ Error placing market order: {error_message} (Full exception: {e})")
+            logger.error(f"❌ Error placing market order: {error_message}")
             return None, error_message
-    
+
     def get_open_orders(self, symbol: Optional[str] = None) -> Optional[List[Dict[str, Any]]]:
-        """Get open orders."""
+        """Get all open orders for a symbol or all symbols."""
         try:
             if not self.sync_client:
                 logger.error("❌ Client not initialized")

+ 1 - 0
src/config/config.py

@@ -19,6 +19,7 @@ class Config:
     HYPERLIQUID_SECRET_KEY: Optional[str] = os.getenv('HYPERLIQUID_SECRET_KEY')    # API generator key
     HYPERLIQUID_WALLET_ADDRESS: Optional[str] = os.getenv('HYPERLIQUID_WALLET_ADDRESS')  # Wallet address
     HYPERLIQUID_TESTNET: bool = get_bool_env('HYPERLIQUID_TESTNET', 'true')
+    HYPERLIQUID_MARGIN_MODE = os.getenv('HYPERLIQUID_MARGIN_MODE', 'ISOLATED').upper()
     
     # Trading Bot Configuration
     DEFAULT_TRADING_TOKEN: str = os.getenv('DEFAULT_TRADING_TOKEN', 'BTC')

+ 1 - 1
trading_bot.py

@@ -14,7 +14,7 @@ from datetime import datetime
 from pathlib import Path
 
 # Bot version
-BOT_VERSION = "2.4.264"
+BOT_VERSION = "2.4.265"
 
 # Add src directory to Python path
 sys.path.insert(0, str(Path(__file__).parent / "src"))