From 8dee4c8f7b89a3244486bd1a68d51e1d00783141 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Mon, 23 Mar 2026 21:33:15 +0800 Subject: [PATCH] 1 --- backend/app/crypto_agent/crypto_agent.py | 34 +++++++++++++++++-- .../services/hyperliquid_trading_service.py | 26 ++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/backend/app/crypto_agent/crypto_agent.py b/backend/app/crypto_agent/crypto_agent.py index b64a44a..4c62247 100644 --- a/backend/app/crypto_agent/crypto_agent.py +++ b/backend/app/crypto_agent/crypto_agent.py @@ -1835,11 +1835,28 @@ class CryptoAgent: # Hyperliquid 执行方法 # ============================================================ + async def _notify_hyperliquid_error(self, symbol: str, operation: str, error: str): + """发送 Hyperliquid 操作失败的飞书/钉钉/Telegram 通知""" + title = f"❌ Hyperliquid 操作失败 - {symbol}" + content = "\n".join([ + f"🔴 **操作**: {operation}", + f"⚠️ **错误**: {error}", + f"🕐 **时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", + ]) + logger.error(f"[Hyperliquid] {operation} 失败 | {symbol} | {error}") + if self.settings.feishu_enabled: + await self.feishu.send_card(title, content, "red") + if self.settings.telegram_enabled: + await self.telegram.send_message(f"{title}\n\n{content}") + if self.settings.dingtalk_enabled: + await self.dingtalk.send_action_card(title, content) + async def _execute_hyperliquid_decisions(self, decision: Dict[str, Any], market_signal: Dict[str, Any], current_price: float): """执行 Hyperliquid 决策""" decision_type = decision.get('decision', 'HOLD') # 修复:使用 'decision' 字段而不是 'action' + symbol = decision.get('symbol', 'UNKNOWN') if decision_type == 'HOLD': reasoning = decision.get('reasoning', '观望') @@ -1854,8 +1871,13 @@ class CryptoAgent: if result.get('success'): logger.info(f" ✅ Hyperliquid 交易成功") await self._send_signal_notification(market_signal, decision, current_price, prefix="[Hyperliquid]") + # 止盈止损设置失败时单独告警 + if result.get('tp_sl_warning'): + await self._notify_hyperliquid_error(symbol, "设置止盈止损", result['tp_sl_warning']) else: - logger.error(f" ❌ Hyperliquid 交易失败: {result.get('error')}") + error = result.get('error', '未知错误') + logger.error(f" ❌ Hyperliquid 交易失败: {error}") + await self._notify_hyperliquid_error(symbol, decision_type, error) elif decision_type == 'CLOSE': logger.info(f" 准备 Hyperliquid 平仓...") @@ -1865,7 +1887,9 @@ class CryptoAgent: logger.info(f" ✅ Hyperliquid 平仓成功") await self._send_signal_notification(market_signal, decision, current_price, prefix="[Hyperliquid]") else: - logger.error(f" ❌ Hyperliquid 平仓失败: {result.get('error')}") + error = result.get('error', '未知错误') + logger.error(f" ❌ Hyperliquid 平仓失败: {error}") + await self._notify_hyperliquid_error(symbol, "平仓", error) elif decision_type == 'CANCEL_PENDING': logger.info(f" 准备取消 Hyperliquid 挂单...") @@ -1874,10 +1898,13 @@ class CryptoAgent: if result.get('success'): logger.info(f" ✅ Hyperliquid 取消成功") else: - logger.error(f" ❌ Hyperliquid 取消失败: {result.get('error')}") + error = result.get('error', '未知错误') + logger.error(f" ❌ Hyperliquid 取消失败: {error}") + await self._notify_hyperliquid_error(symbol, "取消挂单", error) except Exception as e: logger.error(f" ❌ Hyperliquid 执行异常: {e}") + await self._notify_hyperliquid_error(symbol, decision_type, str(e)) async def _execute_hyperliquid_trade(self, decision: Dict[str, Any], market_signal: Dict[str, Any], @@ -1940,6 +1967,7 @@ class CryptoAgent: if not tp_sl_result.get('success'): logger.warning(f" ⚠️ 设置止盈止损失败: {tp_sl_result.get('error')}") + result['tp_sl_warning'] = tp_sl_result.get('error', '设置止盈止损失败') return result diff --git a/backend/app/services/hyperliquid_trading_service.py b/backend/app/services/hyperliquid_trading_service.py index 9f1be2c..c0fbe2f 100644 --- a/backend/app/services/hyperliquid_trading_service.py +++ b/backend/app/services/hyperliquid_trading_service.py @@ -168,6 +168,19 @@ class HyperliquidTradingService: # 开仓使用 market_open result = self.exchange.market_open(symbol, is_buy, size) + # 检查 API 响应状态 + if result.get("status") != "ok": + error_msg = result.get("response", "Unknown error") + logger.error(f"❌ Hyperliquid 市价单失败: {error_msg}") + return {"success": False, "error": str(error_msg), "result": result} + + # 检查单个订单状态 + statuses = result.get("response", {}).get("data", {}).get("statuses", []) + error_statuses = [s for s in statuses if "error" in s] + if error_statuses: + logger.error(f"❌ Hyperliquid 市价单错误: {error_statuses}") + return {"success": False, "error": str(error_statuses), "result": result} + side = "买入" if is_buy else "卖出" order_type = "平仓" if reduce_only else "开仓" logger.info(f"✅ Hyperliquid 市价单: {order_type} {side} {symbol} {size}") @@ -203,6 +216,19 @@ class HyperliquidTradingService: {"limit": {"tif": "Gtc"}}, reduce_only=reduce_only) + # 检查 API 响应状态 + if result.get("status") != "ok": + error_msg = result.get("response", "Unknown error") + logger.error(f"❌ Hyperliquid 限价单失败: {error_msg}") + return {"success": False, "error": str(error_msg), "result": result} + + # 检查单个订单状态 + statuses = result.get("response", {}).get("data", {}).get("statuses", []) + error_statuses = [s for s in statuses if "error" in s] + if error_statuses: + logger.error(f"❌ Hyperliquid 限价单错误: {error_statuses}") + return {"success": False, "error": str(error_statuses), "result": result} + side = "买入" if is_buy else "卖出" logger.info(f"✅ Hyperliquid 限价单: {side} {symbol} {size} @ ${price}")