update
This commit is contained in:
parent
9f796d1efc
commit
20c9333b2f
@ -90,6 +90,22 @@ class CryptoAgent:
|
||||
await self.telegram.send_message(message)
|
||||
logger.info(f"已发送挂单成交通知: {result.get('order_id')}")
|
||||
|
||||
async def _notify_pending_cancelled(self, result: Dict[str, Any]):
|
||||
"""发送挂单撤销通知"""
|
||||
side_text = "做多" if result.get('side') == 'long' else "做空"
|
||||
new_side_text = "做多" if result.get('new_side') == 'long' else "做空"
|
||||
|
||||
message = f"""⚠️ 挂单撤销
|
||||
|
||||
交易对: {result.get('symbol')}
|
||||
原方向: {side_text}
|
||||
挂单价: ${result.get('entry_price', 0):,.2f}
|
||||
原因: 收到反向{new_side_text}信号,自动撤销"""
|
||||
|
||||
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]):
|
||||
"""发送订单平仓通知"""
|
||||
status = result.get('status', '')
|
||||
@ -312,7 +328,15 @@ class CryptoAgent:
|
||||
if grade != 'D':
|
||||
# 转换信号格式以兼容 paper_trading
|
||||
paper_signal = self._convert_to_paper_signal(symbol, best_signal, current_price)
|
||||
order = self.paper_trading.create_order_from_signal(paper_signal)
|
||||
result = self.paper_trading.create_order_from_signal(paper_signal)
|
||||
|
||||
# 发送被取消挂单的通知
|
||||
cancelled_orders = result.get('cancelled_orders', [])
|
||||
for cancelled in cancelled_orders:
|
||||
await self._notify_pending_cancelled(cancelled)
|
||||
|
||||
# 记录新订单
|
||||
order = result.get('order')
|
||||
if order:
|
||||
logger.info(f" 📝 已创建模拟订单: {order.order_id}")
|
||||
else:
|
||||
|
||||
@ -61,7 +61,7 @@ class PaperTradingService:
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def create_order_from_signal(self, signal: Dict[str, Any], current_price: float = None) -> Optional[PaperOrder]:
|
||||
def create_order_from_signal(self, signal: Dict[str, Any], current_price: float = None) -> Dict[str, Any]:
|
||||
"""
|
||||
从交易信号创建模拟订单
|
||||
|
||||
@ -80,11 +80,13 @@ class PaperTradingService:
|
||||
current_price: 当前价格(用于市价单)
|
||||
|
||||
Returns:
|
||||
创建的订单或 None
|
||||
包含 'order' 和 'cancelled_orders' 的字典
|
||||
"""
|
||||
result = {'order': None, 'cancelled_orders': []}
|
||||
|
||||
action = signal.get('action')
|
||||
if action not in ['buy', 'sell']:
|
||||
return None
|
||||
return result
|
||||
|
||||
symbol = signal.get('symbol', 'UNKNOWN')
|
||||
side = OrderSide.LONG if action == 'buy' else OrderSide.SHORT
|
||||
@ -92,7 +94,8 @@ class PaperTradingService:
|
||||
|
||||
# === 反向订单处理 ===
|
||||
# 1. 总是取消同一交易对的反向挂单(混合策略)
|
||||
self._cancel_opposite_pending_orders(symbol, side)
|
||||
cancelled_orders = self._cancel_opposite_pending_orders(symbol, side)
|
||||
result['cancelled_orders'] = cancelled_orders
|
||||
|
||||
# 2. 可选:智能平掉反向持仓(需要配置启用)
|
||||
if self.auto_close_opposite and current_price:
|
||||
@ -104,7 +107,7 @@ class PaperTradingService:
|
||||
total_orders = len(self.active_orders)
|
||||
if total_orders >= self.max_orders:
|
||||
logger.info(f"订单限制: 已达到最大订单数 {self.max_orders},跳过")
|
||||
return None
|
||||
return result
|
||||
|
||||
# 2. 检查是否有接近的挂单(价格差距 < 1%)
|
||||
same_direction_orders = [
|
||||
@ -119,13 +122,13 @@ class PaperTradingService:
|
||||
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
|
||||
return result
|
||||
|
||||
# 获取信号等级
|
||||
grade = signal.get('signal_grade') or signal.get('grade', 'D')
|
||||
if grade == 'D':
|
||||
logger.info(f"D级信号不开仓: {signal.get('symbol')}")
|
||||
return None
|
||||
return result
|
||||
|
||||
# 固定使用保证金(不再根据等级区分)
|
||||
margin = self.margin_per_order # 每单固定 1000 USDT 保证金
|
||||
@ -184,12 +187,13 @@ class PaperTradingService:
|
||||
status_text = "已开仓" if status == OrderStatus.OPEN else "等待触发"
|
||||
logger.info(f"创建模拟订单: {order_id} | {symbol} {side.value} [{entry_type_text}] @ ${entry_price:,.2f} | {status_text}")
|
||||
logger.info(f" 保证金: ${margin:,.0f} | 杠杆: {self.leverage}x | 持仓价值: ${position_value:,.0f} | 当前订单数: {len(self.active_orders)}/{self.max_orders}")
|
||||
return order
|
||||
result['order'] = order
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"创建模拟订单失败: {e}")
|
||||
db.rollback()
|
||||
return None
|
||||
return result
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
@ -485,7 +489,7 @@ class PaperTradingService:
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def _cancel_opposite_pending_orders(self, symbol: str, new_side: OrderSide) -> int:
|
||||
def _cancel_opposite_pending_orders(self, symbol: str, new_side: OrderSide) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
取消同一交易对的反向挂单
|
||||
|
||||
@ -494,7 +498,7 @@ class PaperTradingService:
|
||||
new_side: 新信号的方向
|
||||
|
||||
Returns:
|
||||
取消的订单数量
|
||||
被取消的订单信息列表
|
||||
"""
|
||||
# 找出所有反向挂单
|
||||
opposite_side = OrderSide.SHORT if new_side == OrderSide.LONG else OrderSide.LONG
|
||||
@ -506,19 +510,22 @@ class PaperTradingService:
|
||||
]
|
||||
|
||||
if not opposite_pending:
|
||||
return 0
|
||||
return []
|
||||
|
||||
cancelled_count = 0
|
||||
cancelled_orders = []
|
||||
for order in opposite_pending:
|
||||
result = self._cancel_pending_order(order)
|
||||
if result:
|
||||
cancelled_count += 1
|
||||
result['event_type'] = 'pending_cancelled'
|
||||
result['new_side'] = new_side.value
|
||||
result['reason'] = f'收到反向{new_side.value}信号,自动撤销'
|
||||
cancelled_orders.append(result)
|
||||
logger.info(f"自动取消反向挂单: {order.order_id} | {symbol} {opposite_side.value} @ ${order.entry_price:,.2f}")
|
||||
|
||||
if cancelled_count > 0:
|
||||
logger.info(f"已取消 {cancelled_count} 个反向挂单({symbol} {opposite_side.value}),新信号方向: {new_side.value}")
|
||||
if cancelled_orders:
|
||||
logger.info(f"已取消 {len(cancelled_orders)} 个反向挂单({symbol} {opposite_side.value}),新信号方向: {new_side.value}")
|
||||
|
||||
return cancelled_count
|
||||
return cancelled_orders
|
||||
|
||||
def _close_opposite_positions(self, symbol: str, new_side: OrderSide, signal_grade: str, current_price: float) -> int:
|
||||
"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user