From 6739e0124fc34f85fef4c35a68f3e47870b0391e Mon Sep 17 00:00:00 2001 From: aaron <> Date: Tue, 10 Feb 2026 23:20:30 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8C=82=E5=8D=95=E6=88=90?= =?UTF-8?q?=E4=BA=A4=E9=80=9A=E7=9F=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/crypto_agent/crypto_agent.py | 29 +++++++++++++- backend/app/services/paper_trading_service.py | 39 +++++++++++++++---- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/backend/app/crypto_agent/crypto_agent.py b/backend/app/crypto_agent/crypto_agent.py index 1aa935c..7ec204f 100644 --- a/backend/app/crypto_agent/crypto_agent.py +++ b/backend/app/crypto_agent/crypto_agent.py @@ -61,9 +61,34 @@ class CryptoAgent: for result in triggered: if self._event_loop and self._event_loop.is_running(): - asyncio.run_coroutine_threadsafe(self._notify_order_closed(result), self._event_loop) + # 根据事件类型选择不同的通知方法 + event_type = result.get('event_type', 'order_closed') + if event_type == 'order_filled': + asyncio.run_coroutine_threadsafe(self._notify_order_filled(result), self._event_loop) + else: + asyncio.run_coroutine_threadsafe(self._notify_order_closed(result), self._event_loop) else: - logger.warning(f"无法发送平仓通知: 事件循环不可用") + logger.warning(f"无法发送通知: 事件循环不可用") + + async def _notify_order_filled(self, result: Dict[str, Any]): + """发送挂单成交通知""" + side_text = "做多" if result.get('side') == 'long' else "做空" + grade = result.get('signal_grade', 'N/A') + + message = f"""✅ 挂单成交 + +交易对: {result.get('symbol')} +方向: {side_text} +等级: {grade} +挂单价: ${result.get('entry_price', 0):,.2f} +成交价: ${result.get('filled_price', 0):,.2f} +仓位: ${result.get('quantity', 0):,.0f} +止损: ${result.get('stop_loss', 0):,.2f} +止盈: ${result.get('take_profit', 0):,.2f}""" + + await self.feishu.send_text(message) + await self.telegram.send_message(message) + logger.info(f"已发送挂单成交通知: {result.get('order_id')}") async def _notify_order_closed(self, result: Dict[str, Any]): """发送订单平仓通知""" diff --git a/backend/app/services/paper_trading_service.py b/backend/app/services/paper_trading_service.py index 3121296..e91ab6a 100644 --- a/backend/app/services/paper_trading_service.py +++ b/backend/app/services/paper_trading_service.py @@ -189,7 +189,7 @@ class PaperTradingService: current_price: 当前价格 Returns: - 触发的订单结果列表(平仓结果) + 触发的订单结果列表(包括挂单激活和平仓结果) """ triggered = [] @@ -199,7 +199,9 @@ class PaperTradingService: if order.symbol == symbol and order.status == OrderStatus.PENDING ] for order in pending_orders: - if self._check_pending_entry(order, current_price): + result = self._check_pending_entry(order, current_price) + if result: + triggered.append(result) logger.info(f"挂单触发入场: {order.order_id} | {symbol} @ ${current_price:,.2f}") # 2. 检查持仓订单是否触发止盈止损 @@ -217,12 +219,15 @@ class PaperTradingService: return triggered - def _check_pending_entry(self, order: PaperOrder, current_price: float) -> bool: + def _check_pending_entry(self, order: PaperOrder, current_price: float) -> Optional[Dict[str, Any]]: """ 检查挂单是否触发入场 做多挂单:价格下跌到入场价时触发(买入) 做空挂单:价格上涨到入场价时触发(卖出) + + Returns: + 如果触发,返回激活结果字典;否则返回 None """ should_trigger = False @@ -238,10 +243,15 @@ class PaperTradingService: if should_trigger: return self._activate_pending_order(order, current_price) - return False + return None - def _activate_pending_order(self, order: PaperOrder, filled_price: float) -> bool: - """激活挂单,转为持仓""" + def _activate_pending_order(self, order: PaperOrder, filled_price: float) -> Optional[Dict[str, Any]]: + """ + 激活挂单,转为持仓 + + Returns: + 激活结果字典,包含订单信息 + """ db = db_service.get_session() try: order.status = OrderStatus.OPEN @@ -252,11 +262,24 @@ class PaperTradingService: db.commit() logger.info(f"挂单已激活: {order.order_id} | {order.symbol} {order.side.value} @ ${filled_price:,.2f}") - return True + + # 返回激活结果 + return { + 'event_type': 'order_filled', + 'order_id': order.order_id, + 'symbol': order.symbol, + 'side': order.side.value, + 'entry_price': order.entry_price, + 'filled_price': filled_price, + 'quantity': order.quantity, + 'signal_grade': order.signal_grade.value if order.signal_grade else None, + 'stop_loss': order.stop_loss, + 'take_profit': order.take_profit + } except Exception as e: logger.error(f"激活挂单失败: {e}") db.rollback() - return False + return None finally: db.close()