diff --git a/backend/app/crypto_agent/crypto_agent.py b/backend/app/crypto_agent/crypto_agent.py index 54e3e3c..48fc605 100644 --- a/backend/app/crypto_agent/crypto_agent.py +++ b/backend/app/crypto_agent/crypto_agent.py @@ -12,7 +12,6 @@ from app.services.binance_service import binance_service from app.services.feishu_service import get_feishu_service from app.services.telegram_service import get_telegram_service from app.services.paper_trading_service import get_paper_trading_service -from app.services.price_monitor_service import get_price_monitor_service from app.services.signal_database_service import get_signal_db_service from app.crypto_agent.llm_signal_analyzer import LLMSignalAnalyzer @@ -47,11 +46,8 @@ class CryptoAgent: self.paper_trading_enabled = self.settings.paper_trading_enabled if self.paper_trading_enabled: self.paper_trading = get_paper_trading_service() - self.price_monitor = get_price_monitor_service() - self.price_monitor.add_price_callback(self._on_price_update) else: self.paper_trading = None - self.price_monitor = None # 状态管理 self.last_signals: Dict[str, Dict[str, Any]] = {} @@ -206,19 +202,10 @@ class CryptoAgent: logger.info(f" 模拟交易: 已启用") logger.info("=" * 60 + "\n") - # 启动价格监控(轮询模式) - if self.paper_trading_enabled and self.symbols: - try: - from app.services.price_monitor_service import get_price_monitor_service - self.price_monitor = get_price_monitor_service() - - for symbol in self.symbols: - self.price_monitor.subscribe_symbol(symbol) - self.price_monitor.add_price_callback(self._on_price_update) - - logger.info(f"已启动轮询模式价格监控: {', '.join(self.symbols)}") - except Exception as e: - logger.error(f"价格监控启动失败: {e}") + # 注意:不再启动独立的价格监控 + # 价格监控由 main.py 中的 price_monitor_loop 统一处理,避免重复检查 + if self.paper_trading_enabled: + logger.info(f"模拟交易已启用(由后台统一监控)") # 发送启动通知 await self.feishu.send_text( @@ -259,11 +246,6 @@ class CryptoAgent: def stop(self): """停止运行""" self.running = False - - # 停止轮询价格监控 - if hasattr(self, 'price_monitor') and self.price_monitor: - self.price_monitor.stop() - logger.info("加密货币智能体已停止") async def analyze_symbol(self, symbol: str): diff --git a/backend/app/services/paper_trading_service.py b/backend/app/services/paper_trading_service.py index c7a5d5b..587bf6a 100644 --- a/backend/app/services/paper_trading_service.py +++ b/backend/app/services/paper_trading_service.py @@ -96,12 +96,21 @@ class PaperTradingService: # 使用 make_transient 将对象从会话中分离,使其成为独立对象 from sqlalchemy.orm import make_transient + loaded_count = 0 + skipped_count = 0 for order in orders: + # 跳过异常订单:OPEN 状态但 filled_price 为 0 或 None + if order.status == OrderStatus.OPEN and (not order.filled_price or order.filled_price <= 0): + logger.warning(f"跳过异常订单 {order.order_id} | {order.symbol} | 状态: {order.status.value} | filled_price: {order.filled_price}") + skipped_count += 1 + continue + db.expunge(order) # 从会话中移除 make_transient(order) # 使对象独立 self.active_orders[order.order_id] = order + loaded_count += 1 - logger.info(f"已加载 {len(orders)} 个活跃订单") + logger.info(f"已加载 {loaded_count} 个活跃订单 (跳过 {skipped_count} 个异常订单)") except Exception as e: logger.error(f"加载活跃订单失败: {e}") finally: @@ -470,6 +479,11 @@ class PaperTradingService: def _check_order_trigger(self, order: PaperOrder, current_price: float) -> Optional[Dict[str, Any]]: """检查单个订单是否触发""" + # 防御性检查:如果 filled_price 为 0 或 None,说明订单未正确激活,跳过检查 + if not order.filled_price or order.filled_price <= 0: + logger.warning(f"订单 {order.order_id} 的成交价无效: {order.filled_price},跳过止盈止损检查") + return None + triggered = False new_status = None exit_price = current_price @@ -518,6 +532,11 @@ class PaperTradingService: logger.error(f"数据库中未找到订单: {order.order_id}") return None + # 防御性检查:如果 filled_price 为 0 或 None,无法计算盈亏 + if not db_order.filled_price or db_order.filled_price <= 0: + logger.error(f"订单 {db_order.order_id} 的成交价无效: {db_order.filled_price},无法平仓") + return None + # 计算盈亏 if db_order.side == OrderSide.LONG: pnl_percent = ((exit_price - db_order.filled_price) / db_order.filled_price) * 100