This commit is contained in:
aaron 2026-03-29 10:35:22 +08:00
parent 8fbbe3cbc1
commit 599a3498ba
4 changed files with 209 additions and 47 deletions

View File

@ -716,13 +716,14 @@ class CryptoAgent:
'symbol': symbol,
'action': signal_action,
'confidence': main_signal.get('confidence', 50),
'grade': main_signal.get('grade', 'C'), # 添加信号等级
'entry_price': main_signal.get('entry_price', current_price),
'stop_loss': main_signal.get('stop_loss'),
'take_profit': main_signal.get('take_profit'),
'reasoning': main_signal.get('reasoning', ''),
}
logger.info(f" 信号: {signal_action} {symbol} @ ${trading_signal['entry_price']:.2f} (置信度 {trading_signal['confidence']}%)")
logger.info(f" 信号: {signal_action} {symbol} @ ${trading_signal['entry_price']:.2f} (置信度 {trading_signal['confidence']}%, {trading_signal['grade']})")
# 2.1 模拟盘处理
if self.settings.paper_trading_enabled:

View File

@ -64,28 +64,21 @@ class BitgetExecutor(BaseExecutor):
order_id = result.get('order_id')
order_status = result.get('order_status', 'filled')
# 设置止盈止损(成交后)
# 设置止盈止损
# 策略:总是记录到 pending由定期检查机制处理
# 原因Bitget 的持仓确认可能有延迟,立即设置可能失败
if stop_loss or take_profit:
if order_status == 'filled':
# 已成交,立即设置
tp_sl_result = self.bitget.set_tp_sl(
symbol=symbol,
is_long=is_buy,
size=contracts,
tp_price=take_profit,
sl_price=stop_loss
)
if not tp_sl_result.get('success'):
logger.warning(f" ⚠️ 止盈止损设置失败: {tp_sl_result.get('error')}")
result['tp_sl_warning'] = tp_sl_result.get('error')
else:
# 挂单中,记录到待处理列表
logger.info(f" 📌 挌单中TP/SL 将在成交后设置")
# 由 crypto_agent 的循环检查机制处理
# 返回给 crypto_agent 的 pending_tp_sl 格式
# crypto_agent 会合并: {symbol, is_long, contracts, **pending_tp_sl}
result['pending_tp_sl'] = {
'stop_loss': stop_loss,
'take_profit': take_profit
'tp_price': take_profit,
'sl_price': stop_loss
}
# 同时记录 contracts 到 result供 crypto_agent 使用
result['contracts'] = contracts
logger.info(f" 📌 已记录 TP/SL 到待处理列表: TP=${take_profit}, SL=${stop_loss}")
logger.info(f" 📌 将由定期检查机制在持仓确认后自动设置")
logger.info(f" ✅ 开仓成功: {symbol} {contracts}张 @ ${order_type}")

View File

@ -49,25 +49,26 @@ class HyperliquidExecutor(BaseExecutor):
# 设置杠杆
self.hyperliquid.update_leverage(symbol, leverage)
# 下单Hyperliquid 支持在下单时设置 TP/SL
# 下单
is_buy = (action == 'buy')
order_params = {
'symbol': symbol,
'is_buy': is_buy,
'size': position_size,
'price': entry_price if order_type == 'limit' else None,
'order_type': order_type,
}
# 如果支持下单时设置 TP/SL添加到参数中
if stop_loss or take_profit:
if self.should_set_tp_sl_on_order():
order_params['sl'] = stop_loss
order_params['tp'] = take_profit
logger.info(f" 下单时设置 TP/SL: SL=${stop_loss}, TP={take_profit}")
result = self.hyperliquid.place_order(**order_params)
if order_type == 'market':
# 市价单
result = self.hyperliquid.place_market_order(
symbol=symbol,
is_buy=is_buy,
size=position_size,
reduce_only=False
)
else:
# 限价单
result = self.hyperliquid.place_limit_order(
symbol=symbol,
is_buy=is_buy,
size=position_size,
price=entry_price,
reduce_only=False
)
if not result.get('success'):
return result
@ -93,13 +94,17 @@ class HyperliquidExecutor(BaseExecutor):
}
)
# 如果成交且未在下单时设置 TP/SL单独设置
if order_status == 'filled' and not self.should_set_tp_sl_on_order():
if stop_loss or take_profit:
tp_sl_result = await self.set_stop_loss_take_profit(
symbol, order_id, stop_loss, take_profit, position_size
# 成交后单独设置止盈止损Hyperliquid 不支持下单时设置 TP/SL
if order_status == 'filled' and (stop_loss or take_profit):
tp_sl_result = self.hyperliquid.set_tp_sl(
symbol=symbol,
is_long=is_buy,
size=position_size,
tp_price=take_profit,
sl_price=stop_loss
)
if not tp_sl_result.get('success'):
logger.warning(f" ⚠️ 止盈止损设置失败: {tp_sl_result.get('message')}")
result['tp_sl_warning'] = tp_sl_result.get('message')
return result

163
check_bitget_tp_sl.py Normal file
View File

@ -0,0 +1,163 @@
#!/usr/bin/env python3
"""
Bitget 止盈止损诊断工具
检查当前持仓挂单以及待设置的 TP/SL
"""
import sys
import os
import asyncio
# 添加后端路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'backend'))
from app.config import get_settings
from app.services.bitget_live_trading_service import get_bitget_live_service
from app.services.bitget_trading_api_sdk import get_bitget_trading_api
def diagnose():
"""诊断 Bitget 止盈止损状态"""
settings = get_settings()
print("=" * 80)
print("🔍 Bitget 止盈止损诊断工具")
print("=" * 80)
# 1. 检查配置
print("\n📋 1. 检查配置")
print(f" Bitget 交易已启用: {settings.bitget_trading_enabled}")
if not settings.bitget_trading_enabled:
print(" ❌ Bitget 交易未启用")
return
# 2. 获取服务实例
print("\n🔧 2. 初始化服务")
bitget_service = get_bitget_live_service()
if not bitget_service:
print(" ❌ Bitget 服务初始化失败")
return
print(" ✅ Bitget 服务已初始化")
# 3. 检查账户状态
print("\n💰 3. 账户状态")
account_state = bitget_service.get_account_state()
if account_state:
print(f" 账户价值: ${account_state.get('account_value', 0):,.2f}")
print(f" 已用保证金: ${account_state.get('total_margin_used', 0):,.2f}")
print(f" 可用余额: ${account_state.get('available_balance', 0):,.2f}")
else:
print(" ⚠️ 无法获取账户状态")
# 4. 检查持仓
print("\n📊 4. 当前持仓")
positions = bitget_service.get_open_positions()
if not positions:
print(" 📭 无持仓")
else:
print(f" 发现 {len(positions)} 个持仓:")
for pos in positions:
symbol = pos.get('coin', pos.get('symbol', 'Unknown'))
size = pos.get('size', 0)
entry_price = pos.get('entry_price', 0)
unrealized_pnl = pos.get('unrealized_pnl', 0)
leverage = pos.get('leverage', 1)
side = '做多' if size > 0 else '做空'
size_abs = abs(size)
print(f"\n 🎯 {symbol} {side}")
print(f" 大小: {size_abs:.4f}")
print(f" 入场价: ${entry_price:,.2f}")
print(f" 杠杆: {leverage}x")
print(f" 未实现盈亏: ${unrealized_pnl:,.2f}")
# 检查是否有 TP/SL
tp_sl = bitget_service.get_tp_sl_prices(symbol)
tp_price = tp_sl.get('take_profit')
sl_price = tp_sl.get('stop_loss')
if tp_price or sl_price:
print(f" ✅ 止盈止损已设置:")
if tp_price:
print(f" 止盈: ${tp_price:,.2f}")
if sl_price:
print(f" 止损: ${sl_price:,.2f}")
else:
print(f" ❌ 止盈止损未设置!")
# 5. 检查挂单
print("\n📌 5. 当前挂单")
trading_api = get_bitget_trading_api()
if not trading_api:
print(" ❌ Bitget Trading API 初始化失败")
return
open_orders = trading_api.get_open_orders()
if not open_orders:
print(" 📭 无挂单")
else:
print(f" 发现 {len(open_orders)} 个挂单:")
for order in open_orders:
symbol = order.get('symbol', 'Unknown')
order_id = order.get('id', 'Unknown')
side = order.get('side', 'Unknown')
amount = order.get('amount', 0)
price = order.get('price', 0)
order_type = order.get('type', 'Unknown')
reduce_only = order.get('reduceOnly', False)
side_text = '买入' if side == 'buy' else '卖出'
order_type_text = '限价' if order_type == 'limit' else order_type
print(f"\n 📝 订单 #{order_id}")
print(f" 交易对: {symbol}")
print(f" 类型: {order_type_text} {side_text}")
print(f" 数量: {amount}")
print(f" 价格: ${price:,.2f}")
print(f" 只平仓: {'' if reduce_only else ''}")
# 6. 总结
print("\n" + "=" * 80)
print("📝 诊断总结:")
print("=" * 80)
if positions:
no_tp_sl_count = 0
for pos in positions:
symbol = pos.get('coin', pos.get('symbol', 'Unknown'))
tp_sl = bitget_service.get_tp_sl_prices(symbol)
if not tp_sl.get('take_profit') and not tp_sl.get('stop_loss'):
no_tp_sl_count += 1
if no_tp_sl_count > 0:
print(f"\n⚠️ 警告: {no_tp_sl_count} 个持仓没有设置止盈止损!")
print("\n可能的原因:")
print(" 1. 挂单刚刚成交定期检查还未运行每5分钟检查一次")
print(" 2. 止盈止损设置失败,查看日志确认")
print(" 3. 挂单还在等待成交")
print("\n建议:")
print(" • 等待下一个 5 分钟检查周期")
print(" • 或手动在 Bitget 网页/App 设置止盈止损")
print(" • 或重启后端服务,立即触发检查")
else:
print("\n✅ 所有持仓都已设置止盈止损")
else:
print("\n✅ 当前无持仓")
print("\n" + "=" * 80)
if __name__ == "__main__":
try:
diagnose()
except KeyboardInterrupt:
print("\n\n👋 诊断已取消")
except Exception as e:
print(f"\n❌ 诊断失败: {e}")
import traceback
traceback.print_exc()