diff --git a/backend/app/services/paper_trading_service.py b/backend/app/services/paper_trading_service.py index 988c8b8..3121296 100644 --- a/backend/app/services/paper_trading_service.py +++ b/backend/app/services/paper_trading_service.py @@ -84,6 +84,31 @@ class PaperTradingService: if action not in ['buy', 'sell']: return None + symbol = signal.get('symbol', 'UNKNOWN') + side = OrderSide.LONG if action == 'buy' else OrderSide.SHORT + entry_price = signal.get('entry_price') or signal.get('price', 0) + + # === 限制检查 === + # 1. 同一交易对同一方向最多 3 个订单 + same_direction_orders = [ + order for order in self.active_orders.values() + if order.symbol == symbol and order.side == side + ] + if len(same_direction_orders) >= 3: + logger.info(f"订单限制: {symbol} {side.value} 方向已有 {len(same_direction_orders)} 个订单,跳过") + return None + + # 2. 检查是否有接近的挂单(价格差距 < 1%) + pending_orders = [ + order for order in same_direction_orders + if order.status == OrderStatus.PENDING + ] + for pending in pending_orders: + price_diff = abs(pending.entry_price - entry_price) / pending.entry_price + if price_diff < 0.01: # 价格差距小于 1% + logger.info(f"订单限制: {symbol} 已有接近的挂单 @ ${pending.entry_price:,.2f},新信号 @ ${entry_price:,.2f},跳过") + return None + # 获取信号等级 grade = signal.get('signal_grade') or signal.get('grade', 'D') if grade == 'D': @@ -95,18 +120,11 @@ class PaperTradingService: if quantity == 0: return None - # 确定订单方向 - side = OrderSide.LONG if action == 'buy' else OrderSide.SHORT - # 确定入场类型 entry_type_str = signal.get('entry_type', 'market') entry_type = EntryType.LIMIT if entry_type_str == 'limit' else EntryType.MARKET - # 获取入场价 - entry_price = signal.get('entry_price') or signal.get('price', 0) - # 生成订单ID - symbol = signal.get('symbol', 'UNKNOWN') order_id = f"PT-{symbol}-{datetime.now().strftime('%Y%m%d%H%M%S')}-{uuid.uuid4().hex[:6]}" # 确定订单状态和成交价