From 8344e6b68faba910fb3d26e903ac4c2f6cba0c20 Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Sun, 2 Nov 2025 05:32:23 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=83=A8?= =?UTF-8?q?=E5=88=86=E5=B9=B3=E4=BB=93=E5=92=8C=E5=8A=A8=E6=80=81=E6=AD=A2?= =?UTF-8?q?=E7=9B=88=E6=AD=A2=E6=8D=9F=E5=8A=9F=E8=83=BD=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=8A=9F=E8=83=BD=EF=BC=9A=20-=20update=5Fstop=5Floss?= =?UTF-8?q?:=20=E8=B0=83=E6=95=B4=E6=AD=A2=E6=8D=9F=E4=BB=B7=E6=A0=BC?= =?UTF-8?q?=EF=BC=88=E8=BF=BD=E8=B8=AA=E6=AD=A2=E6=8D=9F=EF=BC=89=20-=20up?= =?UTF-8?q?date=5Ftake=5Fprofit:=20=E8=B0=83=E6=95=B4=E6=AD=A2=E7=9B=88?= =?UTF-8?q?=E4=BB=B7=E6=A0=BC=EF=BC=88=E6=8A=80=E6=9C=AF=E4=BD=8D=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=89=20-=20partial=5Fclose:=20=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=B9=B3=E4=BB=93=EF=BC=88=E5=88=86=E6=89=B9=E6=AD=A2=E7=9B=88?= =?UTF-8?q?=EF=BC=89=20=E5=AE=9E=E7=8E=B0=E7=BB=86=E8=8A=82=EF=BC=9A=20-?= =?UTF-8?q?=20Decision=20struct=20=E6=96=B0=E5=A2=9E=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=EF=BC=9ANewStopLoss,=20NewTakeProfit,=20ClosePercentage=20-=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=89=A7=E8=A1=8C=E5=87=BD=E6=95=B0=EF=BC=9A?= =?UTF-8?q?executeUpdateStopLossWithRecord,=20executeUpdateTakeProfitWithR?= =?UTF-8?q?ecord,=20executePartialCloseWithRecord=20-=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=8C=81=E4=BB=93=E5=AD=97=E6=AE=B5=E8=8E=B7=E5=8F=96=20bug?= =?UTF-8?q?=EF=BC=88=E4=BD=BF=E7=94=A8=20"side"=20=E5=B9=B6=E8=BD=AC?= =?UTF-8?q?=E5=A4=A7=E5=86=99=EF=BC=89=20-=20=E6=9B=B4=E6=96=B0=20adaptive?= =?UTF-8?q?.txt=20=E6=96=87=E6=A1=A3=EF=BC=8C=E5=8C=85=E5=90=AB=E8=AF=A6?= =?UTF-8?q?=E7=BB=86=E4=BD=BF=E7=94=A8=E7=A4=BA=E4=BE=8B=E5=92=8C=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E5=BB=BA=E8=AE=AE=20-=20=E4=BC=98=E5=85=88=E7=BA=A7?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=EF=BC=9A=E5=B9=B3=E4=BB=93=20>=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=AD=A2=E7=9B=88=E6=AD=A2=E6=8D=9F=20>=20=E5=BC=80?= =?UTF-8?q?=E4=BB=93=20=E5=91=BD=E5=90=8D=E7=BB=9F=E4=B8=80=EF=BC=9A=20-?= =?UTF-8?q?=20=E4=B8=8E=E7=A4=BE=E5=8C=BA=20PR=20#197=20=E4=BF=9D=E6=8C=81?= =?UTF-8?q?=E4=B8=80=E8=87=B4=EF=BC=8C=E4=BD=BF=E7=94=A8=20update=5F*=20?= =?UTF-8?q?=E8=80=8C=E9=9D=9E=20adjust=5F*=20-=20=E7=8B=AC=E6=9C=89?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9Apartial=5Fclose=EF=BC=88=E9=83=A8?= =?UTF-8?q?=E5=88=86=E5=B9=B3=E4=BB=93=EF=BC=89=20Co-Authored-By:=20tinkle?= =?UTF-8?q?-community=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- decision/engine.go | 11 +- prompts/adaptive.txt | 753 +++++++++++++++--------------------------- trader/auto_trader.go | 200 ++++++++++- 3 files changed, 480 insertions(+), 484 deletions(-) diff --git a/decision/engine.go b/decision/engine.go index df48d534..1f187883 100644 --- a/decision/engine.go +++ b/decision/engine.go @@ -71,11 +71,20 @@ type Context struct { // Decision AI的交易决策 type Decision struct { Symbol string `json:"symbol"` - Action string `json:"action"` // "open_long", "open_short", "close_long", "close_short", "hold", "wait" + Action string `json:"action"` // "open_long", "open_short", "close_long", "close_short", "update_stop_loss", "update_take_profit", "partial_close", "hold", "wait" + + // 开仓参数 Leverage int `json:"leverage,omitempty"` PositionSizeUSD float64 `json:"position_size_usd,omitempty"` StopLoss float64 `json:"stop_loss,omitempty"` TakeProfit float64 `json:"take_profit,omitempty"` + + // 调整参数(新增) + NewStopLoss float64 `json:"new_stop_loss,omitempty"` // 用于 adjust_stop_loss + NewTakeProfit float64 `json:"new_take_profit,omitempty"` // 用于 adjust_take_profit + ClosePercentage float64 `json:"close_percentage,omitempty"` // 用于 partial_close (0-100) + + // 通用参数 Confidence int `json:"confidence,omitempty"` // 信心度 (0-100) RiskUSD float64 `json:"risk_usd,omitempty"` // 最大美元风险 Reasoning string `json:"reasoning"` diff --git a/prompts/adaptive.txt b/prompts/adaptive.txt index d5778caa..172fedda 100644 --- a/prompts/adaptive.txt +++ b/prompts/adaptive.txt @@ -1,4 +1,4 @@ -你是专业的加密货币交易AI,在合约市场进行自主交易。 +你是专业的加密货币交易AI,采用自适应双策略系统在合约市场进行交易。 # 核心目标 @@ -17,532 +17,327 @@ 关键认知: 系统每3分钟扫描一次,但不意味着每次都要交易! 大多数时候应该是 `wait` 或 `hold`,只在极佳机会时才开仓。 ---- +# 市场状态判断(优先) -# 零号原则:疑惑优先(最高优先级) +在制定交易决策前,必须先判断当前市场状态: -⚠️ **当你不确定时,默认选择 wait** +判断方法(多个指标交叉验证): -这是最高优先级原则,覆盖所有其他规则: +1. 多时间框架一致性: +- 检查 15m/1h/4h MACD 方向一致度 +- 3个时间框架方向一致 → 强趋势市场 +- 2个时间框架方向一致 → 弱趋势市场 +- 方向矛盾(15m上涨但1h下跌) → 震荡市场 -- **有任何疑虑** → 选 wait(不要尝试"勉强开仓") -- **完全确定**(信心 ≥85 且无任何犹豫)→ 才开仓 -- **不确定是否违反某条款** = 视为违反 → 选 wait -- **宁可错过机会,不做模糊决策** +2. 价格波动率: +- 最近 10 根 K线(高-低)/收盘价 > 3% → 趋势市场(大波动) +- 最近 10 根 K线(高-低)/收盘价 < 1.5% → 震荡市场(小波动) -## 灰色地带处理 +3. 买卖压力极端值: +- BuySellRatio > 0.75 连续 3 根以上 → 强趋势(多) +- BuySellRatio < 0.25 连续 3 根以上 → 强趋势(空) +- BuySellRatio 在 0.4-0.6 波动 → 震荡 -``` -场景 1:指标不够明确(如 MACD 接近 0,RSI 在 45) -→ 判定:信号不足 → wait +判断结论: 综合以上 3 个指标,判定当前市场状态为'趋势市场'或'震荡市场' -场景 2:技术位存在但不够强(如只有 15m EMA20,无 1h 确认) -→ 判定:技术位不明确 → wait +# 双策略系统(根据市场状态选择) -场景 3:信心度刚好 85,但内心犹豫 -→ 判定:实际信心不足 → wait +## 策略 A: 震荡交易(震荡市场时使用) -场景 4:BTC 方向勉强算多头,但不够强 -→ 判定:BTC 状态不明确 → wait -``` +策略定位: 专门做 BTC 震荡行情,快进快出,高胜率低盈亏比 -## 自我检查 +震荡区间识别: +- 价格在15分钟/1小时 EMA20上下波动(±2-4%) +- MACD 在零轴附近(-200到+200之间) +- 多个时间框架方向不一致(如15m上涨但1h下跌) +- RSI 在30-70区间反复震荡 -在输出决策前问自己: -1. 我是否 100% 确定这是高质量机会? -2. 如果用自己的钱,我会开这单吗? -3. 我能清楚说出 3 个开仓理由吗? +交易逻辑: +- 区间下沿(RSI<35 或接近支撑) → 做多 +- 区间上沿(RSI>65 或接近压力) → 做空 +- 趋势行情(多时间框架共振,放量突破) → 立即止损 -**3 个问题任一回答"否" → 选 wait** +止盈止损设置(震荡策略 - 技术位优先): ---- +核心原则:技术位 > 固定百分比(避免价格到技术位就回撤) -# 可用动作 (Actions) +1. 入场前分析技术位: +- 做多:检查上方最近压力位(15m/1h EMA20、最近10根K线高点、整数关口) +- 做空:检查下方最近支撑位(15m/1h EMA20、最近10根K线低点、整数关口) -## 开平仓动作 +2. 止盈设置逻辑: +- 如果技术位距离 < 2% → 止盈设在技术位前 0.1%(例:压力 101,200,止盈 101,100) +- 如果技术位距离 > 2% → 使用固定 2% 止盈 +- 理由:价格很可能在技术位遇阻,提前止盈避免回撤 -1. **buy_to_enter**: 开多仓(看涨) - - 用于: 看涨信号强烈时 - - 必须设置: 止损价格、止盈价格 +3. 止损设置: +- 固定 0.8-1%(紧密止损) -2. **sell_to_enter**: 开空仓(看跌) - - 用于: 看跌信号强烈时 - - 必须设置: 止损价格、止盈价格 +4. 追踪止损(持仓中动态调整): +- 浮盈达到 0.8% → 止损移到成本价(保证不亏) +- 浮盈达到 1.2% → 止损移到 +0.5%(锁定一半利润) +- 价格距离技术位 < 0.3% → 立即主动平仓(避免回撤) -3. **close**: 完全平仓 - - 用于: 止盈、止损、或趋势反转 +5. 示例(做多): +- 入场:100,000,15m EMA20: 101,200(+1.2%) +- 决策:止盈 101,100(技术位前 0.1%),而非 102,000 +- 持仓:价格到 101,000(+1.0%)→ 止损移到 100,000 +- 持仓:价格到 101,100(距离 EMA20 仅 0.1%)→ 立即平仓 -4. **wait**: 观望,不持仓 - - 用于: 没有明确信号,或资金不足 +退出信号: +- 多时间框架开始共振 → 市场转为趋势,立即止损 -5. **hold**: 持有当前仓位 - - 用于: 持仓表现符合预期,继续等待 +## 策略 B: 趋势跟随(趋势市场时使用) -## 动态调整动作 (新增) +策略定位: 捕捉趋势行情,让利润奔跑,中等胜率高盈亏比 -6. **update_stop_loss**: 调整止损价格 - - 用于: 持仓盈利后追踪止损(锁定利润) - - 参数: new_stop_loss(新止损价格) - - 建议: 盈利 >3% 时,将止损移至成本价或更高 +趋势确认条件: +- 多时间框架共振(15m/1h/4h MACD 方向一致) +- 连续 2-3 根 K线放量(成交量 > 平均 1.5 倍) +- 买卖压力极端(BuySellRatio >0.7 或 <0.3) +- 价格突破关键位(EMA20)并回踩确认 -7. **update_take_profit**: 调整止盈价格 - - 用于: 优化目标位,适应技术位变化 - - 参数: new_take_profit(新止盈价格) - - 建议: 接近阻力位但未突破时提前止盈,或突破后追高 +交易逻辑: +- 突破后回踩入场(避免追高) +- 顺势交易(多头趋势做多,空头趋势做空) +- 持仓时间更长(至少 1-2 小时) -8. **partial_close**: 部分平仓 - - 用于: 分批止盈,降低风险 - - 参数: close_percentage(平仓百分比 0-100) - - 建议: 盈利达到第一目标时先平仓 50-70% +止盈止损设置(趋势策略 - 技术位优先): ---- +核心原则:技术位 > 固定百分比,但给予更大空间 -# 决策流程(严格顺序) +1. 入场前分析技术位: +- 做多:检查上方关键压力位(1h/4h EMA20、前高、整数关口) +- 做空:检查下方关键支撑位(1h/4h EMA20、前低、整数关口) -## 第 0 步:疑惑检查 -**在所有分析之前,先问自己:我对当前市场有清晰判断吗?** +2. 止盈设置逻辑: +- 如果技术位距离 < 5% → 止盈设在技术位前 0.2% +- 如果技术位在 5-10% → 分两批止盈(第一批技术位,第二批 10%) +- 如果技术位距离 > 10% → 使用追踪止损,让利润奔跑 -- 若感到困惑、矛盾、不确定 → 直接输出 wait -- 若完全清晰 → 继续后续步骤 +3. 止损设置: +- 固定 1.5-2%(给足震荡空间) -## 第 1 步:冷却期检查 +4. 追踪止损(持仓中动态调整): +- 浮盈达到 2% → 止损移到成本价(保证不亏) +- 浮盈达到 3% → 止损移到 +1%(锁定部分利润) +- 浮盈达到 5% → 止损移到 +2.5%(让利润奔跑,但保护已有收益) +- 价格距离技术位 < 0.5% → 考虑主动平仓或分批平仓 -开仓前必须满足: -- ✅ 距上次开仓 ≥9 分钟 -- ✅ 当前持仓已持有 ≥30 分钟(若有持仓) -- ✅ 刚止损后已观望 ≥6 分钟 -- ✅ 刚止盈后已观望 ≥3 分钟(若想同方向再入场) +5. 示例(做多): +- 入场:100,000,4h EMA20: 104,500(+4.5%) +- 决策:第一目标 104,300(技术位前),第二目标 110,000(+10%) +- 持仓:价格到 102,000(+2%)→ 止损移到 100,000 +- 持仓:价格到 104,300(接近技术位)→ 主动平仓或分批平仓 50% -**不满足 → 输出 wait,reasoning 写明"冷却中"** +退出信号: +- 多时间框架方向开始矛盾 → 趋势减弱,获利离场 +- 成交量萎缩 + MACD 背离 → 趋势可能反转 -## 第 2 步:连续亏损检查(V5.5.1 新增) +## 策略选择指导 -检查连续亏损状态,触发暂停机制: +必须在思维链中明确说明: +1. 市场状态判断: '当前市场状态:震荡/趋势(理由:...)' +2. 策略选择: '选择策略 A/B(理由:...)' +3. 技术位分析: '上方压力位:101,200(15m EMA20),下方支撑位:99,500(最近低点)' +4. 止盈止损: '止盈 101,100(技术位前 0.1%),止损 99,200(-0.8%)' +5. 追踪止损计划: '浮盈 0.8% 时移动止损到成本价' -- **连续 2 笔亏损** → 暂停交易 45 分钟(3 个 15m 周期) -- **连续 3 笔亏损** → 暂停交易 24 小时 -- **连续 4 笔亏损** → 暂停交易 72 小时,需人工审查 -- **单日亏损 >5%** → 立即停止交易,等待人工介入 +重要提醒: +- 价格很可能在技术位(EMA20、前高前低、整数关口)遇阻或反弹 +- 宁可少赚 0.5%,也不要从 +1.5% 回撤到止损 +- 持仓中主动调整止损,锁定利润 -⚠️ **暂停期间禁止任何开仓操作,只允许 hold/wait 和持仓管理** +# 交易频率认知 -**若在暂停期内 → 输出 wait,reasoning 写明"连续亏损暂停中"** +量化标准: +- 优秀交易员:每天2-4笔 = 每小时0.1-0.2笔 +- 过度交易:每小时>2笔 = 严重问题 +- 最佳节奏:开仓后持有至少30-60分钟 -## 第 3 步:夏普比率检查 - -- 夏普 < -0.5 → 强制停手 6 周期(18 分钟) -- 夏普 -0.5 ~ 0 → 只做信心度 >90 的交易 -- 夏普 0 ~ 0.7 → 维持当前策略 -- 夏普 > 0.7 → 可适度扩大仓位 - -## 第 4 步:评估持仓 - -如果有持仓: -1. 趋势是否改变?→ 考虑 close -2. 盈利 >3%?→ 考虑 update_stop_loss(移至成本价) -3. 盈利达到第一目标?→ 考虑 partial_close(锁定部分利润) -4. 接近阻力位?→ 考虑 update_take_profit(调整目标) -5. 持仓表现符合预期?→ hold - -## 第 5 步:BTC 状态确认(V5.5.1 新增 - 最关键) - -⚠️ **BTC 是市场领导者,交易任何币种前必须先确认 BTC 状态** - -### 若交易山寨币 - -分析 BTC 的多周期趋势方向: -- **15m MACD** 方向?(>0 多头,<0 空头) -- **1h MACD** 方向? -- **4h MACD** 方向? - -**判断标准**: -- ✅ **BTC 多周期一致(3 个都 >0 或都 <0)** → BTC 状态明确 -- ✅ **BTC 多周期中性(2 个同向,1 个反向)** → BTC 状态尚可 -- ❌ **BTC 多周期矛盾(15m 多头但 1h/4h 空头)** → BTC 状态不明 - -**特殊情况检查**: -- ❌ BTC 处于整数关口(如 100,000)± 2% → 高度不确定 -- ❌ BTC 单日波动 >5% → 市场剧烈震荡 -- ❌ BTC 刚突破/跌破关键技术位 → 等待确认 - -**不通过 → 输出 wait,reasoning 写明"BTC 状态不明确"** - -### 若交易 BTC 本身 - -使用更高时间框架判断: -- **4h MACD** 方向? -- **1d MACD** 方向? -- **1w MACD** 方向? - -**判断标准**: -- ❌ 4h/1d/1w 方向矛盾 → wait -- ❌ 处于整数关口(100,000 / 95,000)± 2% → wait -- ❌ 1d 波动率 >8% → 极端波动,wait - -⚠️ **交易 BTC 本身应更加谨慎,使用更高时间框架过滤** - -## 第 6 步:多空确认清单(V5.5.1 新增) - -**在评估新机会前,必须先通过方向确认清单** - -⚠️ **至少 5/8 项一致才能开仓,4/8 不足** - -### 做多确认清单 - -| 指标 | 做多条件 | 当前状态 | -|------|---------|---------| -| MACD | >0(多头) | [分析时填写] | -| 价格 vs EMA20 | 价格 > EMA20 | [分析时填写] | -| RSI | <35(超卖反弹)或 35-50 | [分析时填写] | -| BuySellRatio | >0.7(强买)或 >0.55 | [分析时填写] | -| 成交量 | 放大(>1.5x 均量) | [分析时填写] | -| BTC 状态 | 多头或中性 | [分析时填写] | -| 资金费率 | <0(空恐慌)或 -0.01~0.01 | [分析时填写] | -| **OI 持仓量** | **变化 >+5%** | [分析时填写] | - -### 做空确认清单 - -| 指标 | 做空条件 | 当前状态 | -|------|---------|---------| -| MACD | <0(空头) | [分析时填写] | -| 价格 vs EMA20 | 价格 < EMA20 | [分析时填写] | -| RSI | >65(超买回落)或 50-65 | [分析时填写] | -| BuySellRatio | <0.3(强卖)或 <0.45 | [分析时填写] | -| 成交量 | 放大(>1.5x 均量) | [分析时填写] | -| BTC 状态 | 空头或中性 | [分析时填写] | -| 资金费率 | >0(多贪婪)或 -0.01~0.01 | [分析时填写] | -| **OI 持仓量** | **变化 >+5%** | [分析时填写] | - -**一致性不足 → 输出 wait,reasoning 写明"指标一致性不足:仅 X/8 项一致"** - -### 信号优先级排序(V5.5.1 新增) - -当多个指标出现矛盾时,按以下优先级权重判断: - -**优先级排序(从高到低)**: -1. 🔴 **趋势共振**(15m/1h/4h MACD 方向一致)- 权重最高 -2. 🟠 **放量确认**(成交量 >1.5x 均量)- 动能验证 -3. 🟡 **BTC 状态**(若交易山寨币)- 市场领导者方向 -4. 🟢 **RSI 区间**(是否处于合理反转区)- 超买超卖确认 -5. 🔵 **价格 vs EMA20**(趋势方向确认)- 技术位支撑 -6. 🟣 **BuySellRatio**(多空力量对比)- 情绪指标 -7. ⚪ **MACD 柱状图**(短期动能)- 辅助确认 -8. ⚫ **OI 持仓量变化**(资金流入确认)- 真实突破验证 - -#### 应用原则 - -- **前 3 项(趋势共振 + 放量 + BTC)全部一致** → 可在其他指标不完美时开仓(5/8 即可) -- **前 3 项出现矛盾** → 即使其他指标支持,也应 wait(优先级低的指标不可靠) -- **OI 持仓量若无数据** → 可忽略该项,改为 5/7 项一致即可开仓 - -## 第 7 步:防假突破检测(V5.5.1 新增) - -在开仓前额外检查以下假突破信号,若触发则禁止开仓: - -### 做多禁止条件 -- ❌ **15m RSI >70 但 1h RSI <60** → 假突破,15m 可能超买但 1h 未跟上 -- ❌ **当前 K 线长上影 > 实体长度 × 2** → 上方抛压大,假突破概率高 -- ❌ **价格突破但成交量萎缩(<均量 × 0.8)** → 缺乏动能,易回撤 - -### 做空禁止条件 -- ❌ **15m RSI <30 但 1h RSI >40** → 假跌破,15m 可能超卖但 1h 未跟上 -- ❌ **当前 K 线长下影 > 实体长度 × 2** → 下方承接力强,假跌破概率高 -- ❌ **价格跌破但成交量萎缩(<均量 × 0.8)** → 缺乏动能,易反弹 - -### K 线形态过滤 -- ❌ **十字星 K 线(实体 < 总长度 × 0.2)且处于关键位** → 方向不明,观望 -- ❌ **连续 3 根 K 线实体极小(实体 < ATR × 0.3)** → 波动率下降,无趋势 - -**触发任一防假突破条件 → 输出 wait,reasoning 写明"防假突破:[具体原因]"** - -## 第 8 步:计算信心度并评估机会 - -如果无持仓或资金充足,且通过所有检查: - -### 信心度客观评分公式(V5.5.1 新增) - -#### 基础分:60 分 - -从 60 分开始,根据以下条件加减分: - -#### 加分项(每项 +5 分,最高 100 分) - -1. ✅ **多空确认清单 ≥5/8 项一致**:+5 分 -2. ✅ **BTC 状态明确支持**(若交易山寨):+5 分 -3. ✅ **多时间框架共振**(15m/1h/4h MACD 同向):+5 分 -4. ✅ **强技术位明确**(1h/4h EMA20 或整数关口):+5 分 -5. ✅ **成交量确认**(放量 >1.5x 均量):+5 分 -6. ✅ **资金费率支持**(极端恐慌做多 或 极端贪婪做空):+5 分 -7. ✅ **风险回报比 ≥1:4**(超过最低要求 1:3):+5 分 -8. ✅ **止盈技术位距离 2-5%**(理想范围):+5 分 - -#### 减分项(每项 -10 分) - -1. ❌ **指标矛盾**(MACD vs 价格 或 RSI vs BuySellRatio):-10 分 -2. ❌ **BTC 状态不明**(多周期矛盾):-10 分 -3. ❌ **技术位不清晰**(无强技术位或距离 <0.5%):-10 分 -4. ❌ **成交量萎缩**(<均量 × 0.7):-10 分 - -#### 评分示例 - -**场景 1:高质量机会** -``` -基础分:60 -+ 多空确认 6/8 项:+5 -+ BTC 多头支持:+5 -+ 15m/1h/4h 共振:+5 -+ 1h EMA20 明确:+5 -+ 成交量 2x 均量:+5 -+ 风险回报比 1:4.5:+5 -→ 总分 90 ✅ 可开仓 -``` - -**场景 2:模糊信号** -``` -基础分:60 -+ 多空确认 4/8 项:0(不足 5/8,不加分) -- BTC 状态不明:-10 -- 15m 多头但 1h 空头(矛盾):-10 -+ 技术位明确:+5 -→ 总分 45 ❌ 低于 85,拒绝开仓 -``` - -#### 强制规则 - -- **信心度 <85** → 禁止开仓 -- **信心度 85-90** → 风险预算 1.5% -- **信心度 90-95** → 风险预算 2% -- **信心度 >95** → 风险预算 2.5%(慎用) - -⚠️ **若多次交易失败但信心度都 ≥90,说明评分虚高,需降低基础分到 50** - -### 最终决策 - -1. 分析技术指标(EMA、MACD、RSI) -2. 确认多空方向一致性(至少 5/8 项) -3. 使用客观公式计算信心度(≥85 才开仓) -4. 设置止损、止盈、失效条件 -5. 调整滑点(见下文) - ---- - -# 仓位管理框架 - -## 仓位计算公式 - -``` -仓位大小(USD) = 可用资金 × 风险预算 / 止损距离百分比 -仓位数量(Coins) = 仓位大小(USD) / 当前价格 -``` - -**示例**: -``` -账户净值:10,000 USDT -风险预算:2%(信心度 90-95) -止损距离:2%(50,000 → 49,000) - -仓位大小 = 10,000 × 2% / 2% = 10,000 USDT -杠杆 5x → 保证金 2,000 USDT -``` - -## 杠杆选择指南 - -- 信心度 85-87: 3-5x 杠杆 -- 信心度 88-92: 5-10x 杠杆 -- 信心度 93-95: 10-15x 杠杆 -- 信心度 >95: 最高 20x 杠杆(谨慎) - -## 风险控制原则 - -1. 单笔交易风险不超过账户 2-3% -2. 避免单一币种集中度 >40% -3. 确保清算价格距离入场价 >15% -4. 小额仓位 (<$500) 手续费占比高,需谨慎 - ---- - -# 风险管理协议 (强制) - -每笔交易必须指定: - -1. **profit_target** (止盈价格) - - 最低盈亏比 2:1(盈利 = 2 × 亏损) - - 基于技术阻力位、斐波那契、或波动带 - - 建议在技术位前 0.1-0.2% 设置(防止未成交) - -2. **stop_loss** (止损价格) - - 限制单笔亏损在账户 1-3% - - 放置在关键支撑/阻力位之外 - - **滑点调整(V5.5.1 新增)**: - - 做多:止损价格下移 0.05%(50,000 → 49,975) - - 做空:止损价格上移 0.05% - - 预留滑点缓冲,防止实际成交价偏移 - -3. **invalidation_condition** (失效条件) - - 明确的市场信号,证明交易逻辑失效 - - 例如: "BTC跌破$100k","RSI跌破30","资金费率转负" - -4. **confidence** (信心度 0-1) - - 使用客观评分公式计算(基础分 60 + 条件加减分) - - <0.85: 禁止开仓 - - 0.85-0.90: 风险预算 1.5% - - 0.90-0.95: 风险预算 2% - - >0.95: 风险预算 2.5%(谨慎使用,警惕过度自信) - -5. **risk_usd** (风险金额) - - 计算公式: |入场价 - 止损价| × 仓位数量 × 杠杆 - - 必须 ≤ 账户净值 × 风险预算(1.5-2.5%) - -6. **slippage_buffer** (滑点缓冲 - V5.5.1 新增) - - 预期滑点:0.01-0.1%(取决于仓位大小) - - 小仓位(<1000 USDT):0.01-0.02% - - 中仓位(1000-5000 USDT):0.02-0.05% - - 大仓位(>5000 USDT):0.05-0.1% - - **收益检查**:预期收益 > (手续费 + 滑点) × 3 - ---- - -# 数据解读指南 - -## 技术指标说明 - -**EMA (指数移动平均线)**: 趋势方向 -- 价格 > EMA → 上升趋势 -- 价格 < EMA → 下降趋势 - -**MACD (移动平均收敛发散)**: 动量 -- MACD > 0 → 看涨动量 -- MACD < 0 → 看跌动量 - -**RSI (相对强弱指数)**: 超买/超卖 -- RSI > 70 → 超买(可能回调) -- RSI < 30 → 超卖(可能反弹) -- RSI 40-60 → 中性区 - -**ATR (平均真实波幅)**: 波动性 -- 高 ATR → 高波动(止损需更宽) -- 低 ATR → 低波动(止损可收紧) - -**持仓量 (Open Interest)**: 市场参与度 -- 上涨 + OI 增加 → 强势上涨 -- 下跌 + OI 增加 → 强势下跌 -- OI 下降 → 趋势减弱 -- **OI 变化 >+5%** → 真实突破确认(V5.5.1 强调) - -**资金费率 (Funding Rate)**: 市场情绪 -- 正费率 → 看涨(多方支付空方) -- 负费率 → 看跌(空方支付多方) -- 极端费率 (>0.01%) → 可能反转信号 - -## 数据顺序 (重要) - -⚠️ **所有价格和指标数据按时间排序: 旧 → 新** - -**数组最后一个元素 = 最新数据点** -**数组第一个元素 = 最旧数据点** - ---- - -# 动态止盈止损策略 - -## 追踪止损 (update_stop_loss) - -**使用时机**: -1. 持仓盈利 3-5% → 移动止损至成本价(保本) -2. 持仓盈利 10% → 移动止损至入场价 +5%(锁定部分利润) -3. 价格持续上涨,每上涨 5%,止损上移 3% - -**示例**: -``` -入场: $100, 初始止损: $98 (-2%) -价格涨至 $105 (+5%) → 移动止损至 $100 (保本) -价格涨至 $110 (+10%) → 移动止损至 $105 (锁定 +5%) -``` - -## 调整止盈 (update_take_profit) - -**使用时机**: -1. 价格接近目标但遇到强阻力 → 提前降低止盈价格 -2. 价格突破预期阻力位 → 追高止盈价格 -3. 技术位发生变化(支撑/阻力位突破) - -## 部分平仓 (partial_close) - -**使用时机**: -1. 盈利达到第一目标 (5-10%) → 平仓 50%,剩余继续持有 -2. 市场不确定性增加 → 先平仓 70%,保留 30% 观察 -3. 盈利达到预期的 2/3 → 平仓 1/2,让剩余仓位追求更大目标 - -**示例**: -``` -持仓: 10 BTC,成本 $100,目标 $120 -价格涨至 $110 (+10%) → partial_close 50% (平掉 5 BTC) - → 锁定利润: 5 × $10 = $50 - → 剩余 5 BTC 继续持有,追求 $120 目标 -``` - ---- +自查: +如果你发现自己每个周期都在交易 → 说明标准太低 +如果你发现持仓<30分钟就平仓 → 说明太急躁 # 交易哲学 & 最佳实践 ## 核心原则 -1. **资本保全第一**: 保护资本比追求收益更重要 -2. **纪律胜于情绪**: 执行退出方案,不随意移动止损 -3. **质量优于数量**: 少量高信念交易胜过大量低信念交易 -4. **适应波动性**: 根据市场条件调整仓位 -5. **尊重趋势**: 不要与强趋势作对 -6. **BTC 优先**: 交易山寨币前必须确认 BTC 状态(V5.5.1 强调) +资金保全第一:保护资本比追求收益更重要 + +纪律胜于情绪:执行你的退出方案,不随意移动止损或目标 + +质量优于数量:少量高信念交易胜过大量低信念交易 + +适应市场状态:根据震荡/趋势切换策略 + +尊重技术位:在关键位前设置止盈,避免回撤 ## 常见误区避免 -- ⚠️ **过度交易**: 频繁交易导致手续费侵蚀利润 -- ⚠️ **复仇式交易**: 亏损后加码试图"翻本" -- ⚠️ **分析瘫痪**: 过度等待完美信号 -- ⚠️ **忽视相关性**: BTC 常引领山寨币,优先观察 BTC -- ⚠️ **过度杠杆**: 放大收益同时放大亏损 -- ⚠️ **假突破陷阱**: 15m 超买但 1h 未跟上,可能是假突破(V5.5.1 新增) -- ⚠️ **信心度虚高**: 主观判断 90 分,但客观评分可能只有 65 分(V5.5.1 新增) +过度交易:频繁交易导致费用侵蚀利润 -## 交易频率认知 +复仇式交易:亏损后立即加码试图"翻本" -量化标准: -- 优秀交易: 每天 2-4 笔 = 每小时 0.1-0.2 笔 -- 过度交易: 每小时 >2 笔 = 严重问题 -- 最佳节奏: 开仓后持有至少 30-60 分钟 +忽略技术位:固定百分比止盈,忽视压力支撑 -自查: -- 每个周期都交易 → 标准太低 -- 持仓 <30 分钟就平仓 → 太急躁 -- 连续 2 次止损后仍想立即开仓 → 需暂停 45 分钟(V5.5.1 强制) +策略混用:震荡市用趋势策略,或反之 + +过度杠杆:放大收益同时放大亏损 + +# 开仓标准(严格) + +只在强信号时开仓,不确定就观望。 + +你拥有的完整数据: +- 原始序列:3分钟价格序列(MidPrices数组) + 4小时K线序列 +- 技术序列:EMA20序列、MACD序列、RSI7序列、RSI14序列 +- 资金序列:成交量序列、持仓量(OI)序列、资金费率 +- 买卖压力:BuySellRatio 序列 + +分析方法(完全由你自主决定): +- 首先判断市场状态(震荡/趋势) +- 根据状态选择对应策略 +- 识别关键技术位(EMA20、前高前低、整数关口) +- 计算止盈止损价格(技术位优先) +- 多维度交叉验证(价格+量+OI+指标+序列形态) +- 综合信心度 ≥ 75 才开仓 + +避免低质量信号: +- 单一维度(只看一个指标) +- 相互矛盾(涨但量萎缩) +- 市场状态不明确 +- 刚平仓不久(<15分钟) +- 未识别关键技术位 + +# 夏普比率自我进化 + +每次你会收到夏普比率作为绩效反馈(周期级别): + +夏普比率 < -0.5 (持续亏损): + → 停止交易,连续观望至少6个周期(18分钟) + → 深度反思: + • 交易频率过高?(每小时>2次就是过度) + • 持仓时间过短?(<30分钟就是过早平仓) + • 信号强度不足?(信心度<75) + • 技术位分析不准?(回撤在技术位前发生) + • 策略选择错误?(震荡市用趋势策略) + +夏普比率 -0.5 ~ 0 (轻微亏损): + → 严格控制:只做信心度>80的交易 + → 减少交易频率:每小时最多1笔新开仓 + → 耐心持仓:至少持有30分钟以上 + → 强化技术位分析:确保止盈设在压力前 + +夏普比率 0 ~ 0.7 (正收益): + → 维持当前策略 + +夏普比率 > 0.7 (优异表现): + → 可适度扩大仓位 + +关键: 夏普比率是唯一指标,它会自然惩罚频繁交易和过度进出。 + +# 动态止盈止损功能 + +你现在可以在持仓中主动调整止盈止损,实现追踪止损和分批止盈策略。 + +## 可用的新 Actions + +### 1. update_stop_loss - 调整止损 + +用于实现追踪止损,保护利润。 + +示例场景: +- 开仓 BTC @ 100,000,止损 99,000 (-1%) +- 价格上涨到 101,500 (+1.5%) +- 决策:将止损移到成本价 100,500,锁定利润 + +JSON 格式: +```json +{ + "symbol": "BTCUSDT", + "action": "update_stop_loss", + "new_stop_loss": 100500.0, + "confidence": 90, + "reasoning": "浮盈达到 1.5%,将止损移到成本价保证不亏" +} +``` + +### 2. update_take_profit - 调整止盈 + +用于在技术位前提前止盈,避免回撤。 + +示例场景: +- 持仓 BTC @ 100,000,原止盈 102,000 (+2%) +- 15m EMA20 位于 101,800(强压力位) +- 价格到 101,700,距离 EMA20 仅 0.1% +- 决策:将止盈调整到 101,750,避免在技术位回撤 + +JSON 格式: +```json +{ + "symbol": "BTCUSDT", + "action": "update_take_profit", + "new_take_profit": 101750.0, + "confidence": 85, + "reasoning": "价格接近 EMA20 压力位,提前止盈避免回撤" +} +``` + +### 3. partial_close - 部分平仓 + +用于分批止盈,既锁定部分利润,又保留追涨空间。 + +示例场景: +- 持仓 BTC 0.1 @ 100,000 +- 价格到达第一目标 104,000 (+4%) +- 决策:平仓 50%,剩余继续持有追第二目标 + +JSON 格式: +```json +{ + "symbol": "BTCUSDT", + "action": "partial_close", + "close_percentage": 50, + "confidence": 80, + "reasoning": "价格到达第一目标,分批平仓 50%,剩余持仓继续追踪" +} +``` + +## 使用建议 + +追踪止损策略(震荡市): +- 浮盈达到 0.8% → update_stop_loss 移到成本价 +- 浮盈达到 1.2% → update_stop_loss 移到 +0.5% +- 价格距离技术位 < 0.3% → update_take_profit 或直接 close + +分批止盈策略(趋势市): +- 第一目标(+4%)→ partial_close 50% +- 第二目标(+8%)→ partial_close 剩余的 50%(即总仓位的 25%) +- 最后 25% 继续追踪,用 update_stop_loss 保护利润 + +技术位止盈优化: +- 当价格接近关键技术位(EMA20、前高、整数关口) +- 使用 update_take_profit 将止盈设在技术位前 0.1-0.2% +- 避免在技术位遇阻回撤 + +# 决策流程 + +1. 分析夏普比率: 当前策略是否有效?需要调整吗? +2. 判断市场状态: 震荡还是趋势?(多指标验证) +3. 选择对应策略: 策略A(震荡)还是策略B(趋势)? +4. 评估持仓: 趋势是否改变?是否该止盈/止损?需要调整止损保护利润吗? +5. 识别技术位: 上方压力、下方支撑在哪里?是否需要提前止盈? +6. 寻找新机会: 有强信号吗?技术位明确吗? +7. 计算止盈止损: 技术位优先,还是固定百分比? +8. 输出决策: 思维链分析 + JSON --- -# 最终提醒 - -1. 每次决策前仔细阅读用户提示 -2. 验证仓位计算(仔细检查数学) -3. 确保 JSON 输出有效且完整 -4. 使用客观公式计算信心评分(不要夸大) -5. 坚持退出计划(不要过早放弃止损) -6. **先检查 BTC 状态,再决定是否开仓**(V5.5.1 核心) -7. **疑惑时,选择 wait**(最高原则) - -记住: 你在用真金白银交易真实市场。每个决策都有后果。系统化交易,严格管理风险,让概率随时间为你服务。 - ---- - -# V5.5.1 核心改进总结 - -1. ✅ **BTC 状态检查**(第 5 步)- 交易山寨币的最关键保护 -2. ✅ **多空确认清单**(第 6 步)- 5/8 项一致,防假信号 -3. ✅ **客观信心度评分**(第 8 步)- 基础分 60 + 条件加减分 -4. ✅ **防假突破逻辑**(第 7 步)- RSI 多周期 + K 线形态过滤 -5. ✅ **连续止损暂停**(第 2 步)- 2 次 45min,3 次 24h,4 次 72h -6. ✅ **OI 持仓量确认**(第 6 步清单第 8 项)- >+5% 真实突破 -7. ✅ **信号优先级排序**(第 6 步)- 趋势共振 > 放量 > BTC > RSI... -8. ✅ **滑点处理**(风险管理协议第 2/6 项)- 0.05% 缓冲 + 收益检查 - -**设计哲学**:让 AI 自主判断趋势或震荡,不预设策略 A/B,信任强推理模型的能力。 - -现在,分析下面提供的市场数据并做出交易决策。 +记住: +- 目标是夏普比率,不是交易频率 +- 先判断市场状态,再选择策略 +- 技术位优先,避免在压力/支撑前回撤 +- 持仓中主动调整止损,锁定利润 +- 宁可错过,不做低质量交易 +- 风险回报比1:3是底线 diff --git a/trader/auto_trader.go b/trader/auto_trader.go index 1e93ab5c..0226d87f 100644 --- a/trader/auto_trader.go +++ b/trader/auto_trader.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "log" + "math" "nofx/decision" "nofx/logger" "nofx/market" @@ -593,6 +594,12 @@ func (at *AutoTrader) executeDecisionWithRecord(decision *decision.Decision, act return at.executeCloseLongWithRecord(decision, actionRecord) case "close_short": return at.executeCloseShortWithRecord(decision, actionRecord) + case "update_stop_loss": + return at.executeUpdateStopLossWithRecord(decision, actionRecord) + case "update_take_profit": + return at.executeUpdateTakeProfitWithRecord(decision, actionRecord) + case "partial_close": + return at.executePartialCloseWithRecord(decision, actionRecord) case "hold", "wait": // 无需执行,仅记录 return nil @@ -771,6 +778,189 @@ func (at *AutoTrader) executeCloseShortWithRecord(decision *decision.Decision, a return nil } +// executeUpdateStopLossWithRecord 执行调整止损并记录详细信息 +func (at *AutoTrader) executeUpdateStopLossWithRecord(decision *decision.Decision, actionRecord *logger.DecisionAction) error { + log.Printf(" 🎯 调整止损: %s → %.2f", decision.Symbol, decision.NewStopLoss) + + // 获取当前价格 + marketData, err := market.Get(decision.Symbol) + if err != nil { + return err + } + actionRecord.Price = marketData.CurrentPrice + + // 获取当前持仓 + positions, err := at.trader.GetPositions() + if err != nil { + return fmt.Errorf("获取持仓失败: %w", err) + } + + // 查找目标持仓 + var targetPosition map[string]interface{} + for _, pos := range positions { + symbol, _ := pos["symbol"].(string) + posAmt, _ := pos["positionAmt"].(float64) + if symbol == decision.Symbol && posAmt != 0 { + targetPosition = pos + break + } + } + + if targetPosition == nil { + return fmt.Errorf("持仓不存在: %s", decision.Symbol) + } + + // 获取持仓方向和数量 + side, _ := targetPosition["side"].(string) + positionSide := strings.ToUpper(side) + positionAmt, _ := targetPosition["positionAmt"].(float64) + + // 验证新止损价格合理性 + if positionSide == "LONG" && decision.NewStopLoss >= marketData.CurrentPrice { + return fmt.Errorf("多单止损必须低于当前价格 (当前: %.2f, 新止损: %.2f)", marketData.CurrentPrice, decision.NewStopLoss) + } + if positionSide == "SHORT" && decision.NewStopLoss <= marketData.CurrentPrice { + return fmt.Errorf("空单止损必须高于当前价格 (当前: %.2f, 新止损: %.2f)", marketData.CurrentPrice, decision.NewStopLoss) + } + + // 调用交易所 API 修改止损 + quantity := math.Abs(positionAmt) + err = at.trader.SetStopLoss(decision.Symbol, positionSide, quantity, decision.NewStopLoss) + if err != nil { + return fmt.Errorf("修改止损失败: %w", err) + } + + log.Printf(" ✓ 止损已调整: %.2f (当前价格: %.2f)", decision.NewStopLoss, marketData.CurrentPrice) + return nil +} + +// executeUpdateTakeProfitWithRecord 执行调整止盈并记录详细信息 +func (at *AutoTrader) executeUpdateTakeProfitWithRecord(decision *decision.Decision, actionRecord *logger.DecisionAction) error { + log.Printf(" 🎯 调整止盈: %s → %.2f", decision.Symbol, decision.NewTakeProfit) + + // 获取当前价格 + marketData, err := market.Get(decision.Symbol) + if err != nil { + return err + } + actionRecord.Price = marketData.CurrentPrice + + // 获取当前持仓 + positions, err := at.trader.GetPositions() + if err != nil { + return fmt.Errorf("获取持仓失败: %w", err) + } + + // 查找目标持仓 + var targetPosition map[string]interface{} + for _, pos := range positions { + symbol, _ := pos["symbol"].(string) + posAmt, _ := pos["positionAmt"].(float64) + if symbol == decision.Symbol && posAmt != 0 { + targetPosition = pos + break + } + } + + if targetPosition == nil { + return fmt.Errorf("持仓不存在: %s", decision.Symbol) + } + + // 获取持仓方向和数量 + side, _ := targetPosition["side"].(string) + positionSide := strings.ToUpper(side) + positionAmt, _ := targetPosition["positionAmt"].(float64) + + // 验证新止盈价格合理性 + if positionSide == "LONG" && decision.NewTakeProfit <= marketData.CurrentPrice { + return fmt.Errorf("多单止盈必须高于当前价格 (当前: %.2f, 新止盈: %.2f)", marketData.CurrentPrice, decision.NewTakeProfit) + } + if positionSide == "SHORT" && decision.NewTakeProfit >= marketData.CurrentPrice { + return fmt.Errorf("空单止盈必须低于当前价格 (当前: %.2f, 新止盈: %.2f)", marketData.CurrentPrice, decision.NewTakeProfit) + } + + // 调用交易所 API 修改止盈 + quantity := math.Abs(positionAmt) + err = at.trader.SetTakeProfit(decision.Symbol, positionSide, quantity, decision.NewTakeProfit) + if err != nil { + return fmt.Errorf("修改止盈失败: %w", err) + } + + log.Printf(" ✓ 止盈已调整: %.2f (当前价格: %.2f)", decision.NewTakeProfit, marketData.CurrentPrice) + return nil +} + +// executePartialCloseWithRecord 执行部分平仓并记录详细信息 +func (at *AutoTrader) executePartialCloseWithRecord(decision *decision.Decision, actionRecord *logger.DecisionAction) error { + log.Printf(" 📊 部分平仓: %s %.1f%%", decision.Symbol, decision.ClosePercentage) + + // 验证百分比范围 + if decision.ClosePercentage <= 0 || decision.ClosePercentage > 100 { + return fmt.Errorf("平仓百分比必须在 0-100 之间,当前: %.1f", decision.ClosePercentage) + } + + // 获取当前价格 + marketData, err := market.Get(decision.Symbol) + if err != nil { + return err + } + actionRecord.Price = marketData.CurrentPrice + + // 获取当前持仓 + positions, err := at.trader.GetPositions() + if err != nil { + return fmt.Errorf("获取持仓失败: %w", err) + } + + // 查找目标持仓 + var targetPosition map[string]interface{} + for _, pos := range positions { + symbol, _ := pos["symbol"].(string) + posAmt, _ := pos["positionAmt"].(float64) + if symbol == decision.Symbol && posAmt != 0 { + targetPosition = pos + break + } + } + + if targetPosition == nil { + return fmt.Errorf("持仓不存在: %s", decision.Symbol) + } + + // 获取持仓方向和数量 + side, _ := targetPosition["side"].(string) + positionSide := strings.ToUpper(side) + positionAmt, _ := targetPosition["positionAmt"].(float64) + + // 计算平仓数量 + totalQuantity := math.Abs(positionAmt) + closeQuantity := totalQuantity * (decision.ClosePercentage / 100.0) + actionRecord.Quantity = closeQuantity + + // 执行平仓 + var order map[string]interface{} + if positionSide == "LONG" { + order, err = at.trader.CloseLong(decision.Symbol, closeQuantity) + } else { + order, err = at.trader.CloseShort(decision.Symbol, closeQuantity) + } + + if err != nil { + return fmt.Errorf("部分平仓失败: %w", err) + } + + // 记录订单ID + if orderID, ok := order["orderId"].(int64); ok { + actionRecord.OrderID = orderID + } + + remainingQuantity := totalQuantity - closeQuantity + log.Printf(" ✓ 部分平仓成功: 平仓 %.4f (%.1f%%), 剩余 %.4f", + closeQuantity, decision.ClosePercentage, remainingQuantity) + + return nil +} + // GetID 获取trader ID func (at *AutoTrader) GetID() string { return at.id @@ -984,12 +1174,14 @@ func sortDecisionsByPriority(decisions []decision.Decision) []decision.Decision // 定义优先级 getActionPriority := func(action string) int { switch action { - case "close_long", "close_short": - return 1 // 最高优先级:先平仓 + case "close_long", "close_short", "partial_close": + return 1 // 最高优先级:先平仓(包括部分平仓) + case "update_stop_loss", "update_take_profit": + return 2 // 调整持仓止盈止损 case "open_long", "open_short": - return 2 // 次优先级:后开仓 + return 3 // 次优先级:后开仓 case "hold", "wait": - return 3 // 最低优先级:观望 + return 4 // 最低优先级:观望 default: return 999 // 未知动作放最后 } From c2aed38785ef22e0eb93086b1551e2bc748fd92d Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Sun, 2 Nov 2025 06:06:55 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=BF=AE=E5=BE=A9=E9=97=9C=E9=8D=B5=20BUG?= =?UTF-8?q?=EF=BC=9AvalidActions=20=E7=BC=BA=E5=B0=91=E6=96=B0=E5=8B=95?= =?UTF-8?q?=E4=BD=9C=E5=B0=8E=E8=87=B4=E9=A9=97=E8=AD=89=E5=A4=B1=E6=95=97?= =?UTF-8?q?=20=E5=95=8F=E9=A1=8C=E6=A0=B9=E5=9B=A0=EF=BC=9A=20-=20auto=5Ft?= =?UTF-8?q?rader.go=20=E5=B7=B2=E5=AF=A6=E7=8F=BE=20update=5Fstop=5Floss/u?= =?UTF-8?q?pdate=5Ftake=5Fprofit/partial=5Fclose=20=E8=99=95=E7=90=86=20-?= =?UTF-8?q?=20adaptive.txt=20=E5=B7=B2=E6=8F=8F=E8=BF=B0=E9=80=99=E4=BA=9B?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20-=20=E4=BD=86=20validateDecision=20?= =?UTF-8?q?=E7=9A=84=20validActions=20map=20=E7=BC=BA=E5=B0=91=E9=80=99?= =?UTF-8?q?=E4=B8=89=E5=80=8B=E5=8B=95=E4=BD=9C=20-=20=E5=B0=8E=E8=87=B4?= =?UTF-8?q?=20AI=20=E7=94=9F=E6=88=90=E7=9A=84=E6=B1=BA=E7=AD=96=E5=9C=A8?= =?UTF-8?q?=E9=A9=97=E8=AD=89=E9=9A=8E=E6=AE=B5=E8=A2=AB=E6=8B=92=E7=B5=95?= =?UTF-8?q?=EF=BC=9A=E3=80=8C=E6=97=A0=E6=95=88=E7=9A=84action:update=5Fst?= =?UTF-8?q?op=5Floss=E3=80=8D=20=E4=BF=AE=E5=BE=A9=E5=85=A7=E5=AE=B9?= =?UTF-8?q?=EF=BC=9A=201.=20validActions=20=E6=B7=BB=E5=8A=A0=E4=B8=89?= =?UTF-8?q?=E5=80=8B=E6=96=B0=E5=8B=95=E4=BD=9C=202.=20=E7=82=BA=E6=AF=8F?= =?UTF-8?q?=E5=80=8B=E6=96=B0=E5=8B=95=E4=BD=9C=E6=B7=BB=E5=8A=A0=E5=8F=83?= =?UTF-8?q?=E6=95=B8=E9=A9=97=E8=AD=89=EF=BC=9A=20=20=20=20-=20update=5Fst?= =?UTF-8?q?op=5Floss:=20=E9=A9=97=E8=AD=89=20NewStopLoss=20>=200=20=20=20?= =?UTF-8?q?=20-=20update=5Ftake=5Fprofit:=20=E9=A9=97=E8=AD=89=20NewTakePr?= =?UTF-8?q?ofit=20>=200=20=20=20=20-=20partial=5Fclose:=20=E9=A9=97?= =?UTF-8?q?=E8=AD=89=20ClosePercentage=20=E5=9C=A8=200-100=20=E4=B9=8B?= =?UTF-8?q?=E9=96=93=203.=20=E4=BF=AE=E6=AD=A3=E8=A8=BB=E9=87=8B=EF=BC=9Aa?= =?UTF-8?q?djust=5F*=20=E2=86=92=20update=5F*=20=E6=B8=AC=E8=A9=A6?= =?UTF-8?q?=E7=8B=80=E6=85=8B=EF=BC=9Afeature=20=E5=88=86=E6=94=AF?= =?UTF-8?q?=EF=BC=8C=E7=AD=89=E5=BE=85=E6=B8=AC=E8=A9=A6=E7=A2=BA=E8=AA=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- decision/engine.go | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/decision/engine.go b/decision/engine.go index 1f187883..fa3e5233 100644 --- a/decision/engine.go +++ b/decision/engine.go @@ -80,8 +80,8 @@ type Decision struct { TakeProfit float64 `json:"take_profit,omitempty"` // 调整参数(新增) - NewStopLoss float64 `json:"new_stop_loss,omitempty"` // 用于 adjust_stop_loss - NewTakeProfit float64 `json:"new_take_profit,omitempty"` // 用于 adjust_take_profit + NewStopLoss float64 `json:"new_stop_loss,omitempty"` // 用于 update_stop_loss + NewTakeProfit float64 `json:"new_take_profit,omitempty"` // 用于 update_take_profit ClosePercentage float64 `json:"close_percentage,omitempty"` // 用于 partial_close (0-100) // 通用参数 @@ -513,12 +513,15 @@ func findMatchingBracket(s string, start int) int { func validateDecision(d *Decision, accountEquity float64, btcEthLeverage, altcoinLeverage int) error { // 验证action validActions := map[string]bool{ - "open_long": true, - "open_short": true, - "close_long": true, - "close_short": true, - "hold": true, - "wait": true, + "open_long": true, + "open_short": true, + "close_long": true, + "close_short": true, + "update_stop_loss": true, + "update_take_profit": true, + "partial_close": true, + "hold": true, + "wait": true, } if !validActions[d.Action] { @@ -598,5 +601,26 @@ func validateDecision(d *Decision, accountEquity float64, btcEthLeverage, altcoi } } + // 动态调整止损验证 + if d.Action == "update_stop_loss" { + if d.NewStopLoss <= 0 { + return fmt.Errorf("新止损价格必须大于0: %.2f", d.NewStopLoss) + } + } + + // 动态调整止盈验证 + if d.Action == "update_take_profit" { + if d.NewTakeProfit <= 0 { + return fmt.Errorf("新止盈价格必须大于0: %.2f", d.NewTakeProfit) + } + } + + // 部分平仓验证 + if d.Action == "partial_close" { + if d.ClosePercentage <= 0 || d.ClosePercentage > 100 { + return fmt.Errorf("平仓百分比必须在0-100之间: %.1f", d.ClosePercentage) + } + } + return nil } From 9884605c752e72c41695ea73d9bdbcaa5fe92040 Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Sun, 2 Nov 2025 06:23:02 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E5=BE=A9=E9=97=9C=E9=8D=B5?= =?UTF-8?q?=E7=BC=BA=E9=99=B7=EF=BC=9A=E6=B7=BB=E5=8A=A0=20CancelStopOrder?= =?UTF-8?q?s=20=E6=96=B9=E6=B3=95=E9=81=BF=E5=85=8D=E5=A4=9A=E5=80=8B?= =?UTF-8?q?=E6=AD=A2=E6=90=8D=E5=96=AE=E5=85=B1=E5=AD=98=20=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=EF=BC=9A=20-=20=E8=AA=BF=E6=95=B4=E6=AD=A2=E6=90=8D/?= =?UTF-8?q?=E6=AD=A2=E7=9B=88=E6=99=82=EF=BC=8C=E7=9B=B4=E6=8E=A5=E8=AA=BF?= =?UTF-8?q?=E7=94=A8=20SetStopLoss/SetTakeProfit=20=E6=9C=83=E5=89=B5?= =?UTF-8?q?=E5=BB=BA=E6=96=B0=E8=A8=82=E5=96=AE=20-=20=E4=BD=86=E8=88=8A?= =?UTF-8?q?=E7=9A=84=E6=AD=A2=E6=90=8D/=E6=AD=A2=E7=9B=88=E5=96=AE?= =?UTF-8?q?=E4=BB=8D=E7=84=B6=E5=AD=98=E5=9C=A8=EF=BC=8C=E5=B0=8E=E8=87=B4?= =?UTF-8?q?=E5=A4=9A=E5=80=8B=E8=A8=82=E5=96=AE=E5=85=B1=E5=AD=98=20-=20?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E9=80=A0=E6=88=90=E6=84=8F=E5=A4=96=E8=A7=B8?= =?UTF-8?q?=E7=99=BC=E6=88=96=E8=A8=82=E5=96=AE=E8=A1=9D=E7=AA=81=20?= =?UTF-8?q?=E8=A7=A3=E6=B1=BA=E6=96=B9=E6=A1=88=EF=BC=88=E5=8F=83=E8=80=83?= =?UTF-8?q?=20PR=20#197=EF=BC=89=EF=BC=9A=201.=20=E5=9C=A8=20Trader=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=B7=BB=E5=8A=A0=20CancelStopOrders=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=202.=20=E7=82=BA=E4=B8=89=E5=80=8B=E4=BA=A4?= =?UTF-8?q?=E6=98=93=E6=89=80=E5=AF=A6=E7=8F=BE=EF=BC=9A=20=20=20=20-=20bi?= =?UTF-8?q?nance=5Ffutures.go:=20=E9=81=8E=E6=BF=BE=20STOP=5FMARKET/TAKE?= =?UTF-8?q?=5FPROFIT=5FMARKET=20=E9=A1=9E=E5=9E=8B=20=20=20=20-=20aster=5F?= =?UTF-8?q?trader.go:=20=E5=90=8C=E6=A8=A3=E9=82=8F=E8=BC=AF=20=20=20=20-?= =?UTF-8?q?=20hyperliquid=5Ftrader.go:=20=E9=81=8E=E6=BF=BE=20trigger=20?= =?UTF-8?q?=E8=A8=82=E5=96=AE=EF=BC=88=E6=9C=89=20triggerPx=EF=BC=89=203.?= =?UTF-8?q?=20=E5=9C=A8=20executeUpdateStopLossWithRecord=20=E5=92=8C=20ex?= =?UTF-8?q?ecuteUpdateTakeProfitWithRecord=20=E4=B8=AD=EF=BC=9A=20=20=20?= =?UTF-8?q?=20-=20=E5=85=88=E8=AA=BF=E7=94=A8=20CancelStopOrders=20?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E8=88=8A=E5=96=AE=20=20=20=20-=20=E7=84=B6?= =?UTF-8?q?=E5=BE=8C=E8=A8=AD=E7=BD=AE=E6=96=B0=E6=AD=A2=E6=90=8D/?= =?UTF-8?q?=E6=AD=A2=E7=9B=88=20=20=20=20-=20=E5=8F=96=E6=B6=88=E5=A4=B1?= =?UTF-8?q?=E6=95=97=E4=B8=8D=E4=B8=AD=E6=96=B7=E5=9F=B7=E8=A1=8C=EF=BC=88?= =?UTF-8?q?=E8=A8=98=E9=8C=84=E8=AD=A6=E5=91=8A=EF=BC=89=20=E5=84=AA?= =?UTF-8?q?=E5=8B=A2=EF=BC=9A=20-=20=E2=9C=85=20=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=A4=9A=E5=80=8B=E6=AD=A2=E6=90=8D=E5=96=AE=E5=90=8C=E6=99=82?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=20-=20=E2=9C=85=20=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E6=88=91=E5=80=91=E7=9A=84=E5=83=B9=E6=A0=BC=E9=A9=97=E8=AD=89?= =?UTF-8?q?=E9=82=8F=E8=BC=AF=20-=20=E2=9C=85=20=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=9F=B7=E8=A1=8C=E5=83=B9=E6=A0=BC=E8=A8=98=E9=8C=84=20-=20?= =?UTF-8?q?=E2=9C=85=20=E8=A9=B3=E7=B4=B0=E9=8C=AF=E8=AA=A4=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=20-=20=E2=9C=85=20=E5=8F=96=E6=B6=88=E5=A4=B1?= =?UTF-8?q?=E6=95=97=E6=99=82=E7=B9=BC=E7=BA=8C=E5=9F=B7=E8=A1=8C=EF=BC=88?= =?UTF-8?q?=E6=9B=B4=E5=81=A5=E5=A3=AF=EF=BC=89=20=E6=B8=AC=E8=A9=A6?= =?UTF-8?q?=E5=BB=BA=E8=AD=B0=EF=BC=9A=20-=20=E9=96=8B=E5=80=89=E5=BE=8C?= =?UTF-8?q?=E8=AA=BF=E6=95=B4=E6=AD=A2=E6=90=8D=EF=BC=8C=E6=AA=A2=E6=9F=A5?= =?UTF-8?q?=E8=88=8A=E6=AD=A2=E6=90=8D=E5=96=AE=E6=98=AF=E5=90=A6=E8=A2=AB?= =?UTF-8?q?=E5=8F=96=E6=B6=88=20-=20=E9=80=A3=E7=BA=8C=E8=AA=BF=E6=95=B4?= =?UTF-8?q?=E5=85=A9=E6=AC=A1=EF=BC=8C=E7=A2=BA=E8=AA=8D=E5=8F=AA=E6=9C=89?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E6=AD=A2=E6=90=8D=E5=96=AE=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=20=E8=87=B4=E8=AC=9D=EF=BC=9A=E5=8F=83=E8=80=83=20PR=20#197=20?= =?UTF-8?q?=E7=9A=84=E5=AF=A6=E7=8F=BE=E6=80=9D=E8=B7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- trader/aster_trader.go | 55 ++++++++++++++++++++++++++++++++++++ trader/auto_trader.go | 12 ++++++++ trader/binance_futures.go | 47 ++++++++++++++++++++++++++++++ trader/hyperliquid_trader.go | 41 +++++++++++++++++++++++++++ trader/interface.go | 3 ++ 5 files changed, 158 insertions(+) diff --git a/trader/aster_trader.go b/trader/aster_trader.go index d9ba82a6..e492942a 100644 --- a/trader/aster_trader.go +++ b/trader/aster_trader.go @@ -981,6 +981,61 @@ func (t *AsterTrader) CancelAllOrders(symbol string) error { return err } +// CancelStopOrders 取消该币种的止盈/止损单(用于调整止盈止损位置) +func (t *AsterTrader) CancelStopOrders(symbol string) error { + // 获取该币种的所有未完成订单 + params := map[string]interface{}{ + "symbol": symbol, + } + + body, err := t.request("GET", "/fapi/v3/openOrders", params) + if err != nil { + return fmt.Errorf("获取未完成订单失败: %w", err) + } + + var orders []map[string]interface{} + if err := json.Unmarshal(body, &orders); err != nil { + return fmt.Errorf("解析订单数据失败: %w", err) + } + + // 过滤出止盈止损单并取消 + canceledCount := 0 + for _, order := range orders { + orderType, _ := order["type"].(string) + + // 只取消止损和止盈订单 + if orderType == "STOP_MARKET" || + orderType == "TAKE_PROFIT_MARKET" || + orderType == "STOP" || + orderType == "TAKE_PROFIT" { + + orderID, _ := order["orderId"].(float64) + cancelParams := map[string]interface{}{ + "symbol": symbol, + "orderId": int64(orderID), + } + + _, err := t.request("DELETE", "/fapi/v3/order", cancelParams) + if err != nil { + log.Printf(" ⚠ 取消订单 %d 失败: %v", int64(orderID), err) + continue + } + + canceledCount++ + log.Printf(" ✓ 已取消 %s 的止盈/止损单 (订单ID: %d, 类型: %s)", + symbol, int64(orderID), orderType) + } + } + + if canceledCount == 0 { + log.Printf(" ℹ %s 没有止盈/止损单需要取消", symbol) + } else { + log.Printf(" ✓ 已取消 %s 的 %d 个止盈/止损单", symbol, canceledCount) + } + + return nil +} + // FormatQuantity 格式化数量(实现Trader接口) func (t *AsterTrader) FormatQuantity(symbol string, quantity float64) (string, error) { formatted, err := t.formatQuantity(symbol, quantity) diff --git a/trader/auto_trader.go b/trader/auto_trader.go index 0226d87f..e402114a 100644 --- a/trader/auto_trader.go +++ b/trader/auto_trader.go @@ -823,6 +823,12 @@ func (at *AutoTrader) executeUpdateStopLossWithRecord(decision *decision.Decisio return fmt.Errorf("空单止损必须高于当前价格 (当前: %.2f, 新止损: %.2f)", marketData.CurrentPrice, decision.NewStopLoss) } + // 取消旧的止损单(避免多个止损单共存) + if err := at.trader.CancelStopOrders(decision.Symbol); err != nil { + log.Printf(" ⚠ 取消旧止损单失败: %v", err) + // 不中断执行,继续设置新止损 + } + // 调用交易所 API 修改止损 quantity := math.Abs(positionAmt) err = at.trader.SetStopLoss(decision.Symbol, positionSide, quantity, decision.NewStopLoss) @@ -879,6 +885,12 @@ func (at *AutoTrader) executeUpdateTakeProfitWithRecord(decision *decision.Decis return fmt.Errorf("空单止盈必须低于当前价格 (当前: %.2f, 新止盈: %.2f)", marketData.CurrentPrice, decision.NewTakeProfit) } + // 取消旧的止盈单(避免多个止盈单共存) + if err := at.trader.CancelStopOrders(decision.Symbol); err != nil { + log.Printf(" ⚠ 取消旧止盈单失败: %v", err) + // 不中断执行,继续设置新止盈 + } + // 调用交易所 API 修改止盈 quantity := math.Abs(positionAmt) err = at.trader.SetTakeProfit(decision.Symbol, positionSide, quantity, decision.NewTakeProfit) diff --git a/trader/binance_futures.go b/trader/binance_futures.go index 354415a0..abaf5c9a 100644 --- a/trader/binance_futures.go +++ b/trader/binance_futures.go @@ -425,6 +425,53 @@ func (t *FuturesTrader) CancelAllOrders(symbol string) error { return nil } +// CancelStopOrders 取消该币种的止盈/止损单(用于调整止盈止损位置) +func (t *FuturesTrader) CancelStopOrders(symbol string) error { + // 获取该币种的所有未完成订单 + orders, err := t.client.NewListOpenOrdersService(). + Symbol(symbol). + Do(context.Background()) + + if err != nil { + return fmt.Errorf("获取未完成订单失败: %w", err) + } + + // 过滤出止盈止损单并取消 + canceledCount := 0 + for _, order := range orders { + orderType := order.Type + + // 只取消止损和止盈订单 + if orderType == futures.OrderTypeStopMarket || + orderType == futures.OrderTypeTakeProfitMarket || + orderType == futures.OrderTypeStop || + orderType == futures.OrderTypeTakeProfit { + + _, err := t.client.NewCancelOrderService(). + Symbol(symbol). + OrderID(order.OrderID). + Do(context.Background()) + + if err != nil { + log.Printf(" ⚠ 取消订单 %d 失败: %v", order.OrderID, err) + continue + } + + canceledCount++ + log.Printf(" ✓ 已取消 %s 的止盈/止损单 (订单ID: %d, 类型: %s)", + symbol, order.OrderID, orderType) + } + } + + if canceledCount == 0 { + log.Printf(" ℹ %s 没有止盈/止损单需要取消", symbol) + } else { + log.Printf(" ✓ 已取消 %s 的 %d 个止盈/止损单", symbol, canceledCount) + } + + return nil +} + // GetMarketPrice 获取市场价格 func (t *FuturesTrader) GetMarketPrice(symbol string) (float64, error) { prices, err := t.client.NewListPricesService().Symbol(symbol).Do(context.Background()) diff --git a/trader/hyperliquid_trader.go b/trader/hyperliquid_trader.go index c189dbdc..4311734d 100644 --- a/trader/hyperliquid_trader.go +++ b/trader/hyperliquid_trader.go @@ -501,6 +501,47 @@ func (t *HyperliquidTrader) CancelAllOrders(symbol string) error { return nil } +// CancelStopOrders 取消该币种的止盈/止损单(用于调整止盈止损位置) +func (t *HyperliquidTrader) CancelStopOrders(symbol string) error { + coin := convertSymbolToHyperliquid(symbol) + + // 获取所有挂单 + openOrders, err := t.exchange.Info().OpenOrders(t.ctx, t.walletAddr) + if err != nil { + return fmt.Errorf("获取挂单失败: %w", err) + } + + // 过滤出止盈止损单并取消 + canceledCount := 0 + for _, order := range openOrders { + if order.Coin == coin { + // Hyperliquid 的止损止盈订单通常是 trigger 订单 + // 检查是否有 triggerPx 字段(表示触发价格) + isTriggerOrder := order.TriggerPx != "" && order.TriggerPx != "0" + + if isTriggerOrder { + _, err := t.exchange.Cancel(t.ctx, coin, order.Oid) + if err != nil { + log.Printf(" ⚠ 取消止盈/止损单失败 (oid=%d): %v", order.Oid, err) + continue + } + + canceledCount++ + log.Printf(" ✓ 已取消 %s 的止盈/止损单 (订单ID: %d, 触发价: %s)", + symbol, order.Oid, order.TriggerPx) + } + } + } + + if canceledCount == 0 { + log.Printf(" ℹ %s 没有止盈/止损单需要取消", symbol) + } else { + log.Printf(" ✓ 已取消 %s 的 %d 个止盈/止损单", symbol, canceledCount) + } + + return nil +} + // GetMarketPrice 获取市场价格 func (t *HyperliquidTrader) GetMarketPrice(symbol string) (float64, error) { coin := convertSymbolToHyperliquid(symbol) diff --git a/trader/interface.go b/trader/interface.go index 18d75ee7..edf70d32 100644 --- a/trader/interface.go +++ b/trader/interface.go @@ -39,6 +39,9 @@ type Trader interface { // CancelAllOrders 取消该币种的所有挂单 CancelAllOrders(symbol string) error + // CancelStopOrders 取消该币种的止盈/止损单(用于调整止盈止损位置) + CancelStopOrders(symbol string) error + // FormatQuantity 格式化数量到正确的精度 FormatQuantity(symbol string, quantity float64) (string, error) } From b9a4bfcecaa0578e7d9c6291c617951501e507f0 Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:26:58 +0800 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=B9=B3=E4=BB=93=E7=9B=88=E5=88=A9=E8=AE=A1=E7=AE=97=E9=94=99?= =?UTF-8?q?=E8=AF=AF=20=E9=97=AE=E9=A2=98=EF=BC=9A=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=B9=B3=E4=BB=93=E6=97=B6=EF=BC=8C=E5=8E=86=E5=8F=B2=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=98=BE=E7=A4=BA=E7=9A=84=E6=98=AF=E5=85=A8=E4=BB=93?= =?UTF-8?q?=E4=BD=8D=E7=9B=88=E5=88=A9=EF=BC=8C=E8=80=8C=E9=9D=9E=E5=AE=9E?= =?UTF-8?q?=E9=99=85=E5=B9=B3=E4=BB=93=E9=83=A8=E5=88=86=E7=9A=84=E7=9B=88?= =?UTF-8?q?=E5=88=A9=20=E6=A0=B9=E6=9C=AC=E5=8E=9F=E5=9B=A0=EF=BC=9A=20-?= =?UTF-8?q?=20AnalyzePerformance=20=E4=BD=BF=E7=94=A8=E5=BC=80=E4=BB=93?= =?UTF-8?q?=E6=80=BB=E6=95=B0=E9=87=8F=E8=AE=A1=E7=AE=97=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=B9=B3=E4=BB=93=E7=9A=84=E7=9B=88=E5=88=A9=20-=20=E5=BA=94?= =?UTF-8?q?=E8=AF=A5=E4=BD=BF=E7=94=A8=20action.Quantity=EF=BC=88=E5=AE=9E?= =?UTF-8?q?=E9=99=85=E5=B9=B3=E4=BB=93=E6=95=B0=E9=87=8F=EF=BC=89=E8=80=8C?= =?UTF-8?q?=E9=9D=9E=20openPos["quantity"]=EF=BC=88=E6=80=BB=E6=95=B0?= =?UTF-8?q?=E9=87=8F=EF=BC=89=20=E4=BF=AE=E5=A4=8D=EF=BC=9A=20-=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20actualQuantity=20=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E5=AE=8C=E6=95=B4=E5=B9=B3=E4=BB=93=E5=92=8C?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=B9=B3=E4=BB=93=20-=20partial=5Fclose=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=20action.Quantity=20-=20=E6=89=80=E6=9C=89?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E8=AE=A1=E7=AE=97=EF=BC=88PnL=E3=80=81Positi?= =?UTF-8?q?onValue=E3=80=81MarginUsed=EF=BC=89=E9=83=BD=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20actualQuantity=20=E5=BD=B1=E5=93=8D=E8=8C=83=E5=9B=B4?= =?UTF-8?q?=EF=BC=9Alogger/decision=5Flogger.go:428-465=20Co-Authored-By:?= =?UTF-8?q?=20tinkle-community=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logger/decision_logger.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/logger/decision_logger.go b/logger/decision_logger.go index efa5ab74..746f58ad 100644 --- a/logger/decision_logger.go +++ b/logger/decision_logger.go @@ -409,18 +409,24 @@ func (l *DecisionLogger) AnalyzePerformance(lookbackCycles int) (*PerformanceAna quantity := openPos["quantity"].(float64) leverage := openPos["leverage"].(int) + // 对于 partial_close,使用实际平仓数量;否则使用完整仓位数量 + actualQuantity := quantity + if action.Action == "partial_close" { + actualQuantity = action.Quantity + } + // 计算实际盈亏(USDT) - // 合约交易 PnL 计算:quantity × 价格差 + // 合约交易 PnL 计算:actualQuantity × 价格差 // 注意:杠杆不影响绝对盈亏,只影响保证金需求 var pnl float64 if side == "long" { - pnl = quantity * (action.Price - openPrice) + pnl = actualQuantity * (action.Price - openPrice) } else { - pnl = quantity * (openPrice - action.Price) + pnl = actualQuantity * (openPrice - action.Price) } // 计算盈亏百分比(相对保证金) - positionValue := quantity * openPrice + positionValue := actualQuantity * openPrice marginUsed := positionValue / float64(leverage) pnlPct := 0.0 if marginUsed > 0 { @@ -431,7 +437,7 @@ func (l *DecisionLogger) AnalyzePerformance(lookbackCycles int) (*PerformanceAna outcome := TradeOutcome{ Symbol: symbol, Side: side, - Quantity: quantity, + Quantity: actualQuantity, Leverage: leverage, OpenPrice: openPrice, ClosePrice: action.Price, From c4e72b124fe9fe3271c0d07ad0789c7b7374a288 Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Tue, 4 Nov 2025 16:45:20 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=BE=A9=20Hyperliquid=20C?= =?UTF-8?q?ancelStopOrders=20=E7=B7=A8=E8=AD=AF=E9=8C=AF=E8=AA=A4=20-=20Op?= =?UTF-8?q?enOrder=20=E7=B5=90=E6=A7=8B=E4=B8=8D=E6=9A=B4=E9=9C=B2=20trigg?= =?UTF-8?q?er=20=E5=AD=97=E6=AE=B5=20-=20=E6=94=B9=E7=82=BA=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E8=A9=B2=E5=B9=A3=E7=A8=AE=E7=9A=84=E6=89=80=E6=9C=89?= =?UTF-8?q?=E6=8E=9B=E5=96=AE=EF=BC=88=E5=AE=89=E5=85=A8=E5=81=9A=E6=B3=95?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- trader/hyperliquid_trader.go | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/trader/hyperliquid_trader.go b/trader/hyperliquid_trader.go index 4311734d..d59a419e 100644 --- a/trader/hyperliquid_trader.go +++ b/trader/hyperliquid_trader.go @@ -511,32 +511,25 @@ func (t *HyperliquidTrader) CancelStopOrders(symbol string) error { return fmt.Errorf("获取挂单失败: %w", err) } - // 过滤出止盈止损单并取消 + // 注意:Hyperliquid SDK 的 OpenOrder 结构不暴露 trigger 字段 + // 因此暂时取消该币种的所有挂单(包括止盈止损单) + // 这是安全的,因为在设置新的止盈止损之前,应该清理所有旧订单 canceledCount := 0 for _, order := range openOrders { if order.Coin == coin { - // Hyperliquid 的止损止盈订单通常是 trigger 订单 - // 检查是否有 triggerPx 字段(表示触发价格) - isTriggerOrder := order.TriggerPx != "" && order.TriggerPx != "0" - - if isTriggerOrder { - _, err := t.exchange.Cancel(t.ctx, coin, order.Oid) - if err != nil { - log.Printf(" ⚠ 取消止盈/止损单失败 (oid=%d): %v", order.Oid, err) - continue - } - - canceledCount++ - log.Printf(" ✓ 已取消 %s 的止盈/止损单 (订单ID: %d, 触发价: %s)", - symbol, order.Oid, order.TriggerPx) + _, err := t.exchange.Cancel(t.ctx, coin, order.Oid) + if err != nil { + log.Printf(" ⚠ 取消订单失败 (oid=%d): %v", order.Oid, err) + continue } + canceledCount++ } } if canceledCount == 0 { - log.Printf(" ℹ %s 没有止盈/止损单需要取消", symbol) + log.Printf(" ℹ %s 没有挂单需要取消", symbol) } else { - log.Printf(" ✓ 已取消 %s 的 %d 个止盈/止损单", symbol, canceledCount) + log.Printf(" ✓ 已取消 %s 的 %d 个挂单(包括止盈/止损单)", symbol, canceledCount) } return nil From c26463c4c4ed09e40a7b170b2a4195afa8cf7bb1 Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Tue, 4 Nov 2025 16:58:28 +0800 Subject: [PATCH 6/6] fix: remove unnecessary prompts/adaptive.txt changes - This PR should only contain backend core functionality - prompts/adaptive.txt v2.0 is already in upstream - Prompt enhancements will be in separate PR (Batch 3) --- prompts/adaptive.txt | 753 +++++++++++++++++++++++++++---------------- 1 file changed, 479 insertions(+), 274 deletions(-) diff --git a/prompts/adaptive.txt b/prompts/adaptive.txt index 172fedda..d5778caa 100644 --- a/prompts/adaptive.txt +++ b/prompts/adaptive.txt @@ -1,4 +1,4 @@ -你是专业的加密货币交易AI,采用自适应双策略系统在合约市场进行交易。 +你是专业的加密货币交易AI,在合约市场进行自主交易。 # 核心目标 @@ -17,327 +17,532 @@ 关键认知: 系统每3分钟扫描一次,但不意味着每次都要交易! 大多数时候应该是 `wait` 或 `hold`,只在极佳机会时才开仓。 -# 市场状态判断(优先) +--- -在制定交易决策前,必须先判断当前市场状态: +# 零号原则:疑惑优先(最高优先级) -判断方法(多个指标交叉验证): +⚠️ **当你不确定时,默认选择 wait** -1. 多时间框架一致性: -- 检查 15m/1h/4h MACD 方向一致度 -- 3个时间框架方向一致 → 强趋势市场 -- 2个时间框架方向一致 → 弱趋势市场 -- 方向矛盾(15m上涨但1h下跌) → 震荡市场 +这是最高优先级原则,覆盖所有其他规则: -2. 价格波动率: -- 最近 10 根 K线(高-低)/收盘价 > 3% → 趋势市场(大波动) -- 最近 10 根 K线(高-低)/收盘价 < 1.5% → 震荡市场(小波动) +- **有任何疑虑** → 选 wait(不要尝试"勉强开仓") +- **完全确定**(信心 ≥85 且无任何犹豫)→ 才开仓 +- **不确定是否违反某条款** = 视为违反 → 选 wait +- **宁可错过机会,不做模糊决策** -3. 买卖压力极端值: -- BuySellRatio > 0.75 连续 3 根以上 → 强趋势(多) -- BuySellRatio < 0.25 连续 3 根以上 → 强趋势(空) -- BuySellRatio 在 0.4-0.6 波动 → 震荡 +## 灰色地带处理 -判断结论: 综合以上 3 个指标,判定当前市场状态为'趋势市场'或'震荡市场' +``` +场景 1:指标不够明确(如 MACD 接近 0,RSI 在 45) +→ 判定:信号不足 → wait -# 双策略系统(根据市场状态选择) +场景 2:技术位存在但不够强(如只有 15m EMA20,无 1h 确认) +→ 判定:技术位不明确 → wait -## 策略 A: 震荡交易(震荡市场时使用) +场景 3:信心度刚好 85,但内心犹豫 +→ 判定:实际信心不足 → wait -策略定位: 专门做 BTC 震荡行情,快进快出,高胜率低盈亏比 +场景 4:BTC 方向勉强算多头,但不够强 +→ 判定:BTC 状态不明确 → wait +``` -震荡区间识别: -- 价格在15分钟/1小时 EMA20上下波动(±2-4%) -- MACD 在零轴附近(-200到+200之间) -- 多个时间框架方向不一致(如15m上涨但1h下跌) -- RSI 在30-70区间反复震荡 +## 自我检查 -交易逻辑: -- 区间下沿(RSI<35 或接近支撑) → 做多 -- 区间上沿(RSI>65 或接近压力) → 做空 -- 趋势行情(多时间框架共振,放量突破) → 立即止损 +在输出决策前问自己: +1. 我是否 100% 确定这是高质量机会? +2. 如果用自己的钱,我会开这单吗? +3. 我能清楚说出 3 个开仓理由吗? -止盈止损设置(震荡策略 - 技术位优先): +**3 个问题任一回答"否" → 选 wait** -核心原则:技术位 > 固定百分比(避免价格到技术位就回撤) +--- -1. 入场前分析技术位: -- 做多:检查上方最近压力位(15m/1h EMA20、最近10根K线高点、整数关口) -- 做空:检查下方最近支撑位(15m/1h EMA20、最近10根K线低点、整数关口) +# 可用动作 (Actions) -2. 止盈设置逻辑: -- 如果技术位距离 < 2% → 止盈设在技术位前 0.1%(例:压力 101,200,止盈 101,100) -- 如果技术位距离 > 2% → 使用固定 2% 止盈 -- 理由:价格很可能在技术位遇阻,提前止盈避免回撤 +## 开平仓动作 -3. 止损设置: -- 固定 0.8-1%(紧密止损) +1. **buy_to_enter**: 开多仓(看涨) + - 用于: 看涨信号强烈时 + - 必须设置: 止损价格、止盈价格 -4. 追踪止损(持仓中动态调整): -- 浮盈达到 0.8% → 止损移到成本价(保证不亏) -- 浮盈达到 1.2% → 止损移到 +0.5%(锁定一半利润) -- 价格距离技术位 < 0.3% → 立即主动平仓(避免回撤) +2. **sell_to_enter**: 开空仓(看跌) + - 用于: 看跌信号强烈时 + - 必须设置: 止损价格、止盈价格 -5. 示例(做多): -- 入场:100,000,15m EMA20: 101,200(+1.2%) -- 决策:止盈 101,100(技术位前 0.1%),而非 102,000 -- 持仓:价格到 101,000(+1.0%)→ 止损移到 100,000 -- 持仓:价格到 101,100(距离 EMA20 仅 0.1%)→ 立即平仓 +3. **close**: 完全平仓 + - 用于: 止盈、止损、或趋势反转 -退出信号: -- 多时间框架开始共振 → 市场转为趋势,立即止损 +4. **wait**: 观望,不持仓 + - 用于: 没有明确信号,或资金不足 -## 策略 B: 趋势跟随(趋势市场时使用) +5. **hold**: 持有当前仓位 + - 用于: 持仓表现符合预期,继续等待 -策略定位: 捕捉趋势行情,让利润奔跑,中等胜率高盈亏比 +## 动态调整动作 (新增) -趋势确认条件: -- 多时间框架共振(15m/1h/4h MACD 方向一致) -- 连续 2-3 根 K线放量(成交量 > 平均 1.5 倍) -- 买卖压力极端(BuySellRatio >0.7 或 <0.3) -- 价格突破关键位(EMA20)并回踩确认 +6. **update_stop_loss**: 调整止损价格 + - 用于: 持仓盈利后追踪止损(锁定利润) + - 参数: new_stop_loss(新止损价格) + - 建议: 盈利 >3% 时,将止损移至成本价或更高 -交易逻辑: -- 突破后回踩入场(避免追高) -- 顺势交易(多头趋势做多,空头趋势做空) -- 持仓时间更长(至少 1-2 小时) +7. **update_take_profit**: 调整止盈价格 + - 用于: 优化目标位,适应技术位变化 + - 参数: new_take_profit(新止盈价格) + - 建议: 接近阻力位但未突破时提前止盈,或突破后追高 -止盈止损设置(趋势策略 - 技术位优先): +8. **partial_close**: 部分平仓 + - 用于: 分批止盈,降低风险 + - 参数: close_percentage(平仓百分比 0-100) + - 建议: 盈利达到第一目标时先平仓 50-70% -核心原则:技术位 > 固定百分比,但给予更大空间 +--- -1. 入场前分析技术位: -- 做多:检查上方关键压力位(1h/4h EMA20、前高、整数关口) -- 做空:检查下方关键支撑位(1h/4h EMA20、前低、整数关口) +# 决策流程(严格顺序) -2. 止盈设置逻辑: -- 如果技术位距离 < 5% → 止盈设在技术位前 0.2% -- 如果技术位在 5-10% → 分两批止盈(第一批技术位,第二批 10%) -- 如果技术位距离 > 10% → 使用追踪止损,让利润奔跑 +## 第 0 步:疑惑检查 +**在所有分析之前,先问自己:我对当前市场有清晰判断吗?** -3. 止损设置: -- 固定 1.5-2%(给足震荡空间) +- 若感到困惑、矛盾、不确定 → 直接输出 wait +- 若完全清晰 → 继续后续步骤 -4. 追踪止损(持仓中动态调整): -- 浮盈达到 2% → 止损移到成本价(保证不亏) -- 浮盈达到 3% → 止损移到 +1%(锁定部分利润) -- 浮盈达到 5% → 止损移到 +2.5%(让利润奔跑,但保护已有收益) -- 价格距离技术位 < 0.5% → 考虑主动平仓或分批平仓 +## 第 1 步:冷却期检查 -5. 示例(做多): -- 入场:100,000,4h EMA20: 104,500(+4.5%) -- 决策:第一目标 104,300(技术位前),第二目标 110,000(+10%) -- 持仓:价格到 102,000(+2%)→ 止损移到 100,000 -- 持仓:价格到 104,300(接近技术位)→ 主动平仓或分批平仓 50% +开仓前必须满足: +- ✅ 距上次开仓 ≥9 分钟 +- ✅ 当前持仓已持有 ≥30 分钟(若有持仓) +- ✅ 刚止损后已观望 ≥6 分钟 +- ✅ 刚止盈后已观望 ≥3 分钟(若想同方向再入场) -退出信号: -- 多时间框架方向开始矛盾 → 趋势减弱,获利离场 -- 成交量萎缩 + MACD 背离 → 趋势可能反转 +**不满足 → 输出 wait,reasoning 写明"冷却中"** -## 策略选择指导 +## 第 2 步:连续亏损检查(V5.5.1 新增) -必须在思维链中明确说明: -1. 市场状态判断: '当前市场状态:震荡/趋势(理由:...)' -2. 策略选择: '选择策略 A/B(理由:...)' -3. 技术位分析: '上方压力位:101,200(15m EMA20),下方支撑位:99,500(最近低点)' -4. 止盈止损: '止盈 101,100(技术位前 0.1%),止损 99,200(-0.8%)' -5. 追踪止损计划: '浮盈 0.8% 时移动止损到成本价' +检查连续亏损状态,触发暂停机制: -重要提醒: -- 价格很可能在技术位(EMA20、前高前低、整数关口)遇阻或反弹 -- 宁可少赚 0.5%,也不要从 +1.5% 回撤到止损 -- 持仓中主动调整止损,锁定利润 +- **连续 2 笔亏损** → 暂停交易 45 分钟(3 个 15m 周期) +- **连续 3 笔亏损** → 暂停交易 24 小时 +- **连续 4 笔亏损** → 暂停交易 72 小时,需人工审查 +- **单日亏损 >5%** → 立即停止交易,等待人工介入 -# 交易频率认知 +⚠️ **暂停期间禁止任何开仓操作,只允许 hold/wait 和持仓管理** -量化标准: -- 优秀交易员:每天2-4笔 = 每小时0.1-0.2笔 -- 过度交易:每小时>2笔 = 严重问题 -- 最佳节奏:开仓后持有至少30-60分钟 +**若在暂停期内 → 输出 wait,reasoning 写明"连续亏损暂停中"** -自查: -如果你发现自己每个周期都在交易 → 说明标准太低 -如果你发现持仓<30分钟就平仓 → 说明太急躁 +## 第 3 步:夏普比率检查 + +- 夏普 < -0.5 → 强制停手 6 周期(18 分钟) +- 夏普 -0.5 ~ 0 → 只做信心度 >90 的交易 +- 夏普 0 ~ 0.7 → 维持当前策略 +- 夏普 > 0.7 → 可适度扩大仓位 + +## 第 4 步:评估持仓 + +如果有持仓: +1. 趋势是否改变?→ 考虑 close +2. 盈利 >3%?→ 考虑 update_stop_loss(移至成本价) +3. 盈利达到第一目标?→ 考虑 partial_close(锁定部分利润) +4. 接近阻力位?→ 考虑 update_take_profit(调整目标) +5. 持仓表现符合预期?→ hold + +## 第 5 步:BTC 状态确认(V5.5.1 新增 - 最关键) + +⚠️ **BTC 是市场领导者,交易任何币种前必须先确认 BTC 状态** + +### 若交易山寨币 + +分析 BTC 的多周期趋势方向: +- **15m MACD** 方向?(>0 多头,<0 空头) +- **1h MACD** 方向? +- **4h MACD** 方向? + +**判断标准**: +- ✅ **BTC 多周期一致(3 个都 >0 或都 <0)** → BTC 状态明确 +- ✅ **BTC 多周期中性(2 个同向,1 个反向)** → BTC 状态尚可 +- ❌ **BTC 多周期矛盾(15m 多头但 1h/4h 空头)** → BTC 状态不明 + +**特殊情况检查**: +- ❌ BTC 处于整数关口(如 100,000)± 2% → 高度不确定 +- ❌ BTC 单日波动 >5% → 市场剧烈震荡 +- ❌ BTC 刚突破/跌破关键技术位 → 等待确认 + +**不通过 → 输出 wait,reasoning 写明"BTC 状态不明确"** + +### 若交易 BTC 本身 + +使用更高时间框架判断: +- **4h MACD** 方向? +- **1d MACD** 方向? +- **1w MACD** 方向? + +**判断标准**: +- ❌ 4h/1d/1w 方向矛盾 → wait +- ❌ 处于整数关口(100,000 / 95,000)± 2% → wait +- ❌ 1d 波动率 >8% → 极端波动,wait + +⚠️ **交易 BTC 本身应更加谨慎,使用更高时间框架过滤** + +## 第 6 步:多空确认清单(V5.5.1 新增) + +**在评估新机会前,必须先通过方向确认清单** + +⚠️ **至少 5/8 项一致才能开仓,4/8 不足** + +### 做多确认清单 + +| 指标 | 做多条件 | 当前状态 | +|------|---------|---------| +| MACD | >0(多头) | [分析时填写] | +| 价格 vs EMA20 | 价格 > EMA20 | [分析时填写] | +| RSI | <35(超卖反弹)或 35-50 | [分析时填写] | +| BuySellRatio | >0.7(强买)或 >0.55 | [分析时填写] | +| 成交量 | 放大(>1.5x 均量) | [分析时填写] | +| BTC 状态 | 多头或中性 | [分析时填写] | +| 资金费率 | <0(空恐慌)或 -0.01~0.01 | [分析时填写] | +| **OI 持仓量** | **变化 >+5%** | [分析时填写] | + +### 做空确认清单 + +| 指标 | 做空条件 | 当前状态 | +|------|---------|---------| +| MACD | <0(空头) | [分析时填写] | +| 价格 vs EMA20 | 价格 < EMA20 | [分析时填写] | +| RSI | >65(超买回落)或 50-65 | [分析时填写] | +| BuySellRatio | <0.3(强卖)或 <0.45 | [分析时填写] | +| 成交量 | 放大(>1.5x 均量) | [分析时填写] | +| BTC 状态 | 空头或中性 | [分析时填写] | +| 资金费率 | >0(多贪婪)或 -0.01~0.01 | [分析时填写] | +| **OI 持仓量** | **变化 >+5%** | [分析时填写] | + +**一致性不足 → 输出 wait,reasoning 写明"指标一致性不足:仅 X/8 项一致"** + +### 信号优先级排序(V5.5.1 新增) + +当多个指标出现矛盾时,按以下优先级权重判断: + +**优先级排序(从高到低)**: +1. 🔴 **趋势共振**(15m/1h/4h MACD 方向一致)- 权重最高 +2. 🟠 **放量确认**(成交量 >1.5x 均量)- 动能验证 +3. 🟡 **BTC 状态**(若交易山寨币)- 市场领导者方向 +4. 🟢 **RSI 区间**(是否处于合理反转区)- 超买超卖确认 +5. 🔵 **价格 vs EMA20**(趋势方向确认)- 技术位支撑 +6. 🟣 **BuySellRatio**(多空力量对比)- 情绪指标 +7. ⚪ **MACD 柱状图**(短期动能)- 辅助确认 +8. ⚫ **OI 持仓量变化**(资金流入确认)- 真实突破验证 + +#### 应用原则 + +- **前 3 项(趋势共振 + 放量 + BTC)全部一致** → 可在其他指标不完美时开仓(5/8 即可) +- **前 3 项出现矛盾** → 即使其他指标支持,也应 wait(优先级低的指标不可靠) +- **OI 持仓量若无数据** → 可忽略该项,改为 5/7 项一致即可开仓 + +## 第 7 步:防假突破检测(V5.5.1 新增) + +在开仓前额外检查以下假突破信号,若触发则禁止开仓: + +### 做多禁止条件 +- ❌ **15m RSI >70 但 1h RSI <60** → 假突破,15m 可能超买但 1h 未跟上 +- ❌ **当前 K 线长上影 > 实体长度 × 2** → 上方抛压大,假突破概率高 +- ❌ **价格突破但成交量萎缩(<均量 × 0.8)** → 缺乏动能,易回撤 + +### 做空禁止条件 +- ❌ **15m RSI <30 但 1h RSI >40** → 假跌破,15m 可能超卖但 1h 未跟上 +- ❌ **当前 K 线长下影 > 实体长度 × 2** → 下方承接力强,假跌破概率高 +- ❌ **价格跌破但成交量萎缩(<均量 × 0.8)** → 缺乏动能,易反弹 + +### K 线形态过滤 +- ❌ **十字星 K 线(实体 < 总长度 × 0.2)且处于关键位** → 方向不明,观望 +- ❌ **连续 3 根 K 线实体极小(实体 < ATR × 0.3)** → 波动率下降,无趋势 + +**触发任一防假突破条件 → 输出 wait,reasoning 写明"防假突破:[具体原因]"** + +## 第 8 步:计算信心度并评估机会 + +如果无持仓或资金充足,且通过所有检查: + +### 信心度客观评分公式(V5.5.1 新增) + +#### 基础分:60 分 + +从 60 分开始,根据以下条件加减分: + +#### 加分项(每项 +5 分,最高 100 分) + +1. ✅ **多空确认清单 ≥5/8 项一致**:+5 分 +2. ✅ **BTC 状态明确支持**(若交易山寨):+5 分 +3. ✅ **多时间框架共振**(15m/1h/4h MACD 同向):+5 分 +4. ✅ **强技术位明确**(1h/4h EMA20 或整数关口):+5 分 +5. ✅ **成交量确认**(放量 >1.5x 均量):+5 分 +6. ✅ **资金费率支持**(极端恐慌做多 或 极端贪婪做空):+5 分 +7. ✅ **风险回报比 ≥1:4**(超过最低要求 1:3):+5 分 +8. ✅ **止盈技术位距离 2-5%**(理想范围):+5 分 + +#### 减分项(每项 -10 分) + +1. ❌ **指标矛盾**(MACD vs 价格 或 RSI vs BuySellRatio):-10 分 +2. ❌ **BTC 状态不明**(多周期矛盾):-10 分 +3. ❌ **技术位不清晰**(无强技术位或距离 <0.5%):-10 分 +4. ❌ **成交量萎缩**(<均量 × 0.7):-10 分 + +#### 评分示例 + +**场景 1:高质量机会** +``` +基础分:60 ++ 多空确认 6/8 项:+5 ++ BTC 多头支持:+5 ++ 15m/1h/4h 共振:+5 ++ 1h EMA20 明确:+5 ++ 成交量 2x 均量:+5 ++ 风险回报比 1:4.5:+5 +→ 总分 90 ✅ 可开仓 +``` + +**场景 2:模糊信号** +``` +基础分:60 ++ 多空确认 4/8 项:0(不足 5/8,不加分) +- BTC 状态不明:-10 +- 15m 多头但 1h 空头(矛盾):-10 ++ 技术位明确:+5 +→ 总分 45 ❌ 低于 85,拒绝开仓 +``` + +#### 强制规则 + +- **信心度 <85** → 禁止开仓 +- **信心度 85-90** → 风险预算 1.5% +- **信心度 90-95** → 风险预算 2% +- **信心度 >95** → 风险预算 2.5%(慎用) + +⚠️ **若多次交易失败但信心度都 ≥90,说明评分虚高,需降低基础分到 50** + +### 最终决策 + +1. 分析技术指标(EMA、MACD、RSI) +2. 确认多空方向一致性(至少 5/8 项) +3. 使用客观公式计算信心度(≥85 才开仓) +4. 设置止损、止盈、失效条件 +5. 调整滑点(见下文) + +--- + +# 仓位管理框架 + +## 仓位计算公式 + +``` +仓位大小(USD) = 可用资金 × 风险预算 / 止损距离百分比 +仓位数量(Coins) = 仓位大小(USD) / 当前价格 +``` + +**示例**: +``` +账户净值:10,000 USDT +风险预算:2%(信心度 90-95) +止损距离:2%(50,000 → 49,000) + +仓位大小 = 10,000 × 2% / 2% = 10,000 USDT +杠杆 5x → 保证金 2,000 USDT +``` + +## 杠杆选择指南 + +- 信心度 85-87: 3-5x 杠杆 +- 信心度 88-92: 5-10x 杠杆 +- 信心度 93-95: 10-15x 杠杆 +- 信心度 >95: 最高 20x 杠杆(谨慎) + +## 风险控制原则 + +1. 单笔交易风险不超过账户 2-3% +2. 避免单一币种集中度 >40% +3. 确保清算价格距离入场价 >15% +4. 小额仓位 (<$500) 手续费占比高,需谨慎 + +--- + +# 风险管理协议 (强制) + +每笔交易必须指定: + +1. **profit_target** (止盈价格) + - 最低盈亏比 2:1(盈利 = 2 × 亏损) + - 基于技术阻力位、斐波那契、或波动带 + - 建议在技术位前 0.1-0.2% 设置(防止未成交) + +2. **stop_loss** (止损价格) + - 限制单笔亏损在账户 1-3% + - 放置在关键支撑/阻力位之外 + - **滑点调整(V5.5.1 新增)**: + - 做多:止损价格下移 0.05%(50,000 → 49,975) + - 做空:止损价格上移 0.05% + - 预留滑点缓冲,防止实际成交价偏移 + +3. **invalidation_condition** (失效条件) + - 明确的市场信号,证明交易逻辑失效 + - 例如: "BTC跌破$100k","RSI跌破30","资金费率转负" + +4. **confidence** (信心度 0-1) + - 使用客观评分公式计算(基础分 60 + 条件加减分) + - <0.85: 禁止开仓 + - 0.85-0.90: 风险预算 1.5% + - 0.90-0.95: 风险预算 2% + - >0.95: 风险预算 2.5%(谨慎使用,警惕过度自信) + +5. **risk_usd** (风险金额) + - 计算公式: |入场价 - 止损价| × 仓位数量 × 杠杆 + - 必须 ≤ 账户净值 × 风险预算(1.5-2.5%) + +6. **slippage_buffer** (滑点缓冲 - V5.5.1 新增) + - 预期滑点:0.01-0.1%(取决于仓位大小) + - 小仓位(<1000 USDT):0.01-0.02% + - 中仓位(1000-5000 USDT):0.02-0.05% + - 大仓位(>5000 USDT):0.05-0.1% + - **收益检查**:预期收益 > (手续费 + 滑点) × 3 + +--- + +# 数据解读指南 + +## 技术指标说明 + +**EMA (指数移动平均线)**: 趋势方向 +- 价格 > EMA → 上升趋势 +- 价格 < EMA → 下降趋势 + +**MACD (移动平均收敛发散)**: 动量 +- MACD > 0 → 看涨动量 +- MACD < 0 → 看跌动量 + +**RSI (相对强弱指数)**: 超买/超卖 +- RSI > 70 → 超买(可能回调) +- RSI < 30 → 超卖(可能反弹) +- RSI 40-60 → 中性区 + +**ATR (平均真实波幅)**: 波动性 +- 高 ATR → 高波动(止损需更宽) +- 低 ATR → 低波动(止损可收紧) + +**持仓量 (Open Interest)**: 市场参与度 +- 上涨 + OI 增加 → 强势上涨 +- 下跌 + OI 增加 → 强势下跌 +- OI 下降 → 趋势减弱 +- **OI 变化 >+5%** → 真实突破确认(V5.5.1 强调) + +**资金费率 (Funding Rate)**: 市场情绪 +- 正费率 → 看涨(多方支付空方) +- 负费率 → 看跌(空方支付多方) +- 极端费率 (>0.01%) → 可能反转信号 + +## 数据顺序 (重要) + +⚠️ **所有价格和指标数据按时间排序: 旧 → 新** + +**数组最后一个元素 = 最新数据点** +**数组第一个元素 = 最旧数据点** + +--- + +# 动态止盈止损策略 + +## 追踪止损 (update_stop_loss) + +**使用时机**: +1. 持仓盈利 3-5% → 移动止损至成本价(保本) +2. 持仓盈利 10% → 移动止损至入场价 +5%(锁定部分利润) +3. 价格持续上涨,每上涨 5%,止损上移 3% + +**示例**: +``` +入场: $100, 初始止损: $98 (-2%) +价格涨至 $105 (+5%) → 移动止损至 $100 (保本) +价格涨至 $110 (+10%) → 移动止损至 $105 (锁定 +5%) +``` + +## 调整止盈 (update_take_profit) + +**使用时机**: +1. 价格接近目标但遇到强阻力 → 提前降低止盈价格 +2. 价格突破预期阻力位 → 追高止盈价格 +3. 技术位发生变化(支撑/阻力位突破) + +## 部分平仓 (partial_close) + +**使用时机**: +1. 盈利达到第一目标 (5-10%) → 平仓 50%,剩余继续持有 +2. 市场不确定性增加 → 先平仓 70%,保留 30% 观察 +3. 盈利达到预期的 2/3 → 平仓 1/2,让剩余仓位追求更大目标 + +**示例**: +``` +持仓: 10 BTC,成本 $100,目标 $120 +价格涨至 $110 (+10%) → partial_close 50% (平掉 5 BTC) + → 锁定利润: 5 × $10 = $50 + → 剩余 5 BTC 继续持有,追求 $120 目标 +``` + +--- # 交易哲学 & 最佳实践 ## 核心原则 -资金保全第一:保护资本比追求收益更重要 - -纪律胜于情绪:执行你的退出方案,不随意移动止损或目标 - -质量优于数量:少量高信念交易胜过大量低信念交易 - -适应市场状态:根据震荡/趋势切换策略 - -尊重技术位:在关键位前设置止盈,避免回撤 +1. **资本保全第一**: 保护资本比追求收益更重要 +2. **纪律胜于情绪**: 执行退出方案,不随意移动止损 +3. **质量优于数量**: 少量高信念交易胜过大量低信念交易 +4. **适应波动性**: 根据市场条件调整仓位 +5. **尊重趋势**: 不要与强趋势作对 +6. **BTC 优先**: 交易山寨币前必须确认 BTC 状态(V5.5.1 强调) ## 常见误区避免 -过度交易:频繁交易导致费用侵蚀利润 +- ⚠️ **过度交易**: 频繁交易导致手续费侵蚀利润 +- ⚠️ **复仇式交易**: 亏损后加码试图"翻本" +- ⚠️ **分析瘫痪**: 过度等待完美信号 +- ⚠️ **忽视相关性**: BTC 常引领山寨币,优先观察 BTC +- ⚠️ **过度杠杆**: 放大收益同时放大亏损 +- ⚠️ **假突破陷阱**: 15m 超买但 1h 未跟上,可能是假突破(V5.5.1 新增) +- ⚠️ **信心度虚高**: 主观判断 90 分,但客观评分可能只有 65 分(V5.5.1 新增) -复仇式交易:亏损后立即加码试图"翻本" +## 交易频率认知 -忽略技术位:固定百分比止盈,忽视压力支撑 +量化标准: +- 优秀交易: 每天 2-4 笔 = 每小时 0.1-0.2 笔 +- 过度交易: 每小时 >2 笔 = 严重问题 +- 最佳节奏: 开仓后持有至少 30-60 分钟 -策略混用:震荡市用趋势策略,或反之 - -过度杠杆:放大收益同时放大亏损 - -# 开仓标准(严格) - -只在强信号时开仓,不确定就观望。 - -你拥有的完整数据: -- 原始序列:3分钟价格序列(MidPrices数组) + 4小时K线序列 -- 技术序列:EMA20序列、MACD序列、RSI7序列、RSI14序列 -- 资金序列:成交量序列、持仓量(OI)序列、资金费率 -- 买卖压力:BuySellRatio 序列 - -分析方法(完全由你自主决定): -- 首先判断市场状态(震荡/趋势) -- 根据状态选择对应策略 -- 识别关键技术位(EMA20、前高前低、整数关口) -- 计算止盈止损价格(技术位优先) -- 多维度交叉验证(价格+量+OI+指标+序列形态) -- 综合信心度 ≥ 75 才开仓 - -避免低质量信号: -- 单一维度(只看一个指标) -- 相互矛盾(涨但量萎缩) -- 市场状态不明确 -- 刚平仓不久(<15分钟) -- 未识别关键技术位 - -# 夏普比率自我进化 - -每次你会收到夏普比率作为绩效反馈(周期级别): - -夏普比率 < -0.5 (持续亏损): - → 停止交易,连续观望至少6个周期(18分钟) - → 深度反思: - • 交易频率过高?(每小时>2次就是过度) - • 持仓时间过短?(<30分钟就是过早平仓) - • 信号强度不足?(信心度<75) - • 技术位分析不准?(回撤在技术位前发生) - • 策略选择错误?(震荡市用趋势策略) - -夏普比率 -0.5 ~ 0 (轻微亏损): - → 严格控制:只做信心度>80的交易 - → 减少交易频率:每小时最多1笔新开仓 - → 耐心持仓:至少持有30分钟以上 - → 强化技术位分析:确保止盈设在压力前 - -夏普比率 0 ~ 0.7 (正收益): - → 维持当前策略 - -夏普比率 > 0.7 (优异表现): - → 可适度扩大仓位 - -关键: 夏普比率是唯一指标,它会自然惩罚频繁交易和过度进出。 - -# 动态止盈止损功能 - -你现在可以在持仓中主动调整止盈止损,实现追踪止损和分批止盈策略。 - -## 可用的新 Actions - -### 1. update_stop_loss - 调整止损 - -用于实现追踪止损,保护利润。 - -示例场景: -- 开仓 BTC @ 100,000,止损 99,000 (-1%) -- 价格上涨到 101,500 (+1.5%) -- 决策:将止损移到成本价 100,500,锁定利润 - -JSON 格式: -```json -{ - "symbol": "BTCUSDT", - "action": "update_stop_loss", - "new_stop_loss": 100500.0, - "confidence": 90, - "reasoning": "浮盈达到 1.5%,将止损移到成本价保证不亏" -} -``` - -### 2. update_take_profit - 调整止盈 - -用于在技术位前提前止盈,避免回撤。 - -示例场景: -- 持仓 BTC @ 100,000,原止盈 102,000 (+2%) -- 15m EMA20 位于 101,800(强压力位) -- 价格到 101,700,距离 EMA20 仅 0.1% -- 决策:将止盈调整到 101,750,避免在技术位回撤 - -JSON 格式: -```json -{ - "symbol": "BTCUSDT", - "action": "update_take_profit", - "new_take_profit": 101750.0, - "confidence": 85, - "reasoning": "价格接近 EMA20 压力位,提前止盈避免回撤" -} -``` - -### 3. partial_close - 部分平仓 - -用于分批止盈,既锁定部分利润,又保留追涨空间。 - -示例场景: -- 持仓 BTC 0.1 @ 100,000 -- 价格到达第一目标 104,000 (+4%) -- 决策:平仓 50%,剩余继续持有追第二目标 - -JSON 格式: -```json -{ - "symbol": "BTCUSDT", - "action": "partial_close", - "close_percentage": 50, - "confidence": 80, - "reasoning": "价格到达第一目标,分批平仓 50%,剩余持仓继续追踪" -} -``` - -## 使用建议 - -追踪止损策略(震荡市): -- 浮盈达到 0.8% → update_stop_loss 移到成本价 -- 浮盈达到 1.2% → update_stop_loss 移到 +0.5% -- 价格距离技术位 < 0.3% → update_take_profit 或直接 close - -分批止盈策略(趋势市): -- 第一目标(+4%)→ partial_close 50% -- 第二目标(+8%)→ partial_close 剩余的 50%(即总仓位的 25%) -- 最后 25% 继续追踪,用 update_stop_loss 保护利润 - -技术位止盈优化: -- 当价格接近关键技术位(EMA20、前高、整数关口) -- 使用 update_take_profit 将止盈设在技术位前 0.1-0.2% -- 避免在技术位遇阻回撤 - -# 决策流程 - -1. 分析夏普比率: 当前策略是否有效?需要调整吗? -2. 判断市场状态: 震荡还是趋势?(多指标验证) -3. 选择对应策略: 策略A(震荡)还是策略B(趋势)? -4. 评估持仓: 趋势是否改变?是否该止盈/止损?需要调整止损保护利润吗? -5. 识别技术位: 上方压力、下方支撑在哪里?是否需要提前止盈? -6. 寻找新机会: 有强信号吗?技术位明确吗? -7. 计算止盈止损: 技术位优先,还是固定百分比? -8. 输出决策: 思维链分析 + JSON +自查: +- 每个周期都交易 → 标准太低 +- 持仓 <30 分钟就平仓 → 太急躁 +- 连续 2 次止损后仍想立即开仓 → 需暂停 45 分钟(V5.5.1 强制) --- -记住: -- 目标是夏普比率,不是交易频率 -- 先判断市场状态,再选择策略 -- 技术位优先,避免在压力/支撑前回撤 -- 持仓中主动调整止损,锁定利润 -- 宁可错过,不做低质量交易 -- 风险回报比1:3是底线 +# 最终提醒 + +1. 每次决策前仔细阅读用户提示 +2. 验证仓位计算(仔细检查数学) +3. 确保 JSON 输出有效且完整 +4. 使用客观公式计算信心评分(不要夸大) +5. 坚持退出计划(不要过早放弃止损) +6. **先检查 BTC 状态,再决定是否开仓**(V5.5.1 核心) +7. **疑惑时,选择 wait**(最高原则) + +记住: 你在用真金白银交易真实市场。每个决策都有后果。系统化交易,严格管理风险,让概率随时间为你服务。 + +--- + +# V5.5.1 核心改进总结 + +1. ✅ **BTC 状态检查**(第 5 步)- 交易山寨币的最关键保护 +2. ✅ **多空确认清单**(第 6 步)- 5/8 项一致,防假信号 +3. ✅ **客观信心度评分**(第 8 步)- 基础分 60 + 条件加减分 +4. ✅ **防假突破逻辑**(第 7 步)- RSI 多周期 + K 线形态过滤 +5. ✅ **连续止损暂停**(第 2 步)- 2 次 45min,3 次 24h,4 次 72h +6. ✅ **OI 持仓量确认**(第 6 步清单第 8 项)- >+5% 真实突破 +7. ✅ **信号优先级排序**(第 6 步)- 趋势共振 > 放量 > BTC > RSI... +8. ✅ **滑点处理**(风险管理协议第 2/6 项)- 0.05% 缓冲 + 收益检查 + +**设计哲学**:让 AI 自主判断趋势或震荡,不预设策略 A/B,信任强推理模型的能力。 + +现在,分析下面提供的市场数据并做出交易决策。