From 9fefca848e36ad683809c2eb7729478f0339a8bc Mon Sep 17 00:00:00 2001 From: aaron <> Date: Sat, 28 Mar 2026 22:41:51 +0800 Subject: [PATCH] uopdate --- backend/app/config.py | 6 +- backend/app/crypto_agent/crypto_agent.py | 200 +++++++- .../executor/AGGRESSIVE_CONFIG.md | 355 +++++++++++++++ .../executor/CONFIG_UPDATE_2026-03-28.md | 197 ++++++++ .../crypto_agent/executor/FEATURE_SUMMARY.md | 272 +++++++++++ .../executor/LEVERAGE_CONFIGURATION.md | 280 ++++++++++++ .../executor/MOVE_STOP_LOSS_FEATURE.md | 321 +++++++++++++ .../executor/NOTIFICATION_FEATURE.md | 2 + .../executor/POSITION_SIZE_LOGIC.md | 308 ++++--------- .../executor/POSITION_SIZE_LOGIC_OLD.md | 426 ++++++++++++++++++ .../executor/POSITION_SIZING_STRATEGY.md | 241 ++++++++++ .../crypto_agent/executor/base_executor.py | 20 + .../crypto_agent/executor/bitget_executor.py | 34 ++ .../executor/hyperliquid_executor.py | 34 ++ .../executor/paper_trading_executor.py | 48 ++ 15 files changed, 2522 insertions(+), 222 deletions(-) create mode 100644 backend/app/crypto_agent/executor/AGGRESSIVE_CONFIG.md create mode 100644 backend/app/crypto_agent/executor/CONFIG_UPDATE_2026-03-28.md create mode 100644 backend/app/crypto_agent/executor/FEATURE_SUMMARY.md create mode 100644 backend/app/crypto_agent/executor/LEVERAGE_CONFIGURATION.md create mode 100644 backend/app/crypto_agent/executor/MOVE_STOP_LOSS_FEATURE.md create mode 100644 backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC_OLD.md create mode 100644 backend/app/crypto_agent/executor/POSITION_SIZING_STRATEGY.md diff --git a/backend/app/config.py b/backend/app/config.py index 45fb57f..da12998 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -130,7 +130,7 @@ class Settings(BaseSettings): # 模拟交易配置 paper_trading_enabled: bool = True # 是否启用模拟交易 paper_trading_initial_balance: float = 10000 # 初始本金 (USDT) - paper_trading_leverage: int = 20 # 单笔订单杠杆倍数 + paper_trading_leverage: int = 10 # 单笔订单杠杆倍数(从20改为10) paper_trading_max_total_leverage: float = 10 # 总杠杆上限(持仓+挂单,倍数) paper_trading_margin_per_order: float = 1000 # 每单保证金 (USDT) paper_trading_max_orders: int = 10 # 最大持仓+挂单总数 @@ -164,6 +164,10 @@ class Settings(BaseSettings): bitget_max_single_position: float = 1000 # 单笔最大持仓金额 (USDT) bitget_max_total_leverage: float = 10 # 总杠杆上限(倍数) + # 账户级止损(所有平台通用) + account_max_drawdown: float = 0.25 # 账户最大回撤(25%),超过则停止交易并平仓 + account_drawdown_alert: float = 0.15 # 回撤警告阈值(15%),触发告警通知 + # Agent 模型配置 (可选值: zhipu, deepseek) smart_agent_model: str = "deepseek" # SmartAgent 使用的模型 crypto_agent_model: str = "deepseek" # CryptoAgent 使用的模型 diff --git a/backend/app/crypto_agent/crypto_agent.py b/backend/app/crypto_agent/crypto_agent.py index 772191e..11814ac 100644 --- a/backend/app/crypto_agent/crypto_agent.py +++ b/backend/app/crypto_agent/crypto_agent.py @@ -449,6 +449,14 @@ class CryptoAgent: logger.info(f"⏰ 定时任务执行 [{run_time.strftime('%Y-%m-%d %H:%M:%S')}]") logger.info("=" * 60) + # 1. 首先检查账户级止损(所有平台) + should_stop, stop_reason = await self._check_account_level_stop_loss() + if should_stop: + logger.error(f"🚨 {stop_reason}") + # 触发账户级止损,停止所有交易 + self.running = False + break + # 检查并取消超时挂单(在分析开始前) cancelled = self.paper_trading.check_and_cancel_expired_orders() if cancelled: @@ -2129,16 +2137,16 @@ class CryptoAgent: Returns: (margin, reason) - 保证金金额和原因 """ - # 基础保证金比例(根据信号强度) + # 基础保证金比例(超激进配置 - 最大化资金利用率) confidence = signal.get('confidence', 50) if confidence >= 90: - base_margin_pct = 0.03 # A级: 3% + base_margin_pct = 0.20 # A级: 20% (重仓出击) grade = 'A' elif confidence >= 70: - base_margin_pct = 0.02 # B级: 2% + base_margin_pct = 0.15 # B级: 15% (中仓跟进) grade = 'B' else: - base_margin_pct = 0.01 # C级: 1% + base_margin_pct = 0.08 # C级: 8% (轻仓试探) grade = 'C' # 可用保证金 @@ -2576,7 +2584,8 @@ class CryptoAgent: return {"success": False, "error": f"仓位计算结果 {contracts} 张,低于最小下单量 1 张"} # 设置杠杆 - leverage = min(decision.get('leverage', 5), 10) + # 设置杠杆 (默认10x,最大10x) + leverage = min(decision.get('leverage', 10), 10) self.bitget.update_leverage(symbol, leverage) # 下单 @@ -3521,6 +3530,159 @@ class CryptoAgent: except Exception as e: logger.error(f"检查挂单超时失败: {e}") + async def _check_account_level_stop_loss(self) -> tuple[bool, str]: + """ + 检查账户级止损(所有平台通用) + + Returns: + (should_stop, reason) - 是否应该停止交易,以及原因 + """ + try: + max_drawdown = self.settings.account_max_drawdown + alert_threshold = self.settings.account_drawdown_alert + alerts = [] + + # 检查所有平台 + platforms_to_check = [] + + # 添加模拟盘 + if self.paper_trading: + platforms_to_check.append(('模拟盘', self.paper_trading)) + + # 添加 Bitget 实盘 + if self.bitget and self.settings.bitget_use_testnet: + platforms_to_check.append(('Bitget', self.bitget)) + + # 添加 Hyperliquid 实盘 + if self.hyperliquid: + platforms_to_check.append(('Hyperliquid', self.hyperliquid)) + + for platform_name, platform_service in platforms_to_check: + try: + # 获取账户状态 + if hasattr(platform_service, 'get_account_state'): + account_state = platform_service.get_account_state() + elif hasattr(platform_service, 'get_balance'): + account_state = platform_service.get_balance() + else: + logger.warning(f"[{platform_name}] 无法获取账户状态") + continue + + initial_balance = account_state.get('initial_balance', account_state.get('current_balance', 0)) + current_balance = account_state.get('current_balance', account_state.get('balance', 0)) + + if initial_balance <= 0 or current_balance <= 0: + continue + + # 计算回撤 + drawdown = (initial_balance - current_balance) / initial_balance + drawdown_pct = drawdown * 100 + + logger.info(f"📊 [{platform_name}] 账户状态: " + f"初始 ${initial_balance:.2f} → 当前 ${current_balance:.2f} " + f"(回撤 {drawdown_pct:.2f}%)") + + # 检查是否触发警告 + if drawdown >= alert_threshold and drawdown < max_drawdown: + warning_msg = (f"⚠️ [{platform_name}] 账户回撤警告: {drawdown_pct:.2f}% " + f"(警告线 {alert_threshold*100:.0f}%, 止损线 {max_drawdown*100:.0f}%)") + logger.warning(warning_msg) + alerts.append((platform_name, 'warning', warning_msg, drawdown_pct)) + + # 检查是否触发止损 + elif drawdown >= max_drawdown: + critical_msg = (f"🚨 [{platform_name}] 触发账户级止损: " + f"回撤 {drawdown_pct:.2f}% >= 止损线 {max_drawdown*100:.0f}%") + logger.error(critical_msg) + + # 立即平掉所有持仓 + await self._emergency_close_all_positions(platform_name, platform_service) + + return True, critical_msg + + except Exception as e: + logger.error(f"[{platform_name}] 检查账户止损失败: {e}") + continue + + # 发送警告通知(如果有) + if alerts: + for platform_name, level, msg, drawdown_pct in alerts: + await self._send_alert_notification( + f"⚠️ [{platform_name}] 账户回撤警告", + f"回撤: {drawdown_pct:.2f}%\n" + f"警告线: {alert_threshold*100:.0f}%\n" + f"止损线: {max_drawdown*100:.0f}%\n\n" + f"请密切监控账户风险!" + ) + + return False, "" + + except Exception as e: + logger.error(f"检查账户级止损失败: {e}") + return False, "" + + async def _emergency_close_all_positions(self, platform_name: str, platform_service): + """ + 紧急平掉所有持仓(账户级止损触发时调用) + + Args: + platform_name: 平台名称 + platform_service: 平台服务实例 + """ + try: + logger.info(f"🚨 [{platform_name}] 执行紧急平仓...") + + # 获取所有持仓 + if hasattr(platform_service, 'get_all_positions'): + positions = platform_service.get_all_positions() + elif hasattr(platform_service, 'get_open_positions'): + positions = platform_service.get_open_positions() + else: + logger.warning(f"[{platform_name}] 无法获取持仓列表") + return + + if not positions: + logger.info(f"[{platform_name}] 无持仓,无需平仓") + return + + logger.info(f"[{platform_name}] 需要平仓 {len(positions)} 个持仓") + + # 逐个平仓 + closed_count = 0 + for pos in positions: + try: + symbol = pos.get('symbol', pos.get('coin', '')) + + if hasattr(platform_service, 'market_close_position'): + result = platform_service.market_close_position(symbol) + elif hasattr(platform_service, 'close_position'): + result = platform_service.close_position(symbol) + else: + logger.warning(f"[{platform_name}] 无法平仓 {symbol}: 无平仓方法") + continue + + if result and result.get('success', False): + closed_count += 1 + logger.info(f" ✅ 平仓成功: {symbol}") + else: + logger.error(f" ❌ 平仓失败: {symbol} - {result.get('message', '')}") + + except Exception as e: + logger.error(f" ❌ 平仓异常: {symbol} - {e}") + + # 发送紧急通知 + await self._send_alert_notification( + f"🚨 [{platform_name}] 紧急平仓完成", + f"触发原因: 账户回撤超过 {self.settings.account_max_drawdown*100:.0f}%\n" + f"平仓数量: {closed_count}/{len(positions)}\n\n" + f"⚠️ 交易系统已停止,请人工检查账户!" + ) + + logger.info(f"🚨 [{platform_name}] 紧急平仓完成: {closed_count}/{len(positions)}") + + except Exception as e: + logger.error(f"紧急平仓失败: {e}") + async def _check_position_management_all_platforms(self): """检查各平台的持仓管理(止盈/止损/移动止损)""" try: @@ -3592,11 +3754,31 @@ class CryptoAgent: elif action == 'MOVE_SL': # 移动止损 new_sl = action_info.get('new_sl') + pnl_pct = action_info.get('pnl_pct', 0) # 从 action_info 获取盈亏百分比 + if new_sl: - # 这里需要调用平台的移动止损方法 - # 具体实现取决于各平台 API - logger.info(f" ✅ 建议移动止损: {symbol} → ${new_sl:.2f}") - # 暂时只记录, pass + # 调用执行器的移动止损方法 + move_result = await executor.move_stop_loss( + symbol=symbol, + new_stop_loss=new_sl + ) + + if move_result.get('success'): + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_sl:.2f}") + await self._send_alert_notification( + f"🔒 [{platform_name}] 移动止损", + f"交易对: {symbol}\n新止损: ${new_sl:.2f}\n原因: {reason}" + ) + + # 发送飞书通知 + await executor.send_execution_notification( + operation='POSITION_MANAGEMENT', + symbol=symbol, + result={'success': True, 'action': 'MOVE_SL', 'reason': reason}, + details={'new_sl': new_sl, 'pnl_percent': pnl_pct} + ) + else: + logger.warning(f" ⚠️ 移动止损失败: {move_result.get('message')}") except Exception as e: logger.error(f"检查持仓管理失败: {e}") diff --git a/backend/app/crypto_agent/executor/AGGRESSIVE_CONFIG.md b/backend/app/crypto_agent/executor/AGGRESSIVE_CONFIG.md new file mode 100644 index 0000000..0dbc2a9 --- /dev/null +++ b/backend/app/crypto_agent/executor/AGGRESSIVE_CONFIG.md @@ -0,0 +1,355 @@ +# 超激进配置 - 最大化资金利用率 +UPDATED: 2026-03-28 + +## 🚀 配置概览 + +### 仓位比例(超激进) + +| 信号等级 | 置信度范围 | 保证金比例 | $1000账户保证金 | 10x杠杆仓位 | 资金利用率 | +|---------|----------|----------|---------------|-----------|-----------| +| **A级** | ≥90分 | **20%** | $200 | $2,000 | **极高** 🔥 | +| **B级** | 70-89分 | **15%** | $150 | $1,500 | **高** 🔥 | +| **C级** | <70分 | **8%** | $80 | $800 | **中** | + +### 杠杆配置 + +| 平台 | 单笔杠杆 | 总杠杆上限 | 说明 | +|------|---------|----------|------| +| **所有平台** | 10x | 10x | 最大化杠杆效应 | + +### 账户级止损 + +| 阈值类型 | 触发条件 | 动作 | +|---------|---------|------| +| **警告阈值** | 回撤 ≥ 15% | ⚠️ 发送警告通知,继续交易 | +| **止损阈值** | 回撤 ≥ 25% | 🚨 **立即平仓 + 停止交易** | + +--- + +## 💰 收益潜力分析 + +### 单次交易收益(+3%盈利) + +| 信号等级 | 保证金 | 杠杆 | 持仓价值 | +3%盈利 | 收益率 | +|---------|--------|-----|---------|---------|-------| +| **A级** | $200 | 10x | $2,000 | +$60 | **+6.0%** 🚀 | +| **B级** | $150 | 10x | $1,500 | +$45 | **+4.5%** | +| **C级** | $80 | 10x | $800 | +$24 | **+2.4%** | + +### 与保守配置对比 + +| 配置类型 | A级单次+3% | A级5次盈利 | 资金利用率 | +|---------|-----------|----------|-----------| +| **保守型** (3%仓位, 5x) | +$4.5 (0.45%) | +$22.5 (2.25%) | 低 | +| **激进型** (10%仓位, 10x) | +$30 (3.0%) | +$150 (15%) | 中 | +| **超激进型** (20%仓位, 10x) | **+$60 (6.0%)** | **+$300 (30%)** 🚀 | **极高** | + +**超激进配置收益是保守配置的 13.3 倍!** + +--- + +## ⚠️ 风险分析 + +### 单笔最大亏损(-3%止损) + +| 信号等级 | 保证金 | 杠杆 | 持仓价值 | -3%亏损 | 占总资金% | +|---------|--------|-----|---------|---------|----------| +| **A级** | $200 | 10x | $2,000 | -$60 | **-6.0%** ⚠️ | +| **B级** | $150 | 10x | $1,500 | -$45 | **-4.5%** | +| **C级** | $80 | 10x | $800 | -$24 | **-2.4%** | + +### 连续亏损场景 + +| 连续亏损次数 | A级信号累计亏损 | 占总资金% | 触发警告? | 触发止损? | +|------------|---------------|----------|----------|----------| +| **3次** | -$180 | -18% | ⚠️ 是 | 否 | +| **4次** | -$240 | -24% | ⚠️ 是 | 🚨 是(即将) | +| **5次** | -$300 | -30% | - | 🚨 **触发止损** | + +### 回撤风险 + +**假设场景**: 10次交易,40%胜率,平均盈利+3%,平均亏损-3% + +``` +盈利: 4次 × $60 = +$240 +亏损: 6次 × $60 = -$360 +净收益: -$120 (-12%) +最大回撤峰值: ~25% ⚠️ (触发止损边缘) +``` + +**结论**: 如果信号质量不高(胜率<50%),超激进配置风险极大! + +--- + +## 🛡️ 账户级止损保护 + +### 触发条件 + +```python +# 计算回撤 +initial_balance = $10,000 # 初始资金 +current_balance = $7,500 # 当前资金 +drawdown = ($10,000 - $7,500) / $10,000 = 25% + +if drawdown >= 25%: + # 🚨 触发账户级止损 + # 1. 立即平掉所有持仓 + # 2. 停止交易系统 + # 3. 发送紧急通知 +``` + +### 实现逻辑 + +**位置**: `crypto_agent.py` 主循环 + +```python +# 每轮循环开始时检查 +async def run(self): + while self.running: + # 1. 检查账户级止损 + should_stop, reason = await self._check_account_level_stop_loss() + if should_stop: + logger.error(f"🚨 {reason}") + self.running = False + break + + # 2. 正常交易逻辑 + for symbol in symbols: + await self.analyze_symbol(symbol) +``` + +### 检查逻辑 + +```python +async def _check_account_level_stop_loss(self): + """检查所有平台账户回撤""" + + for platform_name, platform_service in platforms: + # 获取账户状态 + account_state = platform_service.get_account_state() + initial_balance = account_state['initial_balance'] + current_balance = account_state['current_balance'] + + # 计算回撤 + drawdown = (initial_balance - current_balance) / initial_balance + + # 检查警告阈值 (15%) + if drawdown >= 0.15 and drawdown < 0.25: + await send_alert(f"⚠️ 回撤警告: {drawdown*100:.1f}%") + + # 检查止损阈值 (25%) + elif drawdown >= 0.25: + await self._emergency_close_all_positions(platform_name, platform_service) + return True, f"触发账户级止损: 回撤 {drawdown*100:.1f}%" + + return False, "" +``` + +### 紧急平仓流程 + +``` +1. 获取所有持仓 +2. 逐个平仓(市价单) +3. 发送紧急通知(飞书/Telegram/钉钉) +4. 停止交易系统 +5. 等待人工干预 +``` + +--- + +## 📊 适用场景 + +### ✅ 适合使用超激进配置 + +1. **小资金账户** (< $5,000) + - 目标: 快速增值 + - 风险承受能力强 + - 可以承受较大回撤 + +2. **高质量信号源** + - 信号胜率 > 60% + - 平均盈亏比 > 1.5 + - 信号质量稳定 + +3. **有止损保护** + - 已设置账户级止损 + - 有风险监控系统 + - 能及时干预 + +### ❌ 不适合使用超激进配置 + +1. **大资金账户** (> $50,000) + - 单笔亏损金额过大 + - 流动性风险 + - 心理压力大 + +2. **信号质量不稳定** + - 胜率波动大 + - 信号源未验证 + - 回测数据不足 + +3. **风险厌恶者** + - 无法承受-25%回撤 + - 心理压力大 + - 影响正常交易决策 + +--- + +## 🎯 实战建议 + +### 1. 渐进式启用 + +```python +# 第1周: 测试配置(模拟盘) +- 验证信号质量 +- 观察最大回撤 +- 调整参数 + +# 第2周: 小资金实盘($1000-2000) +- 真实市场测试 +- 验证止损逻辑 +- 心理压力测试 + +# 第3-4周: 逐步增加资金 +- 表现好 → 增加到 $5000 +- 表现差 → 降级到激进配置 +``` + +### 2. 动态调整 + +```python +def get_dynamic_margin_pct(confidence, recent_performance): + """根据近期表现动态调整仓位""" + + base_pct = { + 'A': 0.20, + 'B': 0.15, + 'C': 0.08 + } + + win_rate_7d = recent_performance.get('win_rate_7d', 0.5) + + # 表现不佳,降低仓位 + if win_rate_7d < 0.4: + return base_pct * 0.5 # 减半 + + # 表现优秀,保持仓位 + elif win_rate_7d > 0.7: + return base_pct * 1.0 # 保持 + + else: + return base_pct * 0.8 # 略降 +``` + +### 3. 监控指标 + +**每日监控**: +- 当前回撤百分比 +- 总杠杆使用情况 +- 持仓盈亏分布 + +**每周监控**: +- 胜率和盈亏比 +- 最大回撤峰值 +- 信号质量分析 + +**每月监控**: +- 总收益率 +- 夏普比率 +- 最大连续亏损次数 + +--- + +## 🔧 配置文件 + +### config.py + +```python +class Settings(BaseSettings): + # 账户级止损(所有平台通用) + account_max_drawdown: float = 0.25 # 最大回撤25% + account_drawdown_alert: float = 0.15 # 警告阈值15% +``` + +### crypto_agent.py + +```python +def _calculate_position_size(self, signal, account, platform_name): + """超激进仓位配置""" + confidence = signal.get('confidence', 50) + + if confidence >= 90: + base_margin_pct = 0.20 # A级: 20% + grade = 'A' + elif confidence >= 70: + base_margin_pct = 0.15 # B级: 15% + grade = 'B' + else: + base_margin_pct = 0.08 # C级: 8% + grade = 'C' + + margin = account['available'] * base_margin_pct + return margin, f"信号{grade}级 → {base_margin_pct*100}%保证金" +``` + +--- + +## 📝 检查清单 + +### 部署前检查 +- [x] 修改仓位比例为20%/15%/8% +- [x] 添加账户级止损配置(25%) +- [x] 添加警告阈值配置(15%) +- [x] 实现账户止损检查逻辑 +- [x] 实现紧急平仓功能 +- [x] 添加飞书通知 +- [x] 创建配置文档 + +### 部署后监控 +- [ ] 观察首次A级信号开仓 +- [ ] 验证账户止损计算准确 +- [ ] 测试警告通知发送 +- [ ] 模拟触发止损场景 +- [ ] 记录实际回撤数据 +- [ ] 调整参数优化 + +--- + +## 🚨 紧急情况处理 + +### 如果触发账户止损 + +1. **系统自动操作**: + - ✅ 已平掉所有持仓 + - ✅ 已停止交易系统 + - ✅ 已发送紧急通知 + +2. **人工干预**: + ```bash + # 1. 检查账户状态 + python scripts/check_account_status.py + + # 2. 分析止损原因 + python scripts/analyze_stop_loss.py --days 7 + + # 3. 调整配置 + # 修改 config.py 中的参数 + + # 4. 重启系统(谨慎!) + python main.py + ``` + +3. **复盘分析**: + - 检查信号质量 + - 分析亏损原因 + - 优化策略参数 + - 考虑降级配置 + +--- + +## 相关文档 + +- [杠杆配置详解](./LEVERAGE_CONFIGURATION.md) +- [仓位配置策略](./POSITION_SIZING_STRATEGY.md) +- [移动止损功能](./MOVE_STOP_LOSS_FEATURE.md) +- [功能完成总结](./FEATURE_SUMMARY.md) diff --git a/backend/app/crypto_agent/executor/CONFIG_UPDATE_2026-03-28.md b/backend/app/crypto_agent/executor/CONFIG_UPDATE_2026-03-28.md new file mode 100644 index 0000000..f594ab8 --- /dev/null +++ b/backend/app/crypto_agent/executor/CONFIG_UPDATE_2026-03-28.md @@ -0,0 +1,197 @@ +# 配置更新总结 (2026-03-28) +CREATED: 2026-03-28 + +## 🔥 超激进配置已启用 + +### ✅ 已完成的修改 + +| 配置项 | 修改前 | 修改后 | 变化 | +|--------|--------|--------|------| +| **A级仓位** | 3% | **20%** | **+567%** 🚀 | +| **B级仓位** | 2% | **15%** | **+650%** | +| **C级仓位** | 1% | **8%** | **+700%** | +| **单笔杠杆** | 5-20x | **10x** | 统一 | +| **账户止损** | 无 | **25%** | 新增 🛡️ | +| **警告阈值** | 无 | **15%** | 新增 ⚠️ | + +--- + +## 📊 新配置 vs 旧配置 + +### 资金利用效率对比 + +**$1000账户, A级信号**: + +| 配置 | 保证金 | 杠杆 | 持仓价值 | +3%盈利 | 收益率 | +|------|--------|-----|---------|---------|-------| +| **旧配置** | $30 | 5x | $150 | +$4.5 | +0.45% | +| **新配置** | $200 | 10x | $2,000 | **+$60** | **+6.0%** 🚀 | + +**收益提升**: **13.3倍** + +### 10次交易后的差异(60%胜率) + +| 配置类型 | 盈利(6次) | 亏损(4次) | 净收益 | ROI | +|---------|----------|----------|-------|-----| +| **旧配置** | +$27 | -$18 | +$9 | **+0.9%** | +| **新配置** | +$360 | -$240 | **+$120** | **+12%** 🚀 | + +--- + +## 🛡️ 风险控制机制 + +### 1. 账户级止损 (25%) + +``` +初始资金: $10,000 +当前资金: $7,500 +回撤: ($10,000 - $7,500) / $10,000 = 25% ✅ 触发止损 + +动作: +1. 🚨 立即平掉所有持仓 +2. 🛑 停止交易系统 +3. 📢 发送紧急通知 +``` + +### 2. 警告阈值 (15%) + +``` +初始资金: $10,000 +当前资金: $8,500 +回撤: 15% ✅ 触发警告 + +动作: +1. ⚠️ 发送警告通知 +2. ✅ 继续交易 +3. 📊 密切监控 +``` + +### 3. 总杠杆限制 (10x) + +``` +账户余额: $1,000 +当前持仓价值: $9,500 +当前总杠杆: 9.5x + +新信号保证金: $200 +新持仓价值: $2,000 +预计总杠杆: ($9,500 + $2,000) / $1,000 = 11.5x ❌ 拒绝 + +原因: "已达最大杠杆 9.5x/10x" +``` + +--- + +## 🎯 使用场景 + +### ✅ 适合超激进配置 + +1. **小资金** (< $5,000) - 快速增值 +2. **高质量信号** (胜率 > 60%) +3. **有止损保护** - 账户级25%止损 + +### ❌ 不适合超激进配置 + +1. **大资金** (> $50,000) - 单笔亏损过大 +2. **信号质量不稳定** - 胜率波动大 +3. **风险厌恶者** - 无法承受-25%回撤 + +--- + +## 📈 监控指标 + +### 实时监控(每5分钟) + +- [x] 检查账户回撤 +- [x] 检查总杠杆 +- [x] 检查持仓盈亏 + +### 每日报告 + +- 当前回撤百分比 +- 当日盈亏 +- 信号质量统计 + +### 每周分析 + +- 胜率和盈亏比 +- 最大回撤峰值 +- 策略表现评估 + +--- + +## 🔧 配置文件位置 + +### 1. 仓位比例 +**文件**: `crypto_agent.py:2132-2142` + +```python +if confidence >= 90: + base_margin_pct = 0.20 # A级: 20% +elif confidence >= 70: + base_margin_pct = 0.15 # B级: 15% +else: + base_margin_pct = 0.08 # C级: 8% +``` + +### 2. 杠杆配置 +**文件**: `config.py:133` + +```python +paper_trading_leverage: int = 10 # 10x杠杆 +``` + +### 3. 账户止损 +**文件**: `config.py:165-166` + +```python +account_max_drawdown: float = 0.25 # 最大回撤25% +account_drawdown_alert: float = 0.15 # 警告阈值15% +``` + +--- + +## 📝 相关文档 + +1. **[AGGRESSIVE_CONFIG.md](./AGGRESSIVE_CONFIG.md)** - 超激进配置完整文档 +2. **[LEVERAGE_CONFIGURATION.md](./LEVERAGE_CONFIGURATION.md)** - 杠杆配置详解 +3. **[POSITION_SIZING_STRATEGY.md](./POSITION_SIZING_STRATEGY.md)** - 仓位策略对比 +4. **[FEATURE_SUMMARY.md](./FEATURE_SUMMARY.md)** - 所有功能总结 + +--- + +## ⚠️ 重要提醒 + +### 1. 风险警告 + +**超激进配置风险极大**: +- 单笔最大亏损: -6% (A级信号) +- 5次连续亏损: -30% (触发止损) +- 需要严格止损纪律 + +### 2. 建议 + +**第1周**: +- 使用模拟盘测试 +- 观察最大回撤 +- 验证信号质量 + +**第2-4周**: +- 小资金实盘 ($1000-2000) +- 监控账户回撤 +- 根据表现调整 + +**长期**: +- 表现好 → 保持配置 +- 表现差 → 降级到平衡型 +- 定期复盘优化 + +--- + +## 🚀 下一步 + +- [ ] 回测验证新配置效果 +- [ ] 模拟盘测试1周 +- [ ] 实盘小资金测试 +- [ ] 监控实际回撤数据 +- [ ] 根据实际表现微调 diff --git a/backend/app/crypto_agent/executor/FEATURE_SUMMARY.md b/backend/app/crypto_agent/executor/FEATURE_SUMMARY.md new file mode 100644 index 0000000..a1c5478 --- /dev/null +++ b/backend/app/crypto_agent/executor/FEATURE_SUMMARY.md @@ -0,0 +1,272 @@ +# 执行器移动止损 + 飞书通知完成总结 +CREATED: 2026-03-28 + +## ✅ 已完成的功能 + +### 1. 飞书通知集成 + +所有交易执行操作现在都会自动发送飞书通知: + +#### 修改的文件 +- [base_executor.py](./base_executor.py) - 添加基类通知方法 +- [bitget_executor.py](./bitget_executor.py) - Bitget 平台集成 +- [hyperliquid_executor.py](./hyperliquid_executor.py) - Hyperliquid 平台集成 +- [paper_trading_executor.py](./paper_trading_executor.py) - 模拟盘集成 + +#### 通知类型 +| 操作 | 成功通知 | 失败通知 | +|------|---------|---------| +| **开仓** (OPEN) | ✅ 绿色卡片 | ❌ 红色卡片 | +| **平仓** (CLOSE) | ✅ 绿色卡片(含盈亏) | ❌ 红色卡片 | +| **撤单** (CANCEL) | ✅ 绿色卡片 | ❌ 红色卡片 | +| **止盈止损** (TP_SL) | ✅ 绿色卡片 | ⚠️ 橙色卡片 | +| **持仓管理** (POSITION_MANAGEMENT) | 🔵 蓝色卡片 | - | + +#### 通知内容 +``` +标题: ✅ [Bitget] 开仓成功 - BTC +内容: + 平台: Bitget + 交易对: BTC + 订单ID: 1234567890 + 数量: 1 张 + 价格: $85,000.00 + 保证金: $170.00 + 杠杆: 5x + 止损: $82,000.00 + 止盈: $88,000.00 + 订单类型: limit +``` + +详细文档: [NOTIFICATION_FEATURE.md](./NOTIFICATION_FEATURE.md) + +--- + +### 2. 移动止损功能 + +所有平台已实现智能移动止损,当持仓盈利达到 2% 时自动将止损移动到入场价。 + +#### 修改的文件 +- [base_executor.py](./base_executor.py) - 添加抽象方法 `move_stop_loss()` +- [bitget_executor.py](./bitget_executor.py) - Bitget 平台实现 +- [hyperliquid_executor.py](./hyperliquid_executor.py) - Hyperliquid 平台实现 +- [paper_trading_executor.py](./paper_trading_executor.py) - 模拟盘实现 +- [crypto_agent.py](../crypto_agent.py) - 集成移动止损调用 + +#### 触发条件 +```python +if pnl_pct >= 2%: + if side == 'buy' and current_sl < entry_price: + # 做多:移动止损到入场价 + MOVE_SL → entry_price + elif side == 'sell' and current_sl > entry_price: + # 做空:移动止损到入场价 + MOVE_SL → entry_price +``` + +#### 平台配置 +| 平台 | 目标盈利 | 最大持仓 | 移动止损触发 | 移动到 | +|------|---------|---------|------------|-------| +| **Bitget** | 3% | 6h | 盈利 >= 2% | 入场价 | +| **Hyperliquid** | 2.5% | 4h | 盈利 >= 2% | 入场价 | +| **PaperTrading** | 3% | 4h | 盈利 >= 2% | 入场价 | + +#### 执行流程 +1. **检查**: `_check_position_management_all_platforms()` (每轮循环) +2. **触发**: 盈利达到 2% 且止损未移动 +3. **执行**: 调用 `executor.move_stop_loss()` +4. **通知**: + - 日志: `"✅ 移动止损成功: BTC → $85,000.00"` + - 告警: `"🔒 [Bitget] 移动止损"` + - 飞书: 蓝色卡片通知 + +详细文档: [MOVE_STOP_LOSS_FEATURE.md](./MOVE_STOP_LOSS_FEATURE.md) + +--- + +## 📂 新增文件 + +1. **NOTIFICATION_FEATURE.md** - 飞书通知功能完整文档 +2. **MOVE_STOP_LOSS_FEATURE.md** - 移动止损功能完整文档 +3. **FEISHU_NOTIFICATION_INTEGRATION.md** (用户创建) - 飞书集成说明 + +--- + +## 🔧 技术实现 + +### 基类新增方法 + +```python +# 1. 通知发送方法 +async def send_execution_notification(operation, symbol, result, details) + +# 2. 移动止损抽象方法 +@abstractmethod +async def move_stop_loss(symbol, new_stop_loss, current_stop_loss) +``` + +### 各平台实现 + +#### Bitget +```python +async def move_stop_loss(symbol, new_stop_loss, current_stop_loss): + success = self.bitget.modify_sl_tp( + symbol=symbol.replace('USDT', ''), + stop_loss=new_stop_loss + ) + return {'success': success} +``` + +**API**: `bitget_trading_api_sdk.modify_sl_tp(symbol, stop_loss, take_profit)` + +#### Hyperliquid +```python +async def move_stop_loss(symbol, new_stop_loss, current_stop_loss): + result = self.hyperliquid.set_tp_sl( + symbol=symbol.replace('USDT', ''), + sl_price=new_stop_loss + ) + return {'success': result.get('success', False)} +``` + +**API**: `hyperliquid_trading_service.set_tp_sl(symbol, sl_price)` + +#### PaperTrading +```python +async def move_stop_loss(symbol, new_stop_loss, current_stop_loss): + orders = self.paper_trading.get_active_orders(symbol) + success_count = 0 + + for order in orders: + result = self.paper_trading.update_order( + order_id=order.order_id, + stop_loss=new_stop_loss + ) + if result.get('success'): + success_count += 1 + + return {'success': success_count > 0} +``` + +**API**: `paper_trading_service.update_order(order_id, stop_loss)` + +--- + +## 🎯 使用示例 + +### 示例 1: Bitget 开仓 + 移动止损 +``` +1. 信号: BTC 做多, 置信度 85% (A级) +2. 决策: + - 保证金: $170 (3% of $1074) + - 杠杆: 5x + - 入场价: $85,000 + - 止损: $82,000 + - 止盈: $88,000 + +3. 执行: Bitget 开仓 1 张合约 + → 📢 飞书通知: ✅ [Bitget] 开仓成功 - BTC + +4. 价格上涨到 $87,000 (盈利 2.35%) + → 系统触发移动止损 + → 执行: 移动止损到 $85,000 + → 📢 飞书通知: 🔒 [Bitget] 移动止损 + 交易对: BTC + 新止损: $85,000.00 + 原因: 盈利 2.35% >= 2%,移动止损到入场价 +``` + +### 示例 2: Hyperliquid 平仓通知 +``` +1. 持仓: ETH 做多, 入场价 $3,500 +2. 当前价: $3,600 (盈利 2.86%) +3. 触发: 持仓管理检查 +4. 执行: 自动止盈平仓 + → 📢 飞书通知: ✅ [Hyperliquid] 平仓成功 - ETH + 平台: Hyperliquid + 交易对: ETH + 盈利: $100.00 + 收益率: 2.86% + 平仓原因: 盈利 2.86% >= 2.5% +``` + +--- + +## ⚠️ 注意事项 + +### 1. 飞书 Webhook 配置 +确保配置正确的飞书 Webhook URL: +```python +# settings.py +feishu_paper_trading_webhook_url = "https://open.feishu.cn/open-apis/bot/v2/hook/..." +feishu_enabled = True +``` + +### 2. 止损设置 +- Bitget 和 Hyperliquid 需要在开仓时或开仓后设置止损 +- 移动止损只会修改已存在的止损订单 +- 如果没有初始止损,移动止损可能会失败 + +### 3. 异步调用 +所有执行器方法都是异步的,需要使用 `await`: +```python +result = await executor.move_stop_loss(symbol, new_sl) +await executor.send_execution_notification(operation, symbol, result) +``` + +--- + +## 📊 监控建议 + +### 关键指标 +1. **通知成功率**: 飞书通知发送成功率 +2. **移动止损触发次数**: 统计移动止损执行频率 +3. **移动止损效果**: 移动止损后最终盈亏情况 + +### 日志监控 +```bash +# 查看移动止损日志 +grep "移动止损成功" logs/crypto_agent.log + +# 查看飞书通知日志 +grep "飞书消息发送成功" logs/crypto_agent.log +``` + +--- + +## 🚀 下一步计划 + +### 1. 测试 +- [ ] 测试各平台飞书通知是否正常 +- [ ] 测试移动止损逻辑是否正确触发 +- [ ] 测试失败场景的通知 + +### 2. 优化 +- [ ] 根据实际使用情况调整移动止损触发阈值 +- [ ] 优化飞书通知的展示格式 +- [ ] 添加通知失败重试机制 + +### 3. 扩展 +- [ ] 支持更多平台(Binance, OKX 等) +- [ ] 添加邮件/短信通知渠道 +- [ ] 实现分级移动止损(2% 移到入场价, 4% 移到 +1% 等) + +--- + +## 📖 相关文档 + +- [仓位计算逻辑](./POSITION_SIZE_LOGIC.md) +- [飞书通知功能](./NOTIFICATION_FEATURE.md) +- [移动止损功能](./MOVE_STOP_LOSS_FEATURE.md) +- [执行器优化总结](./EXECUTOR_OPTIMIZATION_SUMMARY.md) + +--- + +## 📝 变更日志 + +### 2026-03-28 +- ✅ 为所有平台添加飞书通知功能 +- ✅ 实现移动止损功能(Bitget, Hyperliquid, PaperTrading) +- ✅ 集成持仓管理自动执行(crypto_agent.py) +- ✅ 创建完整文档 +- ✅ 修复 crypto_agent.py 中的移动止损调用逻辑 diff --git a/backend/app/crypto_agent/executor/LEVERAGE_CONFIGURATION.md b/backend/app/crypto_agent/executor/LEVERAGE_CONFIGURATION.md new file mode 100644 index 0000000..832a6b6 --- /dev/null +++ b/backend/app/crypto_agent/executor/LEVERAGE_CONFIGURATION.md @@ -0,0 +1,280 @@ +# 杠杆配置总结 +UPDATED: 2026-03-28 + +## 配置变更 + +### ✅ 已完成的修改 + +| 配置项 | 修改前 | 修改后 | 文件 | +|--------|--------|--------|------| +| **PaperTrading 单笔杠杆** | 20x | **10x** | `config.py:133` | +| **Bitget 默认杠杆** | 5x | **10x** | `crypto_agent.py:2580` | +| **Hyperliquid 默认杠杆** | 10x | **10x** (不变) | `crypto_agent.py:2884` | +| **总杠杆上限** | 10x | **10x** (不变) | `config.py` | + +--- + +## 当前配置 + +### 杠杆配置总览 + +| 平台 | 单笔杠杆 | 总杠杆上限 | 说明 | +|------|---------|----------|------| +| **PaperTrading** | 10x | 10x | 模拟盘统一10x杠杆 | +| **Bitget** | 10x | 10x | 实盘默认10x,可动态调整 | +| **Hyperliquid** | 10x | 10x | 实盘默认10x,最大10x | + +### 配置文件位置 + +```python +# config.py +class Settings(BaseSettings): + # 模拟交易 + paper_trading_leverage: int = 10 # ✅ 从20改为10 + paper_trading_max_total_leverage: float = 10 # 总杠杆上限 + + # Bitget 实盘 + bitget_max_total_leverage: float = 10 # 总杠杆上限 + + # Hyperliquid 实盘 + hyperliquid_max_total_leverage: float = 10 # 总杠杆上限. +``` + +### 代码实现 + +#### Bitget 开仓 +```python +# crypto_agent.py:2579-2581 +# 设置杠杆 (默认10x,最大10x) +leverage = min(decision.get('leverage', 10), 10) +self.bitget.update_leverage(symbol, leverage) +``` + +#### Hyperliquid 开仓 +```python +# crypto_agent.py:2884-2885 +leverage = min(decision.get('leverage', 10), 10) +self.hyperliquid.update_leverage(symbol, leverage) +``` + +#### PaperTrading 开仓 +```python +# paper_trading_service.py 使用配置中的杠杆 +self.leverage = settings.paper_trading_leverage # 10x +``` + +--- + +## 杠杆控制逻辑 + +### 单笔杠杆限制 + +```python +# 确保单笔杠杆不超过10x +leverage = min(decision.get('leverage', 10), 10) +``` + +### 总杠杆控制 + +系统会实时监控总杠杆使用情况: + +```python +# 计算当前总杠杆 +total_position_value = sum(all_positions_value) +current_total_leverage = total_position_value / account_balance + +# 检查是否还能开仓 +remaining_leverage = max_total_leverage - current_total_leverage + +if remaining_leverage <= 0: + # 已达最大杠杆,无法开仓 + return 0, f"已达最大杠杆 {current_leverage:.1f}x/{max_total_leverage}x" + +# 限制新开仓的杠杆 +max_new_position = account_balance * remaining_leverage +``` + +--- + +## 实际案例 + +### 案例 1: Bitget $1074 账户, A级信号 +``` +账户余额: $1,074 +可用余额: $1,074 +当前总杠杆: 0x (无持仓) + +信号置信度: 92% (A级) +保证金比例: 10% (Kelly公式型) +保证金: $1,074 × 10% = $107.40 + +单笔杠杆: 10x +持仓价值: $107.40 × 10 = $1,074 +当前总杠杆: $1,074 / $1,074 = 1.0x ✅ + +剩余可用杠杆: 10x - 1.0x = 9.0x +剩余可开仓金额: $1,074 × 9.0 = $9,666 +``` + +### 案例 2: Hyperliquid $2000 账户, 已有持仓 +``` +账户余额: $2,000 +当前持仓价值: $8,000 (已用杠杆 4x) +当前总杠杆: $8,000 / $2,000 = 4.0x + +新信号 (B级): +保证金比例: 6% (Kelly公式型) +保证金: $2,000 × 6% = $120 + +单笔杠杆: 10x +新持仓价值: $120 × 10 = $1,200 + +开仓后总杠杆: ($8,000 + $1,200) / $2,000 = 4.6x ✅ (< 10x) + +剩余可用杠杆: 10x - 4.6x = 5.4x +``` + +### 案例 3: 杠杆超限,拒绝开仓 +``` +账户余额: $1,000 +当前持仓价值: $9,500 (已用杠杆 9.5x) +当前总杠杆: $9,500 / $1,000 = 9.5x + +新信号 (A级): +保证金: $100 +期望杠杆: 10x +期望持仓价值: $1,000 + +预计总杠杆: ($9,500 + $1,000) / $1,000 = 10.5x ❌ (> 10x) + +系统拒绝: "已达最大杠杆 9.5x/10x" +建议: 先平仓部分持仓 +``` + +--- + +## Kelly公式型 + 10x杠杆的威力 + +### 资金利用效率对比 + +| 场景 | 3%仓位+5x杠杆 | 10%仓位+10x杠杆 | 倍数 | +|------|--------------|----------------|------| +| **$1000账户 A级信号** | $150 仓位 | $1000 仓位 | **6.7x** | +| **盈利 3%** | +$4.5 | +$30 | **6.7x** | +| **亏损 3%** | -$4.5 | -$30 | **6.7x** | + +### 示例: 10次交易后的差异 + +假设: +- A级信号胜率: 60% +- 平均盈利: 4% +- 平均亏损: 3% +- $1000账户 + +**保守配置 (3% + 5x)**: +``` +盈利: 6次 × $150 × 4% = $36 +亏损: 4次 × $150 × 3% = -$18 +净收益: +$18 (1.8%) +总杠杆峰值: ~1.5x (非常安全) +``` + +**Kelly配置 (10% + 10x)**: +``` +盈利: 6次 × $1000 × 4% = $240 +亏损: 4次 × $1000 × 3% = -$120 +净收益: +$120 (12%) 🚀 +总杠杆峰值: ~6x (风险可控) +``` + +**收益差异: 12% vs 1.8% = 6.7倍** + +--- + +## 风险管理 + +### 单笔最大亏损(-3%止损) + +| 信号等级 | 保证金 | 杠杆 | 持仓价值 | -3%亏损 | 占总资金% | +|---------|--------|-----|---------|---------|----------| +| **A级** | $100 | 10x | $1,000 | -$30 | **-3.0%** | +| **B级** | $60 | 10x | $600 | -$18 | **-1.8%** | +| **C级** | $20 | 10x | $200 | -$6 | **-0.6%** | + +### 最大回撤控制 + +- **单笔最大亏损**: -3% (A级信号止损) +- **连续5次亏损**: -15% (极端情况) +- **建议**: 设置账户级止损 -20% + +--- + +## 监控指标 + +### 实时监控 + +```python +# 每轮循环检查 +current_total_leverage = total_position_value / account_balance + +if current_total_leverage > 8.0: + # 警告: 接近杠杆上限 + logger.warning(f"⚠️ 总杠杆 {current_leverage:.1f}x,接近上限10x") + +if current_total_leverage >= 10.0: + # 紧急: 达到杠杆上限 + logger.error(f"🚨 已达最大杠杆 {current_leverage:.1f}x/10x") +``` + +### 告警通知 + +- **飞书通知**: 杠杆 > 8x 时发送告警 +- **日志记录**: 每次开仓记录杠杆变化 +- **自动拒绝**: 杠杆满时自动拒绝新信号 + +--- + +## 配置建议 + +### 保守型(推荐新手) +```python +paper_trading_leverage: int = 5 # 或保持10x但降低仓位比例 +base_margin_pct = 0.05 # A级5% +``` + +### 平衡型(当前配置) +```python +paper_trading_leverage: int = 10 +base_margin_pct = 0.10 # A级10% +``` + +### 激进型(仅限经验丰富) +```python +paper_trading_leverage: int = 10 +base_margin_pct = 0.15 # A级15% +max_total_leverage: float = 15 # ⚠️ 极高风险 +``` + +--- + +## 检查清单 + +- [x] PaperTrading 杠杆从20x改为10x +- [x] Bitget 默认杠杆从5x改为10x +- [x] Hyperliquid 默认杠杆保持10x +- [x] 总杠杆上限保持10x +- [x] 更新配置文档 +- [x] 创建杠杆控制文档 + +- [ ] 回测验证新配置效果 +- [ ] 实盘测试并监控 +- [ ] 根据实际表现微调 + +--- + +## 相关文档 + +- [仓位配置策略](./POSITION_SIZING_STRATEGY.md) +- [仓位计算逻辑](./POSITION_SIZE_LOGIC.md) +- [移动止损功能](./MOVE_STOP_LOSS_FEATURE.md) +- [功能完成总结](./FEATURE_SUMMARY.md) diff --git a/backend/app/crypto_agent/executor/MOVE_STOP_LOSS_FEATURE.md b/backend/app/crypto_agent/executor/MOVE_STOP_LOSS_FEATURE.md new file mode 100644 index 0000000..ceccfbf --- /dev/null +++ b/backend/app/crypto_agent/executor/MOVE_STOP_LOSS_FEATURE.md @@ -0,0 +1,321 @@ +# 移动止损功能文档 +CREATED: 2026-03-28 + +## 功能概述 + +所有平台(Bitget、Hyperliquid、PaperTrading)均已实现**移动止损**功能。当持仓盈利达到 2% 或以上时,系统会自动将止损价移动到入场价,锁定盈亏并降低风险。 + +## 触发条件 + +在 [base_executor.py](./base_executor.py) 的 `check_position_management()` 方法中定义: + +```python +# 规则3: 移动止损 +if pnl_pct >= 2: + current_sl = pos.get('stop_loss') + if side == 'buy' and current_sl and current_sl < entry_price: + actions.append({ + 'symbol': symbol, + 'action': 'MOVE_SL', + 'new_sl': entry_price, + 'reason': f"盈利 {pnl_pct:.1f}% >= 2%,移动止损到入场价", + 'priority': 3 + }) + elif side == 'sell' and current_sl and current_sl > entry_price: + actions.append({ + 'symbol': symbol, + 'action': 'MOVE_SL', + 'new_sl': entry_price, + 'reason': f"盈利 {pnl_pct:.1f}% >= 2%,移动止损到入场价", + 'priority': 3 + }) +``` + +### 条件详解 + +1. **盈利条件**: `pnl_pct >= 2%` (持仓盈利达到或超过2%) +2. **止损位置**: + - **做多** (`buy`): 当前止损 < 入场价 → 移动到入场价 + - **做空** (`sell`): 当前止损 > 入场价 → 移动到入场价 +3. **优先级**: 3 (低于 TAKE_PROFIT 和 TIME_EXIT) + +## 实现位置 + +### 1. 基类定义 ([base_executor.py:438](./base_executor.py#L438)) + +```python +@abstractmethod +async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """ + 移动止损 + + Args: + symbol: 交易对 + new_stop_loss: 新的止损价 + current_stop_loss: 当前止损价(可选) + + Returns: + {'success': bool, 'message': str} + """ + pass +``` + +### 2. Bitget 实现 ([bitget_executor.py:300](./bitget_executor.py#L300)) + +```python +async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """移动止损(Bitget)""" + try: + # Bitget 使用 modify_sl_tp 方法 + success = self.bitget.modify_sl_tp( + symbol=symbol.replace('USDT', ''), + stop_loss=new_stop_loss + ) + + if success: + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_stop_loss:.2f}") + return {'success': True, 'message': f'移动止损成功: {new_stop_loss:.2f}'} + else: + return {'success': False, 'message': '移动止损失败'} + + except Exception as e: + logger.error(f"Bitget 移动止损失败: {e}") + return {'success': False, 'message': str(e)} +``` + +**API**: `bitget.modify_sl_tp(symbol, stop_loss, take_profit)` + +### 3. Hyperliquid 实现 ([hyperliquid_executor.py:295](./hyperliquid_executor.py#L295)) + +```python +async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """移动止损(Hyperliquid)""" + try: + # Hyperliquid 使用 set_tp_sl 方法(只传 sl_price) + result = self.hyperliquid.set_tp_sl( + symbol=symbol.replace('USDT', ''), + sl_price=new_stop_loss + ) + + if result.get('success', False): + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_stop_loss:.2f}") + return {'success': True, 'message': f'移动止损成功: {new_stop_loss:.2f}'} + else: + return {'success': False, 'message': result.get('message', '移动止损失败')} + + except Exception as e: + logger.error(f"Hyperliquid 移动止损失败: {e}") + return {'success': False, 'message': str(e)} +``` + +**API**: `hyperliquid.set_tp_sl(symbol, sl_price)` + +### 4. PaperTrading 实现 ([paper_trading_executor.py:263](./paper_trading_executor.py#L263)) + +```python +async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """移动止损(模拟盘)""" + try: + # 查找该交易对的所有活跃订单 + orders = self.paper_trading.get_active_orders(symbol) + + if not orders: + return {'success': False, 'message': f'找不到 {symbol} 的活跃订单'} + + # 更新所有该交易对的订单止损价 + success_count = 0 + for order in orders: + update_result = self.paper_trading.update_order( + order_id=order.order_id, + stop_loss=new_stop_loss + ) + + if update_result.get('success'): + success_count += 1 + + if success_count > 0: + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_stop_loss:.2f} ({success_count}/{len(orders)} 订单)") + return { + 'success': True, + 'message': f'移动止损成功: {new_stop_loss:.2f} ({success_count}/{len(orders)} 订单)' + } + else: + return {'success': False, 'message': '所有订单移动止损失败'} + + except Exception as e: + logger.error(f"模拟盘移动止损失败: {e}") + return {'success': False, 'message': str(e)} +``` + +**API**: `paper_trading.update_order(order_id, stop_loss)` + +## 执行流程 + +### 在 crypto_agent.py 中调用 + +```python +async def _check_position_management_all_platforms(self): + """检查所有平台的持仓管理""" + try: + for platform_name, executor in self.executors.items(): + # 获取持仓 + positions = await executor.get_positions() + if not positions: + continue + + # 获取当前价格 + symbols = [pos.get('symbol') for pos in positions] + current_prices = {} + for symbol in symbols: + price = await self._get_current_price(symbol) + current_prices[symbol] = price + + # 检查持仓管理 + actions = executor.check_position_management(positions, current_prices) + + # 执行建议的操作 + for action_info in actions: + symbol = action_info.get('symbol') + action = action_info.get('action') + reason = action_info.get('reason', '') + + if action == 'MOVE_SL': + new_sl = action_info.get('new_sl') + if new_sl: + # 调用执行器的移动止损方法 + move_result = await executor.move_stop_loss( + symbol=symbol, + new_stop_loss=new_sl + ) + + if move_result.get('success'): + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_sl:.2f}") + await self._send_alert_notification( + f"🔒 [{platform_name}] 移动止损", + f"交易对: {symbol}\n新止损: ${new_sl:.2f}\n原因: {reason}" + ) + + # 发送飞书通知 + await executor.send_execution_notification( + operation='POSITION_MANAGEMENT', + symbol=symbol, + result={'success': True, 'action': 'MOVE_SL', 'reason': reason}, + details={'new_sl': new_sl, 'pnl_percent': pnl_pct} + ) + else: + logger.warning(f" ⚠️ 移动止损失败: {move_result.get('message')}") + + except Exception as e: + logger.error(f"检查持仓管理失败: {e}") +``` + +## 通知机制 + +### 1. 日志通知 +- ✅ 成功: `"✅ 移动止损成功: {symbol} → ${new_sl:.2f}"` +- ⚠️ 失败: `"⚠️ 移动止损失败: {message}"` + +### 2. 告警通知 +- 标题: `"🔒 [{platform_name}] 移动止损"` +- 内容: + ``` + 交易对: BTC + 新止损: $85,000.00 + 原因: 盈利 2.5% >= 2%,移动止损到入场价 + ``` + +### 3. 飞书通知 +- **操作类型**: `POSITION_MANAGEMENT` +- **操作**: `MOVE_SL` +- **颜色**: 蓝色 +- **详情**: + - 平台 + - 交易对 + - 操作: 移动止损 + - 原因 + - 新止损价 + - 盈亏百分比 + +## 配置参数 + +| 平台 | 目标盈利 | 最大持仓 | 移动止损触发 | 移动到 | +|------|---------|---------|------------|-------| +| **Bitget** | 3% | 6h | 盈利 >= 2% | 入场价 | +| **Hyperliquid** | 2.5% | 4h | 盈利 >= 2% | 入场价 | +| **PaperTrading** | 3% | 4h | 盈利 >= 2% | 入场价 | + +## 示例场景 + +### 场景 1: Bitget BTC 做多 +``` +入场价: $80,000 +当前价: $82,000 (盈利 2.5%) +当前止损: $78,000 + +触发条件: ✅ 盈利 2.5% >= 2% +执行动作: 移动止损到 $80,000 (入场价) +结果: 锁定盈亏,最坏情况保本退出 +``` + +### 场景 2: Hyperliquid ETH 做空 +``` +入场价: $3,500 +当前价: $3,400 (盈利 2.86%) +当前止损: $3,600 + +触发条件: ✅ 盈利 2.86% >= 2% +执行动作: 移动止损到 $3,500 (入场价) +结果: 锁定盈亏,最坏情况保本退出 +``` + +### 场景 3: PaperTrading SOL 做多 +``` +入场价: $140 +当前价: $145 (盈利 3.57%) +当前止损: $135 + +触发条件: ✅ 盈利 3.57% >= 2% +执行动作: 移动止损到 $140 (入场价) +结果: 锁定盈亏,最坏情况保本退出 +``` + +## 风险管理 + +### 优势 +1. **锁定盈亏**: 盈利 2% 后,最坏情况也能保本退出 +2. **降低心理压力**: 不用担心从盈利变亏损 +3. **自动化**: 无需人工干预,系统自动执行 + +### 注意事项 +1. **市场波动**: 剧烈波动可能导致止损被触发后价格反弹 +2. **止损距离**: 入场价作为止损可能较近,需结合市场情况 +3. **仓位大小**: 大仓位时移动止损更为重要 + +## 监控与调优 + +### 监控指标 +- 移动止损执行次数 +- 移动止损后价格反转次数 +- 移动止损触发后的最终盈亏 + +### 调优建议 +1. **触发阈值**: 可根据市场波动率调整(1.5% ~ 3%) +2. **移动位置**: 可移动到更保守的位置(如入场价 - 0.5%) +3. **分批移动**: 盈利 2% 移动到入场价,盈利 4% 移动到 +1% 等 + +## 相关文档 +- [仓位计算逻辑](./POSITION_SIZE_LOGIC.md) +- [飞书通知功能](./NOTIFICATION_FEATURE.md) +- [执行器优化总结](./EXECUTOR_OPTIMIZATION_SUMMARY.md) diff --git a/backend/app/crypto_agent/executor/NOTIFICATION_FEATURE.md b/backend/app/crypto_agent/executor/NOTIFICATION_FEATURE.md index edfb724..ef023b4 100644 --- a/backend/app/crypto_agent/executor/NOTIFICATION_FEATURE.md +++ b/backend/app/crypto_agent/executor/NOTIFICATION_FEATURE.md @@ -54,6 +54,8 @@ FIXED: 2026-03-28 - **颜色**: 根据操作类型(TAKE_PROFIT=绿色, TIME_EXIT=橙色, MOVE_SL=蓝色) - **内容**: 平台、交易对、操作类型、原因、盈亏百分比、持仓时长 +**特别说明**: 移动止损 (MOVE_SL) 会在持仓盈利达到 2% 时自动触发,详见 [MOVE_STOP_LOSS_FEATURE.md](./MOVE_STOP_LOSS_FEATURE.md) + ## 通知格式 使用飞书卡片消息(Interactive Card),格式如下: ``` diff --git a/backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC.md b/backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC.md index 5cabf26..d728972 100644 --- a/backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC.md +++ b/backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC.md @@ -1,9 +1,10 @@ -# 仓位大小计算逻辑 +# 仓位大小计算逻辑(超激进配置) +UPDATED: 2026-03-28 ## 📊 总体流程 ``` -市场信号 (LLM) → 硬编码规则决策 → 保证金计算 → 平台执行器 → 下单 +市场信号 (LLM) → 硬编码规则决策 → 保证金计算 → 平台执行器 → 下单 + 飞书通知 ↓ ↓ ↓ ↓ 置信度 75% 同向/反向检查 保证金金额 合约张数/币数量 ``` @@ -12,24 +13,25 @@ ## 1️⃣ 决策层:保证金计算 (`crypto_agent.py`) -### **输入参数** -- **信号置信度** (`confidence`): 0-100 分 -- **可用余额** (`available`): 账户可用 USDT -- **账户余额** (`balance`): 账户总余额 USDT -- **当前杠杆** (`current_total_leverage`): 已使用杠杆 -- **最大杠杆** (`max_total_leverage`): 允许的最大杠杆 +### **超激进配置** 🔥 + +| 信号等级 | 置信度范围 | 保证金比例 | $1000账户保证金 | 10x杠杆仓位 | +|---------|----------|----------|---------------|-----------| +| **A级** | ≥90分 | **20%** | $200 | $2,000 | +| **B级** | 70-89分 | **15%** | $150 | $1,500 | +| **C级** | <70分 | **8%** | $80 | $800 | ### **计算步骤** -#### **Step 1: 根据信号等级确定基础保证金比例** +#### **Step 1: 根据信号等级确定基础保证金比例(超激进配置)** ```python if confidence >= 90: - base_margin_pct = 0.03 # A级: 3% + base_margin_pct = 0.20 # A级: 20% (重仓出击) 🔥 elif confidence >= 70: - base_margin_pct = 0.02 # B级: 2% + base_margin_pct = 0.15 # B级: 15% (中仓跟进) 🔥 else: - base_margin_pct = 0.01 # C级: 1% + base_margin_pct = 0.08 # C级: 8% (轻仓试探) ``` #### **Step 2: 计算初始保证金** @@ -39,17 +41,17 @@ margin = available * base_margin_pct # 示例: # 可用余额: $1000 -# 信号等级: B级 (75分) -# margin = 1000 × 2% = $20 +# 信号等级: A级 (92分) +# margin = 1000 × 20% = $200 🔥 ``` #### **Step 3: 应用平台最小保证金限制** ```python -# Bitget 最小保证金(各币种不同) -BTC: min_margin = $85 # 0.01 BTC × $85000 ÷ 10x杠杆 -ETH: min_margin = $35 # 0.1 ETH × $3500 ÷ 10x杠杆 -SOL: min_margin = $14 # 1 SOL × $140 ÷ 10x杠杆 +# Bitget 最小保证金(各币种不同,考虑10x杠杆) +BTC: min_margin = $85 # 0.01 BTC × $85000 / 10x杠杆 +ETH: min_margin = $35 # 0.1 ETH × $3500 / 10x杠杆 +SOL: min_margin = $14 # 1 SOL × $140 / 10x杠杆 if margin < min_margin: margin = min_margin @@ -57,16 +59,16 @@ if margin < min_margin: **示例**: ``` -计算保证金: $20 +计算保证金: $200 BTC 最小保证金: $85 -调整后: margin = $85 +调整后: margin = $200 (大于$85,不调整) ✅ ``` #### **Step 4: 应用最大保证金限制** ```python -# 单笔不超过余额的 10% (Bitget/Hyperliquid) 或 5% (模拟盘) -max_margin = balance * max_margin_pct +# 单笔不超过余额的 10% (所有平台) +max_margin = balance * 0.10 if margin > max_margin: margin = max_margin @@ -74,10 +76,10 @@ if margin > max_margin: **示例**: ``` -计算保证金: $150 +计算保证金: $200 账户余额: $1000 最大限制: 10% -调整后: margin = $100 +调整后: margin = $100 (不超过$100) ⚠️ ``` #### **Step 5: 应用杠杆限制** @@ -95,12 +97,12 @@ if margin > max_margin_by_leverage: **示例**: ``` -计算保证金: $200 +计算保证金: $100 账户余额: $1000 -当前杠杆: 8x +当前杠杆: 0x 最大杠杆: 10x -剩余杠杆: 2x -调整后: margin = $1000 × 2 = $2000 (超过余额,限制为 $200) +剩余杠杆: 10x +调整后: margin = min($100, $1000 × 10 = $10000) = $100 ✅ ``` #### **Step 6: 确保不超过可用余额** @@ -114,21 +116,21 @@ if margin > available: ``` 输入: -- 信号置信度: 75% (B级) -- 可用余额: $1074 -- 账户余额: $1074 +- 信号置信度: 92% (A级) +- 可用余额: $1,074 +- 账户余额: $1,074 - 当前杠杆: 0x - 最大杠杆: 10x -Step 1: 基础保证金比例 = 2% (B级) -Step 2: 初始保证金 = 1074 × 2% = $21.48 -Step 3: BTC 最小保证金 = $85 → 调整为 $85 -Step 4: 最大保证金限制 = 1074 × 10% = $107.4 → 不调整 +Step 1: 基础保证金比例 = 20% (A级) 🔥 +Step 2: 初始保证金 = 1074 × 20% = $214.80 +Step 3: BTC 最小保证金 = $85 → 不调整 +Step 4: 最大保证金限制 = 1074 × 10% = $107.40 → 调整为 $107.40 ⚠️ Step 5: 剩余杠杆 = 10x → 不调整 -Step 6: $85 < $1074 → 不调整 +Step 6: $107.40 < $1074 → 不调整 -最终保证金: $85 -原因: "信号B级(75%) → 2%保证金,应用BTC最小保证金限制$85" +最终保证金: $107.40 (受10%最大限制,实际10%而非20%) +原因: "信号A级(92%) → 20%保证金,受平台10%限制 → 10%保证金" ``` --- @@ -137,19 +139,19 @@ Step 6: $85 < $1074 → 不调整 ### **Bitget 执行器** -#### **输入**: 保证金 `$85` + 杠杆 `5x` (假设) + 价格 `$85000` +#### **输入**: 保证金 `$107.40` + 杠杆 `10x` + 价格 `$85000` #### **Step 1: 计算持仓价值** ```python position_value = margin × leverage - = $85 × 5 = $425 + = $107.40 × 10 = $1,074 ``` #### **Step 2: 计算币数量** ```python coin_amount = position_value / price - = $425 / $85000 - = 0.005 BTC + = $1,074 / $85000 + = 0.01264 BTC ``` #### **Step 3: 获取合约规格** @@ -166,31 +168,16 @@ SOL: 1 SOL/张 #### **Step 4: 计算合约张数(向下取整)** ```python contracts = int(coin_amount / contract_size) - = int(0.005 / 0.01) - = 0 张 ❌ -``` - -**问题**: `0 张 < 1 张` → 无法下单! - -#### **解决方案: 调整保证金** - -```python -# 需要至少 1 张合约 -min_contracts = 1 -min_coin_amount = 1 × 0.01 = 0.01 BTC -min_position_value = 0.01 × $85000 = $850 -min_margin = $850 / 5x = $170 - -# 之前的最小保证金 $85 是按 10x 杠杆算的 -# 如果用 5x 杠杆,需要 $170 + = int(0.01264 / 0.01) + = 1 张 ✅ ``` **完整示例**: ``` -保证金: $170 -杠杆: 5x -持仓价值: $850 -BTC 数量: 0.01 BTC +保证金: $107.40 +杠杆: 10x +持仓价值: $1,074 +BTC 数量: 0.01264 BTC 合约张数: 1 张 ✅ ``` @@ -198,19 +185,19 @@ BTC 数量: 0.01 BTC ### **Hyperliquid 执行器** -#### **输入**: 保证金 `$50` + 杠杆 `5x` + 价格 `$85000` +#### **输入**: 保证金 `$100` + 杠杆 `10x` + 价格 `$85000` #### **Step 1: 计算持仓价值** ```python position_value = margin × leverage - = $50 × 5 = $250 + = $100 × 10 = $1,000 ``` #### **Step 2: 计算仓位大小(币数量)** ```python position_size = position_value / price - = $250 / $85000 - = 0.00294 BTC + = $1,000 / $85000 + = 0.01176 BTC ``` #### **Step 3: 直接下单(无合约规格限制)** @@ -219,8 +206,8 @@ position_size = position_value / price order_params = { 'symbol': 'BTC', 'is_buy': True, - 'size': 0.00294, # 直接使用币数量 - 'price': None, # 市价单 + 'size': 0.01176, # 直接使用币数量 + 'price': None, 'order_type': 'market', } ``` @@ -236,144 +223,44 @@ order_params = { | **最小单位** | 合约张数(整数) | 币数量(任意) | | **BTC 合约规格** | 0.01 BTC/张 | 无限制 | | **最小保证金** (10x杠杆) | $85 | $50 | -| **最小保证金** (5x杠杆) | $170 | $25 | | **仓位表示** | 张数 | 币数量 | -| **计算公式** | `(保证金 × 杠杆) / 价格 / 合约规格` | `(保证金 × 杠杆) / 价格` | +| **计算公式** | `(保证金×杠杆) / 价格 / 合约规格` | `(保证金×杠杆) / 价格` | --- -## 🔍 实际案例 +## 🛡️ 风险控制 -### **案例 1: Bitget BTC,账户 $1074** - -``` -信号: BTC 做多,置信度 75% (B级) - -Step 1 (决策层): -- 基础保证金 = $1074 × 2% = $21.48 -- 最小保证金限制 (BTC) = $85 -- 最终保证金 = $85 - -Step 2 (执行层,假设 10x 杠杆): -- 持仓价值 = $85 × 10 = $850 -- BTC 数量 = $850 / $85000 = 0.01 BTC -- 合约张数 = 0.01 / 0.01 = 1 张 ✅ - -结果: 下单 1 张 BTC 合约,保证金 $85 -``` - -### **案例 2: Bitget SOL,账户 $1074** - -``` -信号: SOL 做多,置信度 75% (B级) - -Step 1 (决策层): -- 基础保证金 = $1074 × 2% = $21.48 -- 最小保证金限制 (SOL) = $14 -- 最终保证金 = $21.48 (大于 $14,不调整) - -Step 2 (执行层,假设 5x 杠杆): -- 持仓价值 = $21.48 × 5 = $107.40 -- SOL 数量 = $107.40 / $140 = 0.767 SOL -- 合约张数 = 0.767 / 1 = 0 张 ❌ - -问题: 0 张 < 1 张 - -解决方案: 调整保证金到至少 $28 (28 × 5 / 140 / 1 = 1 张) - -实际调整: -- 最小保证金 (5x杠杆) = (1 × 1 × $140) / 5 = $28 -- 调整后保证金 = $28 -- SOL 数量 = $28 × 5 / $140 = 1 SOL -- 合约张数 = 1 / 1 = 1 张 ✅ - -结果: 下单 1 张 SOL 合约,保证金 $28 -``` - -### **案例 3: Hyperliquid BTC,账户 $1000** - -``` -信号: BTC 做多,置信度 80% (B级) - -Step 1 (决策层): -- 基础保证金 = $1000 × 2% = $20 -- 最小保证金限制 (BTC) = $50 -- 最终保证金 = $50 - -Step 2 (执行层,5x 杠杆): -- 持仓价值 = $50 × 5 = $250 -- BTC 数量 = $250 / $85000 = 0.00294 BTC -- 直接下单: 0.00294 BTC ✅ - -结果: 下单 0.00294 BTC,保证金 $50 -``` - ---- - -## ⚠️ 常见问题 - -### **问题 1: 为什么 Bitget 的仓位计算失败?** - -**原因**: Bitget 有合约规格限制,必须是整数张数。 - -**解决**: -```python -# 方法1: 提高杠杆(从 5x → 10x) -# $85 × 10 = $850 → 0.01 BTC → 1 张 ✅ - -# 方法2: 提高保证金 -# $170 × 5 = $850 → 0.01 BTC → 1 张 ✅ -``` - -### **问题 2: 为什么保证金会被调整两次?** - -**第一次调整** (决策层): -- 确保满足平台最小保证金(如 BTC $85) - -**第二次调整** (执行层): -- 确保至少能买 1 张合约 -- 考虑实际杠杆配置 - -**建议**: 统一在执行层调整,决策层只计算基础保证金。 - -### **问题 3: Hyperliquid 为什么不需要最小保证金?** - -**原因**: Hyperliquid 支持任意大小的仓位,没有合约规格限制。 - -**优势**: 可以精确控制仓位大小,无需凑整。 - ---- - -## 🎯 优化建议 - -### **1. 统一最小保证金计算** +### **账户级止损** (25%) ```python -def get_min_margin_for_symbol(symbol: str, leverage: int, platform: str) -> float: - """获取某币种的最小保证金(考虑杠杆)""" - if platform == 'Bitget': - contract_size = get_contract_size(symbol) - price = get_current_price(symbol) - min_contracts = 1 - min_position_value = min_contracts * contract_size * price - min_margin = min_position_value / leverage - return min_margin - elif platform == 'Hyperliquid': - # Hyperliquid 最小 $50 - return 50.0 - else: - return 0.0 +# 每轮循环开始时检查 +initial_balance = $10,000 +current_balance = $7,500 +drawdown = ($10,000 - $7,500) / $10,000 = 25% + +if drawdown >= 25%: + # 🚨 触发账户级止损 + # 1. 立即平掉所有持仓 + # 2. 停止交易系统 + # 3. 发送紧急通知 ``` -### **2. 在决策层预先计算** +### **警告阈值** (15%) ```python -# 在 _calculate_position_size 中 -leverage = signal.get('leverage', 5) # 使用实际杠杆 -min_margin = get_min_margin_for_symbol(symbol, leverage, platform_name) -if margin < min_margin: - margin = min_margin - logger.info(f" 调整保证金到最小值: ${margin:.2f} (杠杆 {leverage}x)") +if drawdown >= 15% and drawdown < 25%: + # ⚠️ 发送警告通知 + await send_alert("账户回撤警告: 15%") +``` + +### **总杠杆限制** (10x) + +```python +current_total_leverage = total_position_value / account_balance + +if current_total_leverage >= 10.0: + # 拒绝新开仓 + return "已达最大杠杆 10x/10x" ``` --- @@ -381,9 +268,10 @@ if margin < min_margin: ## 📝 总结 **决策层 (`crypto_agent.py`)**: -- ✅ 根据信号等级计算保证金(1%/2%/3%) +- ✅ 根据信号等级计算保证金(8%/15%/20%) - ✅ 应用平台规则(最小/最大限制) - ✅ 考虑杠杆空间 +- ✅ 账户级止损保护(25%) **执行层 (执行器)**: - ✅ Bitget: 保证金 → 币数量 → 合约张数(整数) @@ -396,21 +284,17 @@ if margin < min_margin: - **Bitget**: 受合约规格限制,必须整数张,最小保证金较高 - **Hyperliquid**: 无合约规格限制,任意大小,灵活性强 +**风险管理**: +- **账户止损**: 25% 回撤自动平仓 +- **警告阈值**: 15% 回撤发送警告 +- **总杠杆限制**: 10x 上限 + --- -## 📢 飞书通知集成 +## 相关文档 -### 功能说明 -所有交易执行操作都会自动发送飞书通知,详见 [NOTIFICATION_FEATURE.md](./NOTIFICATION_FEATURE.md) - -### 通知时机 -- **开仓**: 执行成功/失败后立即通知 -- **平仓**: 执行成功/失败后立即通知 -- **撤单**: 执行成功/失败后立即通知 -- **止盈止损**: 设置成功/失败后立即通知 - -### 通知内容 -- **平台**: Bitget / Hyperliquid / 模拟盘 -- **交易对**: BTC / ETH / SOL 等 -- **执行结果**: 成功/失败状态 -- **详细信息**: 订单ID、数量、价格、保证金、杠杆、盈亏等 +- [超激进配置详解](./AGGRESSIVE_CONFIG.md) +- [杠杆配置说明](./LEVERAGE_CONFIGURATION.md) +- [仓位策略对比](./POSITION_SIZING_STRATEGY.md) +- [移动止损功能](./MOVE_STOP_LOSS_FEATURE.md) +- [配置更新总结](./CONFIG_UPDATE_2026-03-28.md) diff --git a/backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC_OLD.md b/backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC_OLD.md new file mode 100644 index 0000000..08ac120 --- /dev/null +++ b/backend/app/crypto_agent/executor/POSITION_SIZE_LOGIC_OLD.md @@ -0,0 +1,426 @@ +# 仓位大小计算逻辑 + +## 📊 总体流程 + +``` +市场信号 (LLM) → 硬编码规则决策 → 保证金计算 → 平台执行器 → 下单 + ↓ ↓ ↓ ↓ + 置信度 75% 同向/反向检查 保证金金额 合约张数/币数量 +``` + +--- + +## 1️⃣ 决策层:保证金计算 (`crypto_agent.py`) + +### **输入参数** +- **信号置信度** (`confidence`): 0-100 分 +- **可用余额** (`available`): 账户可用 USDT +- **账户余额** (`balance`): 账户总余额 USDT +- **当前杠杆** (`current_total_leverage`): 已使用杠杆 +- **最大杠杆** (`max_total_leverage`): 允许的最大杠杆 + +### **计算步骤** + +#### **Step 1: 根据信号等级确定基础保证金比例** + +```python +if confidence >= 90: + base_margin_pct = 0.03 # A级: 3% +elif confidence >= 70: + base_margin_pct = 0.02 # B级: 2% +else: + base_margin_pct = 0.01 # C级: 1% +``` + +#### **Step 2: 计算初始保证金** + +```python +margin = available * base_margin_pct + +# 示例: +# 可用余额: $1000 +# 信号等级: B级 (75分) +# margin = 1000 × 2% = $20 +``` + +#### **Step 3: 应用平台最小保证金限制** + +```python +# Bitget 最小保证金(各币种不同) +BTC: min_margin = $85 # 0.01 BTC × $85000 ÷ 10x杠杆 +ETH: min_margin = $35 # 0.1 ETH × $3500 ÷ 10x杠杆 +SOL: min_margin = $14 # 1 SOL × $140 ÷ 10x杠杆 + +if margin < min_margin: + margin = min_margin +``` + +**示例**: +``` +计算保证金: $20 +BTC 最小保证金: $85 +调整后: margin = $85 +``` + +#### **Step 4: 应用最大保证金限制** + +```python +# 单笔不超过余额的 10% (Bitget/Hyperliquid) 或 5% (模拟盘) +max_margin = balance * max_margin_pct + +if margin > max_margin: + margin = max_margin +``` + +**示例**: +``` +计算保证金: $150 +账户余额: $1000 +最大限制: 10% +调整后: margin = $100 +``` + +#### **Step 5: 应用杠杆限制** + +```python +remaining_leverage = max_leverage - current_leverage + +if remaining_leverage <= 0: + return 0, "已达最大杠杆" + +max_margin_by_leverage = balance * remaining_leverage +if margin > max_margin_by_leverage: + margin = max_margin_by_leverage +``` + +**示例**: +``` +计算保证金: $200 +账户余额: $1000 +当前杠杆: 8x +最大杠杆: 10x +剩余杠杆: 2x +调整后: margin = $1000 × 2 = $2000 (超过余额,限制为 $200) +``` + +#### **Step 6: 确保不超过可用余额** + +```python +if margin > available: + margin = available * 0.95 # 留 5% 余量(手续费) +``` + +### **完整示例(Bitget BTC)** + +``` +输入: +- 信号置信度: 75% (B级) +- 可用余额: $1074 +- 账户余额: $1074 +- 当前杠杆: 0x +- 最大杠杆: 10x + +Step 1: 基础保证金比例 = 2% (B级) +Step 2: 初始保证金 = 1074 × 2% = $21.48 +Step 3: BTC 最小保证金 = $85 → 调整为 $85 +Step 4: 最大保证金限制 = 1074 × 10% = $107.4 → 不调整 +Step 5: 剩余杠杆 = 10x → 不调整 +Step 6: $85 < $1074 → 不调整 + +最终保证金: $85 +原因: "信号B级(75%) → 2%保证金,应用BTC最小保证金限制$85" +``` + +--- + +## 2️⃣ 执行层:平台特定转换 + +### **Bitget 执行器** + +#### **输入**: 保证金 `$85` + 杠杆 `5x` (假设) + 价格 `$85000` + +#### **Step 1: 计算持仓价值** +```python +position_value = margin × leverage + = $85 × 5 = $425 +``` + +#### **Step 2: 计算币数量** +```python +coin_amount = position_value / price + = $425 / $85000 + = 0.005 BTC +``` + +#### **Step 3: 获取合约规格** +```python +# BTC 合约规格 +contract_size = 0.01 BTC/张 + +# 不同币种的合约规格 +BTC: 0.01 BTC/张 +ETH: 0.1 ETH/张 +SOL: 1 SOL/张 +``` + +#### **Step 4: 计算合约张数(向下取整)** +```python +contracts = int(coin_amount / contract_size) + = int(0.005 / 0.01) + = 0 张 ❌ +``` + +**问题**: `0 张 < 1 张` → 无法下单! + +#### **解决方案: 调整保证金** + +```python +# 需要至少 1 张合约 +min_contracts = 1 +min_coin_amount = 1 × 0.01 = 0.01 BTC +min_position_value = 0.01 × $85000 = $850 +min_margin = $850 / 5x = $170 + +# 之前的最小保证金 $85 是按 10x 杠杆算的 +# 如果用 5x 杠杆,需要 $170 +``` + +**完整示例**: +``` +保证金: $170 +杠杆: 5x +持仓价值: $850 +BTC 数量: 0.01 BTC +合约张数: 1 张 ✅ +``` + +--- + +### **Hyperliquid 执行器** + +#### **输入**: 保证金 `$50` + 杠杆 `5x` + 价格 `$85000` + +#### **Step 1: 计算持仓价值** +```python +position_value = margin × leverage + = $50 × 5 = $250 +``` + +#### **Step 2: 计算仓位大小(币数量)** +```python +position_size = position_value / price + = $250 / $85000 + = 0.00294 BTC +``` + +#### **Step 3: 直接下单(无合约规格限制)** +```python +# Hyperliquid 支持任意大小 +order_params = { + 'symbol': 'BTC', + 'is_buy': True, + 'size': 0.00294, # 直接使用币数量 + 'price': None, # 市价单 + 'order_type': 'market', +} +``` + +**优势**: Hyperliquid 无最小合约限制,可以下任意大小的订单。 + +--- + +## 📊 平台对比 + +| 项目 | Bitget | Hyperliquid | +|------|--------|-------------| +| **最小单位** | 合约张数(整数) | 币数量(任意) | +| **BTC 合约规格** | 0.01 BTC/张 | 无限制 | +| **最小保证金** (10x杠杆) | $85 | $50 | +| **最小保证金** (5x杠杆) | $170 | $25 | +| **仓位表示** | 张数 | 币数量 | +| **计算公式** | `(保证金 × 杠杆) / 价格 / 合约规格` | `(保证金 × 杠杆) / 价格` | + +--- + +## 🔍 实际案例 + +### **案例 1: Bitget BTC,账户 $1074** + +``` +信号: BTC 做多,置信度 75% (B级) + +Step 1 (决策层): +- 基础保证金 = $1074 × 2% = $21.48 +- 最小保证金限制 (BTC) = $85 +- 最终保证金 = $85 + +Step 2 (执行层,假设 10x 杠杆): +- 持仓价值 = $85 × 10 = $850 +- BTC 数量 = $850 / $85000 = 0.01 BTC +- 合约张数 = 0.01 / 0.01 = 1 张 ✅ + +结果: 下单 1 张 BTC 合约,保证金 $85 +``` + +### **案例 2: Bitget SOL,账户 $1074** + +``` +信号: SOL 做多,置信度 75% (B级) + +Step 1 (决策层): +- 基础保证金 = $1074 × 2% = $21.48 +- 最小保证金限制 (SOL) = $14 +- 最终保证金 = $21.48 (大于 $14,不调整) + +Step 2 (执行层,假设 5x 杠杆): +- 持仓价值 = $21.48 × 5 = $107.40 +- SOL 数量 = $107.40 / $140 = 0.767 SOL +- 合约张数 = 0.767 / 1 = 0 张 ❌ + +问题: 0 张 < 1 张 + +解决方案: 调整保证金到至少 $28 (28 × 5 / 140 / 1 = 1 张) + +实际调整: +- 最小保证金 (5x杠杆) = (1 × 1 × $140) / 5 = $28 +- 调整后保证金 = $28 +- SOL 数量 = $28 × 5 / $140 = 1 SOL +- 合约张数 = 1 / 1 = 1 张 ✅ + +结果: 下单 1 张 SOL 合约,保证金 $28 +``` + +### **案例 3: Hyperliquid BTC,账户 $1000** + +``` +信号: BTC 做多,置信度 80% (B级) + +Step 1 (决策层): +- 基础保证金 = $1000 × 2% = $20 +- 最小保证金限制 (BTC) = $50 +- 最终保证金 = $50 + +Step 2 (执行层,5x 杠杆): +- 持仓价值 = $50 × 5 = $250 +- BTC 数量 = $250 / $85000 = 0.00294 BTC +- 直接下单: 0.00294 BTC ✅ + +结果: 下单 0.00294 BTC,保证金 $50 +``` + +--- + +## ⚠️ 常见问题 + +### **问题 1: 为什么 Bitget 的仓位计算失败?** + +**原因**: Bitget 有合约规格限制,必须是整数张数。 + +**解决**: +```python +# 方法1: 提高杠杆(从 5x → 10x) +# $85 × 10 = $850 → 0.01 BTC → 1 张 ✅ + +# 方法2: 提高保证金 +# $170 × 5 = $850 → 0.01 BTC → 1 张 ✅ +``` + +### **问题 2: 为什么保证金会被调整两次?** + +**第一次调整** (决策层): +- 确保满足平台最小保证金(如 BTC $85) + +**第二次调整** (执行层): +- 确保至少能买 1 张合约 +- 考虑实际杠杆配置 + +**建议**: 统一在执行层调整,决策层只计算基础保证金。 + +### **问题 3: Hyperliquid 为什么不需要最小保证金?** + +**原因**: Hyperliquid 支持任意大小的仓位,没有合约规格限制。 + +**优势**: 可以精确控制仓位大小,无需凑整。 + +--- + +## 🎯 优化建议 + +### **1. 统一最小保证金计算** + +```python +def get_min_margin_for_symbol(symbol: str, leverage: int, platform: str) -> float: + """获取某币种的最小保证金(考虑杠杆)""" + if platform == 'Bitget': + contract_size = get_contract_size(symbol) + price = get_current_price(symbol) + min_contracts = 1 + min_position_value = min_contracts * contract_size * price + min_margin = min_position_value / leverage + return min_margin + elif platform == 'Hyperliquid': + # Hyperliquid 最小 $50 + return 50.0 + else: + return 0.0 +``` + +### **2. 在决策层预先计算** + +```python +# 在 _calculate_position_size 中 +leverage = signal.get('leverage', 5) # 使用实际杠杆 +min_margin = get_min_margin_for_symbol(symbol, leverage, platform_name) +if margin < min_margin: + margin = min_margin + logger.info(f" 调整保证金到最小值: ${margin:.2f} (杠杆 {leverage}x)") +``` + +--- + +## 📝 总结 + +**决策层 (`crypto_agent.py`)**: +- ✅ 根据信号等级计算保证金(1%/2%/3%) +- ✅ 应用平台规则(最小/最大限制) +- ✅ 考虑杠杆空间 + +**执行层 (执行器)**: +- ✅ Bitget: 保证金 → 币数量 → 合约张数(整数) +- ✅ Hyperliquid: 保证金 → 币数量(任意) +- ✅ 预留手续费 +- ✅ 智能重试 +- ✅ **飞书通知**: 所有执行结果自动发送通知 + +**关键差异**: +- **Bitget**: 受合约规格限制,必须整数张,最小保证金较高 +- **Hyperliquid**: 无合约规格限制,任意大小,灵活性强 + +--- + +## 📢 飞书通知集成 + +### 功能说明 +所有交易执行操作都会自动发送飞书通知,详见 [NOTIFICATION_FEATURE.md](./NOTIFICATION_FEATURE.md) + +### 通知时机 +- **开仓**: 执行成功/失败后立即通知 +- **平仓**: 执行成功/失败后立即通知 +- **撤单**: 执行成功/失败后立即通知 +- **止盈止损**: 设置成功/失败后立即通知 + +### 通知内容 +- **平台**: Bitget / Hyperliquid / 模拟盘 +- **交易对**: BTC / ETH / SOL 等 +- **执行结果**: 成功/失败状态 +- **详细信息**: 订单ID、数量、价格、保证金、杠杆、盈亏等 + +## 📊 持仓管理功能 + +所有平台都实现了智能持仓管理,包括: + +1. **自动止盈** (TAKE_PROFIT): 达到目标盈利时自动平仓 +2. **超时退出** (TIME_EXIT): 持仓超过最大时长时自动平仓 +3. **移动止损** (MOVE_SL): 盈利达到 2% 时,自动移动止损到入场价 + +详细说明: [MOVE_STOP_LOSS_FEATURE.md](./MOVE_STOP_LOSS_FEATURE.md) diff --git a/backend/app/crypto_agent/executor/POSITION_SIZING_STRATEGY.md b/backend/app/crypto_agent/executor/POSITION_SIZING_STRATEGY.md new file mode 100644 index 0000000..37fe9c6 --- /dev/null +++ b/backend/app/crypto_agent/executor/POSITION_SIZING_STRATEGY.md @@ -0,0 +1,241 @@ +# 仓位配置方案 +UPDATED: 2026-03-28 + +## 当前方案: Kelly公式型 + +### 配置详情 + +| 信号等级 | 置信度范围 | 保证金比例 | $1000账户示例 | 5x杠杆仓位 | 10x杠杆仓位 | +|---------|----------|----------|-------------|-----------|------------| +| **A级** | ≥90分 | **10%** | $100 | $500 | $1,000 | +| **B级** | 70-89分 | **6%** | $60 | $300 | $600 | +| **C级** | <70分 | **2%** | $20 | $100 | $200 | + +### 特点 +- ✅ **最大化资金利用率**: A级信号用10%仓位,充分利用高质量机会 +- ✅ **分级明确**: 不同信号等级差异明显(10% / 6% / 2%) +- ✅ **适合小资金**: $1000账户也能开有意义仓位($500-$1000) +- ⚠️ **高风险**: 单笔最大亏损可能较大,需严格止损 + +### 理论基础: Kelly公式 + +Kelly公式用于计算最优仓位大小: + +``` +f* = (p × b - q) / b + +其中: +f* = 最优仓位比例 +p = 胜率 +q = 败率 (1 - p) +b = 盈亏比 (平均盈利/平均亏损) +``` + +**假设参数**: +- A级信号胜率: 65%, 盈亏比 2.0 → Kelly建议 ~22% (我们用10%更保守) +- B级信号胜率: 55%, 盈亏比 1.5 → Kelly建议 ~10% (我们用6%) +- C级信号胜率: 50%, 盈亏比 1.2 → Kelly建议 ~3% (我们用2%) + +## 实际案例 + +### 案例 1: Bitget BTC, $1074账户, A级信号 +``` +信号置信度: 92% (A级) +账户余额: $1,074 +可用余额: $1,074 + +Step 1: 基础保证金 = $1,074 × 10% = $107.40 +Step 2: 最小保证金限制 (BTC) = $85 → 不调整 +Step 3: 最大保证金限制 = $1,074 × 10% = $107.40 → 不调整 +Step 4: 杠杆限制 (5x) → 不调整 + +最终保证金: $107.40 +杠杆: 5x +持仓价值: $537 +BTC数量: 0.00631 BTC +合约张数: 0 张 ❌ + +问题: 0.00631 BTC / 0.01 BTC/张 = 0.631张 → 不足1张 + +解决: 调整保证金到 $170 +→ 0.01 BTC = 1张 ✅ +``` + +### 案例 2: Hyperliquid ETH, $1000账户, B级信号 +``` +信号置信度: 78% (B级) +账户余额: $1,000 +可用余额: $1,000 + +Step 1: 基础保证金 = $1,000 × 6% = $60 +Step 2: 最小保证金限制 = $50 → 不调整 +Step 3: 最大保证金限制 = $1,000 × 10% = $100 → 不调整 + +最终保证金: $60 +杠杆: 5x +持仓价值: $300 +ETH数量: 0.0857 ETH ✅ (Hyperliquid支持任意大小) +``` + +### 案例 3: PaperTrading SOL, $10000账户, C级信号 +``` +信号置信度: 65% (C级) +账户余额: $10,000 +可用余额: $10,000 + +Step 1: 基础保证金 = $10,000 × 2% = $200 +Step 2: 无最小限制 (模拟盘) +Step 3: 最大保证金限制 = $10,000 × 5% = $500 → 不调整 + +最终保证金: $200 +杠杆: 5x +持仓价值: $1,000 +SOL数量: 7.14 SOL ✅ +``` + +## 风险管理 + +### 单笔最大亏损计算 + +假设止损设置为-3%: + +| 信号等级 | 保证金 | 杠杆 | 持仓价值 | -3%亏损 | 占总资金% | +|---------|--------|-----|---------|---------|----------| +| **A级** | $100 | 5x | $500 | -$15 | -1.5% | +| **A级** | $100 | 10x | $1,000 | -$30 | -3.0% | +| **B级** | $60 | 5x | $300 | -$9 | -0.9% | +| **C级** | $20 | 5x | $100 | -$3 | -0.3% | + +### 最大持仓限制 + +除了保证金比例,还有其他限制: + +1. **平台最大保证金**: 单笔不超过余额的10% (Bitget/Hyperliquid) +2. **杠杆限制**: 总杠杆不超过10x +3. **最小保证金**: + - Bitget BTC: $85 (10x) / $170 (5x) + - Hyperliquid: $50 (任意杠杆) +4. **合约规格** (Bitget): + - 必须是整数张 + - BTC: 0.01 BTC/张 + - ETH: 0.1 ETH/张 + - SOL: 1 SOL/张 + +## 与其他方案对比 + +### 方案对比表 + +| 方案 | A级 | B级 | C级 | $1000账户A级仓位(5x) | 特点 | +|------|-----|-----|-----|---------------------|------| +| **保守型** | 3% | 2% | 1% | $150 | 风险低,收益慢 | +| **平衡型** | 5% | 3% | 1% | $250 | 风险收益平衡 | +| **激进型** | 8% | 5% | 2% | $400 | 高收益,高风险 | +| **Kelly型** (当前) | 10% | 6% | 2% | $500 | 最大化资金效率 | + +### 资金曲线对比 + +假设10次A级信号,胜率60%,平均盈利4%,平均亏损3%: + +``` +保守型 (3%): +- 盈利: 6次 × $150 × 4% = $36 +- 亏损: 4次 × $150 × 3% = -$18 +- 净收益: +$18 (1.8%) + +Kelly型 (10%): +- 盈利: 6次 × $500 × 4% = $120 +- 亏损: 4次 × $500 × 3% = -$60 +- 净收益: +$60 (6.0%) +``` + +**Kelly型收益是保守型的3.3倍**,但最大回撤也会更大。 + +## 调整建议 + +### 何时调整 + +1. **降低仓位** (回到平衡型): + - 连续亏损 > 5次 + - 账户回撤 > 15% + - 市场极度波动 (VIX > 40) + +2. **提高杠杆** (保持10%保证金): + - 使用10x杠杆替代5x + - A级信号仓位: $500 → $1,000 + - 适合高置信度信号 (≥95%) + +### 动态调整策略 + +```python +def get_dynamic_position_size(confidence, account, recent_performance): + """根据近期表现动态调整仓位""" + + # 基础比例 (Kelly型) + if confidence >= 90: + base_pct = 0.10 + elif confidence >= 70: + base_pct = 0.06 + else: + base_pct = 0.02 + + # 根据近期表现调整 + win_rate = recent_performance.get('win_rate_7d', 0.5) + + if win_rate < 0.4: + # 近期表现差,降低仓位 + base_pct *= 0.7 + elif win_rate > 0.7: + # 近期表现好,提高仓位 + base_pct *= 1.2 + + return account['available'] * base_pct +``` + +## 实施检查清单 + +- [x] 修改 `crypto_agent.py` 中的 `_calculate_position_size()` 方法 +- [x] 更新文档说明新比例 +- [x] 测试A级信号仓位计算 +- [x] 测试B级信号仓位计算 +- [x] 测试C级信号仓位计算 +- [x] 验证Bitget合约张数计算 +- [x] 验证Hyperliquid任意大小支持 + +- [ ] 实盘测试并监控 +- [ ] 根据实盘表现微调 + +## 相关配置文件 + +```python +# crypto_agent.py + +# Kelly公式型配置 +if confidence >= 90: + base_margin_pct = 0.10 # A级: 10% +elif confidence >= 70: + base_margin_pct = 0.06 # B级: 6% +else: + base_margin_pct = 0.02 # C级: 2% + +# 平台限制 +PLATFORM_RULES = { + 'Bitget': { + 'max_margin_pct': 0.10, # 单笔最大10% + 'min_margin': { + 'BTC': 85, # 10x杠杆 + 'ETH': 35, + 'SOL': 14 + } + }, + 'Hyperliquid': { + 'max_margin_pct': 0.10, + 'min_margin': 50 # 通用最小$50 + } +} +``` + +## 相关文档 + +- [仓位计算逻辑](./POSITION_SIZE_LOGIC.md) +- [执行器优化总结](./EXECUTOR_OPTIMIZATION_SUMMARY.md) +- [移动止损功能](./MOVE_STOP_LOSS_FEATURE.md) diff --git a/backend/app/crypto_agent/executor/base_executor.py b/backend/app/crypto_agent/executor/base_executor.py index cc2e363..db38adb 100644 --- a/backend/app/crypto_agent/executor/base_executor.py +++ b/backend/app/crypto_agent/executor/base_executor.py @@ -432,6 +432,26 @@ class BaseExecutor(ABC): """ pass + # ==================== 移动止损 ==================== + + @abstractmethod + async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """ + 移动止损 + + Args: + symbol: 交易对 + new_stop_loss: 新的止损价 + current_stop_loss: 当前止损价(可选) + + Returns: + {'success': bool, 'message': str} + """ + pass + # ==================== 飞书通知 ==================== async def send_execution_notification(self, diff --git a/backend/app/crypto_agent/executor/bitget_executor.py b/backend/app/crypto_agent/executor/bitget_executor.py index 184b44b..e8b77e8 100644 --- a/backend/app/crypto_agent/executor/bitget_executor.py +++ b/backend/app/crypto_agent/executor/bitget_executor.py @@ -295,6 +295,40 @@ class BitgetExecutor(BaseExecutor): """价格更新阈值: 0.5%""" return 0.5 + # ==================== 移动止损 ==================== + + async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """ + 移动止损(Bitget) + + Args: + symbol: 交易对(如 BTCUSDT) + new_stop_loss: 新止损价 + current_stop_loss: 当前止损价(可选) + + Returns: + {'success': bool, 'message': str} + """ + try: + # Bitget 使用 modify_sl_tp 方法 + success = self.bitget.modify_sl_tp( + symbol=symbol.replace('USDT', ''), + stop_loss=new_stop_loss + ) + + if success: + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_stop_loss:.2f}") + return {'success': True, 'message': f'移动止损成功: {new_stop_loss:.2f}'} + else: + return {'success': False, 'message': '移动止损失败'} + + except Exception as e: + logger.error(f"Bitget 移动止损失败: {e}") + return {'success': False, 'message': str(e)} + # ==================== 辅助方法 ==================== def _calculate_contracts(self, symbol: str, margin: float, price: float) -> int: diff --git a/backend/app/crypto_agent/executor/hyperliquid_executor.py b/backend/app/crypto_agent/executor/hyperliquid_executor.py index a059b4b..1ae2eeb 100644 --- a/backend/app/crypto_agent/executor/hyperliquid_executor.py +++ b/backend/app/crypto_agent/executor/hyperliquid_executor.py @@ -289,3 +289,37 @@ class HyperliquidExecutor(BaseExecutor): except Exception as e: logger.error(f"计算仓位大小失败: {e}") return 0 + + # ==================== 移动止损 ==================== + + async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """ + 移动止损(Hyperliquid) + + Args: + symbol: 交易对 + new_stop_loss: 新止损价 + current_stop_loss: 当前止损价(可选) + + Returns: + {'success': bool, 'message': str} + """ + try: + # Hyperliquid 使用 set_tp_sl 方法(只传 sl_price) + result = self.hyperliquid.set_tp_sl( + symbol=symbol.replace('USDT', ''), + sl_price=new_stop_loss + ) + + if result.get('success', False): + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_stop_loss:.2f}") + return {'success': True, 'message': f'移动止损成功: {new_stop_loss:.2f}'} + else: + return {'success': False, 'message': result.get('message', '移动止损失败')} + + except Exception as e: + logger.error(f"Hyperliquid 移动止损失败: {e}") + return {'success': False, 'message': str(e)} diff --git a/backend/app/crypto_agent/executor/paper_trading_executor.py b/backend/app/crypto_agent/executor/paper_trading_executor.py index 814bb8c..0b4e268 100644 --- a/backend/app/crypto_agent/executor/paper_trading_executor.py +++ b/backend/app/crypto_agent/executor/paper_trading_executor.py @@ -257,3 +257,51 @@ class PaperTradingExecutor(BaseExecutor): def get_price_update_threshold(self) -> float: """价格更新阈值:0.3%""" return 0.3 + + # ==================== 移动止损 ==================== + + async def move_stop_loss(self, + symbol: str, + new_stop_loss: float, + current_stop_loss: Optional[float] = None) -> Dict[str, Any]: + """ + 移动止损(模拟盘) + + Args: + symbol: 交易对 + new_stop_loss: 新止损价 + current_stop_loss: 当前止损价(可选) + + Returns: + {'success': bool, 'message': str} + """ + try: + # 查找该交易对的所有活跃订单 + orders = self.paper_trading.get_active_orders(symbol) + + if not orders: + return {'success': False, 'message': f'找不到 {symbol} 的活跃订单'} + + # 更新所有该交易对的订单止损价 + success_count = 0 + for order in orders: + update_result = self.paper_trading.update_order( + order_id=order.order_id, + stop_loss=new_stop_loss + ) + + if update_result.get('success'): + success_count += 1 + + if success_count > 0: + logger.info(f" ✅ 移动止损成功: {symbol} → ${new_stop_loss:.2f} ({success_count}/{len(orders)} 订单)") + return { + 'success': True, + 'message': f'移动止损成功: {new_stop_loss:.2f} ({success_count}/{len(orders)} 订单)' + } + else: + return {'success': False, 'message': '所有订单移动止损失败'} + + except Exception as e: + logger.error(f"模拟盘移动止损失败: {e}") + return {'success': False, 'message': str(e)}