|
@@ -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")
|